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', (keydown.enter)='config.save()', ) button.btn.btn-secondary( *ngIf='config.store.configSync.host', (click)='openSyncHost()' ) i.fas.fa-external-link-alt .form-line(*ngIf='config.store.configSync.host') .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', (keydown.enter)='config.save(); testConnection()' ) .input-group-text(*ngIf='config.store.configSync.token') 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') .alert.alert-info.d-flex.align-items-center .me-auto span(translate) Config sync requires an instance of the Tabby Web service. a.ml-1((click)='openTabbyWebInfo()', href='#', translate) Learn more ng-container(*ngIf='config.store.configSync.token') .alert.alert-danger(*ngIf='connectionSuccessful === false') i.fas.fa-exclamation-triangle span.ms-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.ms-2(translate) Loading configs... ng-container(*ngIf='configs !== null') .list-group.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 .ms-2.d-flex.flex-column.align-items-start div {{cfg.name}} small.text-muted( translate='Modified on {date}', [translateParams]='{date: cfg.modified_at|tabbyDate}' ) .me-auto button.btn.btn-link.ms-1( (click)='uploadAndSync(cfg)', [class.hover-reveal]='!isActiveConfig(cfg)' ) i.fas.fa-arrow-up span.ms-2(*ngIf='isActiveConfig(cfg)', translate) Upload span.ms-2(*ngIf='!isActiveConfig(cfg)', translate) Replace button.btn.btn-link.ms-1( (click)='downloadAndSync(cfg)', [class.hover-reveal]='!isActiveConfig(cfg)' ) i.fas.fa-arrow-down span.ms-2(translate) Download button.btn.btn-link.ms-1( (click)='delete(cfg)', [class.hover-reveal]='!isActiveConfig(cfg)' ) i.fas.fa-trash span.ms-2(translate) Delete 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 .ms-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')