h3.mb-3(translate) Config sync ul.nav-tabs(ngbNav, #nav='ngbNav') li(ngbNavItem) a(ngbNavLink, translate) Sync ng-template(ngbNavContent) .form-line .header .title(translate) Sync host .input-group.w-50 input.form-control( type='text', [(ngModel)]='config.store.configSync.host', (ngModelChange)='config.save()', ) .input-group-append(*ngIf='config.store.configSync.host') button.btn.btn-secondary((click)='openSyncHost()') i.fas.fa-external-link-alt .form-line .header .title(translate) Secret sync token .description(translate) Get it from the Tabby Web settings window .input-group input.form-control( type='password', [(ngModel)]='config.store.configSync.token', (ngModelChange)='config.save(); testConnection()' ) .input-group-append(*ngIf='config.store.configSync.token') .input-group-text i.fas.fa-fw.fa-circle-notch.fa-spin.text-warning(*ngIf='connectionSuccessful === null') i.fas.fa-fw.fa-check.text-success(*ngIf='connectionSuccessful') i.fas.fa-fw.fa-exclamation-triangle.text-danger(*ngIf='connectionSuccessful === false') ng-container(*ngIf='config.store.configSync.token') .alert.alert-danger(*ngIf='connectionSuccessful === false') i.fas.fa-exclamation-triangle span.ml-2(translate='Connection failed: {error}', [translateParams]='{error: connectionError}') ng-container(*ngIf='connectionSuccessful') .form-line .header .title(translate) Configs div(*ngIf='configs === null') i.fas.fa-fw.fa-circle-notch.fa-spin span.ml-2(translate) Loading configs... ng-container(*ngIf='configs !== null') .list-group-light .list-group-item.d-flex.align-items-center( *ngFor='let cfg of configs', [class.active]='isActiveConfig(cfg)', ) i.fas.fa-fw.text-success([class.fa-check]='isActiveConfig(cfg)') i.fas.fa-fw.fa-file .ml-2.d-flex.flex-column.align-items-start div {{cfg.name}} small.text-muted( translate='Modified on {date}', [translateParams]='{date: cfg.modified_at|date:"medium"}' ) .mr-auto button.btn.btn-link.ml-1( (click)='uploadAndSync(cfg)', [class.hover-reveal]='!isActiveConfig(cfg)' ) i.fas.fa-arrow-up span.ml-2(*ngIf='isActiveConfig(cfg)', translate) Upload span.ml-2(*ngIf='!isActiveConfig(cfg)', translate) Replace button.btn.btn-link.ml-1( (click)='downloadAndSync(cfg)', [class.hover-reveal]='!isActiveConfig(cfg)' ) i.fas.fa-arrow-down span.ml-2(translate) Download a.list-group-item.list-group-item-action.d-flex.align-items-center( href='#', (click)='uploadAsNew()' ) i.fas.fa-fw i.fas.fa-fw.fa-cloud-upload-alt .ml-2(translate) Upload as a new config ng-container(*ngIf='hasMatchingRemoteConfig()') .form-line .header .title(translate) Sync automatically .description(translate) Automatically upload changes and check for updates every minute toggle( [(ngModel)]='config.store.configSync.auto', (ngModelChange)='config.save()', ) li(ngbNavItem) a(ngbNavLink, translate) Advanced ng-template(ngbNavContent) .alert.alert-info(*ngIf='config.store.encrypted') div(translate) Partial config sync is not possible when the config is encrypted via Vault. .form-line(*ngIf='!config.store.encrypted') .header .title(translate) Sync hotkeys toggle( [(ngModel)]='config.store.configSync.parts.hotkeys', (ngModelChange)='config.save()', ) .form-line(*ngIf='!config.store.encrypted') .header .title(translate) Sync window settings toggle( [(ngModel)]='config.store.configSync.parts.appearance', (ngModelChange)='config.save()', ) .form-line(*ngIf='!config.store.encrypted') .header .title(translate) Sync Vault toggle( [(ngModel)]='config.store.configSync.parts.vault', (ngModelChange)='config.save()', ) div([ngbNavOutlet]='nav')