diff --git a/tabby-core/src/services/profiles.service.ts b/tabby-core/src/services/profiles.service.ts index b198822b..a14401d6 100644 --- a/tabby-core/src/services/profiles.service.ts +++ b/tabby-core/src/services/profiles.service.ts @@ -8,6 +8,7 @@ import { AppService } from './app.service' import { configMerge, ConfigProxy, ConfigService } from './config.service' import { NotificationsService } from './notifications.service' import { SelectorService } from './selector.service' +import deepClone from 'clone-deep' @Injectable({ providedIn: 'root' }) export class ProfilesService { @@ -74,7 +75,7 @@ export class ProfilesService { ...this.config.store.profiles ?? [], ...list, ] - const sortKey = p => `${p.group ?? ''} / ${p.name}` + const sortKey = p => `${this.resolveProfileGroupName(p.group ?? '')} / ${p.name}` list.sort((a, b) => sortKey(a).localeCompare(sortKey(b))) list.sort((a, b) => (a.isBuiltin ? 1 : 0) - (b.isBuiltin ? 1 : 0)) return list @@ -96,8 +97,7 @@ export class ProfilesService { const freeInputEquivalent = provider?.intoQuickConnectString(fullProfile) ?? undefined return { ...profile, - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - group: profile.group || '', + group: this.resolveProfileGroupName(profile.group ?? ''), freeInputEquivalent, description: provider?.getDescription(fullProfile), } @@ -280,7 +280,7 @@ export class ProfilesService { } const profileGroupCollapsed = JSON.parse(window.localStorage.profileGroupCollapsed ?? '{}') - let groups: PartialProfileGroup[] = this.config.store.groups ?? [] + let groups: PartialProfileGroup[] = deepClone(this.config.store.groups ?? []) groups = groups.map(x => { x.editable = true x.collapsed = profileGroupCollapsed[x.id] ?? false @@ -322,6 +322,48 @@ export class ProfilesService { return groups } + /** + * Write a ProfileGroup in config + * arg: saveConfig (default: true) -> invoke after the ProfileGroup was updated + */ + async writeProfileGroup (group: PartialProfileGroup, saveConfig = true): Promise { + this.deleteProfileGroup(group, false) + + delete group.profiles + delete group.editable + delete group.collapsed + + this.config.store.groups.push(group) + if (saveConfig) { + return this.config.save() + } + } + + /** + * Delete a ProfileGroup from config + * arg: saveConfig (default: true) -> invoke after the ProfileGroup was deleted + */ + async deleteProfileGroup (group: PartialProfileGroup, saveConfig = true, deleteProfiles = true): Promise { + this.config.store.groups = this.config.store.groups.filter(g => g.id !== group.id) + if (deleteProfiles) { + this.config.store.profiles = this.config.store.profiles.filter(x => x.group !== group.id) + } else { + for (const profile of this.config.store.profiles.filter(x => x.group === group.id)) { + delete profile.group + } + } + if (saveConfig) { + return this.config.save() + } + } + + /** + * Resolve and return ProfileGroup from ProfileGroup ID + */ + resolveProfileGroupName (groupId: string): string { + return this.config.store.groups.find(g => g.id === groupId)?.name ?? '' + } + /** * Save ProfileGroup collapse state in localStorage */ diff --git a/tabby-settings/src/components/editProfileModal.component.ts b/tabby-settings/src/components/editProfileModal.component.ts index a57ee865..3a17ce0f 100644 --- a/tabby-settings/src/components/editProfileModal.component.ts +++ b/tabby-settings/src/components/editProfileModal.component.ts @@ -36,7 +36,7 @@ export class EditProfileModalComponent

{ private modalInstance: NgbActiveModal, ) { if (!this.defaultsMode) { - this.profilesService.getProfileGroups().then(groups => { + this.profilesService.getProfileGroups().then(groups => { this.groups = groups this.profileGroup = groups.find(g => g.id === this.profile.group) }) @@ -97,9 +97,9 @@ export class EditProfileModalComponent

{ if (typeof this.profileGroup === 'string') { const newGroup: PartialProfileGroup = { id: uuidv4(), - name: this.profileGroup + name: this.profileGroup, } - this.groups.push(newGroup) + this.profilesService.writeProfileGroup(newGroup, false) this.profileGroup = newGroup } this.profile.group = this.profileGroup.id diff --git a/tabby-settings/src/components/profilesSettingsTab.component.ts b/tabby-settings/src/components/profilesSettingsTab.component.ts index 2ede9f2d..4826a03d 100644 --- a/tabby-settings/src/components/profilesSettingsTab.component.ts +++ b/tabby-settings/src/components/profilesSettingsTab.component.ts @@ -167,7 +167,7 @@ export class ProfilesSettingsTabComponent extends BaseComponent { const result = await modal.result if (result) { group.name = result.value - await this.config.save() + await this.profilesService.writeProfileGroup(group) } } @@ -184,7 +184,8 @@ export class ProfilesSettingsTabComponent extends BaseComponent { cancelId: 1, }, )).response === 0) { - if ((await this.platform.showMessageBox( + let deleteProfiles = false + if ((group.profiles?.length ?? 0) > 0 && (await this.platform.showMessageBox( { type: 'warning', message: this.translate.instant('Delete the group\'s profiles?'), @@ -195,14 +196,11 @@ export class ProfilesSettingsTabComponent extends BaseComponent { defaultId: 0, cancelId: 0, }, - )).response === 0) { - for (const profile of this.profiles.filter(x => x.group === group.id)) { - delete profile.group - } - } else { - this.config.store.profiles = this.config.store.profiles.filter(x => x.group !== group.id) + )).response !== 0) { + deleteProfiles = true } - await this.config.save() + + await this.profilesService.deleteProfileGroup(group, true, deleteProfiles) } }