diff --git a/tabby-core/src/api/profileProvider.ts b/tabby-core/src/api/profileProvider.ts index a6e6bdd6..7010d25a 100644 --- a/tabby-core/src/api/profileProvider.ts +++ b/tabby-core/src/api/profileProvider.ts @@ -21,6 +21,11 @@ export interface Profile { isTemplate: boolean } +export interface ProfileDefaults { + id: string + //[provider]: +} + export type PartialProfile = Omit, 'type'>, 'name'> & { diff --git a/tabby-core/src/services/config.service.ts b/tabby-core/src/services/config.service.ts index daa0d746..2b9cf0db 100644 --- a/tabby-core/src/services/config.service.ts +++ b/tabby-core/src/services/config.service.ts @@ -10,6 +10,7 @@ import { PlatformService } from '../api/platform' import { HostAppService } from '../api/hostApp' import { Vault, VaultService } from './vault.service' import { serializeFunction } from '../utils' +import { ProfileDefaults } from '../api/profileProvider' const deepmerge = require('deepmerge') // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types @@ -364,6 +365,16 @@ export class ConfigService { } config.version = 4 } + if (config.version < 5) { + const oldDefaults = config.profileDefaults + const globalDefaults: ProfileDefaults = { + id: 'global', + ...oldDefaults + } + config.profileDefaults = [] + config.profileDefaults.push(globalDefaults) + config.version = 5 + } } private async maybeDecryptConfig (store) { diff --git a/tabby-core/src/services/profiles.service.ts b/tabby-core/src/services/profiles.service.ts index cc0fc1f9..1afd50c7 100644 --- a/tabby-core/src/services/profiles.service.ts +++ b/tabby-core/src/services/profiles.service.ts @@ -2,7 +2,7 @@ import { Injectable, Inject } from '@angular/core' import { TranslateService } from '@ngx-translate/core' import { NewTabParameters } from './tabs.service' import { BaseTabComponent } from '../components/baseTab.component' -import { PartialProfile, Profile, ProfileProvider } from '../api/profileProvider' +import { PartialProfile, Profile, ProfileDefaults, ProfileProvider } from '../api/profileProvider' import { SelectorOption } from '../api/selector' import { AppService } from './app.service' import { configMerge, ConfigProxy, ConfigService } from './config.service' @@ -212,12 +212,7 @@ export class ProfilesService { } getConfigProxyForProfile (profile: PartialProfile, skipUserDefaults = false): T { - const provider = this.providerForProfile(profile) - const defaults = [ - this.profileDefaults, - provider?.configDefaults ?? {}, - !provider || skipUserDefaults ? {} : this.config.store.profileDefaults[provider.id] ?? {}, - ].reduce(configMerge, {}) + const defaults = this.getProfileDefaults(profile).reduce(configMerge, {}) return new ConfigProxy(profile, defaults) as unknown as T } @@ -234,4 +229,72 @@ export class ProfilesService { } window.localStorage['recentProfiles'] = JSON.stringify(recentProfiles) } + + /* + * Methods used to interract with Profile/ProfileGroup/Global defaults + */ + + /** + * Return ProfileDefaults Array from config + */ + private getAllDefaults (): ProfileDefaults[] { + return this.config.store.profileDefaults + } + + /** + * Return ProfileDefaults for a given defaultsId (ex. 'global', 'profileId' or 'groupId') + */ + private getDefaults (defaultsId: string): ProfileDefaults { + return this.getAllDefaults().find(x => x.id == defaultsId) ?? { id: defaultsId } + } + + /** + * Replace or insert ProfileDefaults in config + */ + private setDefaults (defaults: ProfileDefaults) { + let allDefaults = this.getAllDefaults().filter(x => x.id !== defaults.id) + allDefaults.push(defaults) + + this.config.store.profileDefaults = allDefaults + } + + /** + * Replace or insert ProfileDefaults in config + */ + /*private deleteDefaults (defaults: ProfileDefaults) { + if (defaults.id === 'global') { + throw new Error('Unable to delete \'global\' profile Defaults') + } + this.config.store.profileDefaults = this.getAllDefaults().filter(x => x.id !== defaults.id) + }*/ + + /** + * Return global defaults for a given profile provider + */ + getProviderDefaults (defaultsId: string, provider: ProfileProvider): any { + const defaults = this.getDefaults(defaultsId) + return defaults[provider.id] ?? {} + } + + /** + * Set global defaults for a given profile provider + */ + setProviderDefaults (defaultsId: string, provider: ProfileProvider, pdefaults: any) { + const defaults = this.getDefaults(defaultsId) + defaults[provider.id] = pdefaults + this.setDefaults(defaults) + } + + /** + * Return defaults for a given profile + */ + getProfileDefaults (profile: PartialProfile, skipUserDefaults = false): any { + const provider = this.providerForProfile(profile) + return [ + this.profileDefaults, + provider?.configDefaults ?? {}, + !provider || skipUserDefaults ? {} : this.getProviderDefaults('global', provider), + ] + } + } diff --git a/tabby-settings/src/components/profilesSettingsTab.component.pug b/tabby-settings/src/components/profilesSettingsTab.component.pug index 9ce3f981..df8f902d 100644 --- a/tabby-settings/src/components/profilesSettingsTab.component.pug +++ b/tabby-settings/src/components/profilesSettingsTab.component.pug @@ -170,7 +170,7 @@ ul.nav-tabs(ngbNav, #nav='ngbNav') .list-group.mt-3.mb-3.content-box a.list-group-item.list-group-item-action( - (click)='editDefaults(provider)', + (click)='editGlobalDefaults(provider)', *ngFor='let provider of profileProviders' ) {{provider.name|translate}} diff --git a/tabby-settings/src/components/profilesSettingsTab.component.ts b/tabby-settings/src/components/profilesSettingsTab.component.ts index 38898ae6..be7cd4b4 100644 --- a/tabby-settings/src/components/profilesSettingsTab.component.ts +++ b/tabby-settings/src/components/profilesSettingsTab.component.ts @@ -277,12 +277,16 @@ export class ProfilesSettingsTabComponent extends BaseComponent { window.localStorage.profileGroupCollapsed = JSON.stringify(profileGroupCollapsed) } - async editDefaults (provider: ProfileProvider): Promise { + /** + * Edit Defaults for a given profile provider + * defaultsId: used to identify defaults stored in config (ex. value: group ID) + */ + async editDefaults (defaultsId: string, provider: ProfileProvider): Promise { const modal = this.ngbModal.open( EditProfileModalComponent, { size: 'lg' }, ) - const model = this.config.store.profileDefaults[provider.id] ?? {} + const model = this.profilesService.getProviderDefaults(defaultsId, provider) model.type = provider.id modal.componentInstance.profile = Object.assign({}, model) modal.componentInstance.profileProvider = provider @@ -295,10 +299,17 @@ export class ProfilesSettingsTabComponent extends BaseComponent { delete model[k] } Object.assign(model, result) - this.config.store.profileDefaults[provider.id] = model + this.profilesService.setProviderDefaults(defaultsId, provider, model) await this.config.save() } + /** + * Edit global Defaults for a given profile provider + */ + async editGlobalDefaults (provider: ProfileProvider): Promise { + return this.editDefaults('global', provider) + } + blacklistProfile (profile: PartialProfile): void { this.config.store.profileBlacklist = [...this.config.store.profileBlacklist, profile.id] this.config.save()