mirror of
https://github.com/Eugeny/tabby
synced 2025-03-04 15:17:17 +00:00
wip ref(settings): move out group managment from settings
This commit is contained in:
parent
21df033012
commit
1903ec5995
3 changed files with 48 additions and 65 deletions
|
@ -24,8 +24,10 @@
|
|||
type='text',
|
||||
alwaysVisibleTypeahead,
|
||||
placeholder='Ungrouped',
|
||||
[(ngModel)]='profile.group',
|
||||
[(ngModel)]='profileGroup',
|
||||
[ngbTypeahead]='groupTypeahead',
|
||||
[inputFormatter]="groupFormatter",
|
||||
[resultFormatter]="groupFormatter",
|
||||
)
|
||||
|
||||
.mb-3(*ngIf='!defaultsMode')
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
import { Observable, OperatorFunction, debounceTime, map, distinctUntilChanged } from 'rxjs'
|
||||
import { Component, Input, ViewChild, ViewContainerRef, ComponentFactoryResolver, Injector } from '@angular/core'
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { ConfigProxy, ConfigService, Profile, ProfileProvider, ProfileSettingsComponent, ProfilesService, TAB_COLORS } from 'tabby-core'
|
||||
import { ConfigProxy, ConfigService, PartialProfileGroup, Profile, ProfileProvider, ProfileSettingsComponent, ProfilesService, TAB_COLORS, ProfileGroup } from 'tabby-core'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
const iconsData = require('../../../tabby-core/src/icons.json')
|
||||
const iconsClassList = Object.keys(iconsData).map(
|
||||
|
@ -20,7 +21,8 @@ export class EditProfileModalComponent<P extends Profile> {
|
|||
@Input() profileProvider: ProfileProvider<P>
|
||||
@Input() settingsComponent: new () => ProfileSettingsComponent<P>
|
||||
@Input() defaultsMode = false
|
||||
groupNames: string[]
|
||||
@Input() profileGroup: PartialProfileGroup<ProfileGroup> | string | undefined
|
||||
groups: PartialProfileGroup<ProfileGroup>[]
|
||||
@ViewChild('placeholder', { read: ViewContainerRef }) placeholder: ViewContainerRef
|
||||
|
||||
private _profile: Profile
|
||||
|
@ -33,11 +35,12 @@ export class EditProfileModalComponent<P extends Profile> {
|
|||
config: ConfigService,
|
||||
private modalInstance: NgbActiveModal,
|
||||
) {
|
||||
this.groupNames = [...new Set(
|
||||
(config.store.profiles as Profile[])
|
||||
.map(x => x.group)
|
||||
.filter(x => !!x),
|
||||
)].sort() as string[]
|
||||
if (!this.defaultsMode) {
|
||||
this.profilesService.getProfileGroups().then(groups => {
|
||||
this.groups = groups
|
||||
this.profileGroup = groups.find(g => g.id === this.profile.group)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
colorsAutocomplete = text$ => text$.pipe(
|
||||
|
@ -72,13 +75,15 @@ export class EditProfileModalComponent<P extends Profile> {
|
|||
}
|
||||
}
|
||||
|
||||
groupTypeahead = (text$: Observable<string>) =>
|
||||
groupTypeahead: OperatorFunction<string, readonly PartialProfileGroup<ProfileGroup>[]> = (text$: Observable<string>) =>
|
||||
text$.pipe(
|
||||
debounceTime(200),
|
||||
distinctUntilChanged(),
|
||||
map(q => this.groupNames.filter(x => !q || x.toLowerCase().includes(q.toLowerCase()))),
|
||||
map(q => this.groups.filter(g => !q || g.name.toLowerCase().includes(q.toLowerCase()))),
|
||||
)
|
||||
|
||||
groupFormatter = (g: PartialProfileGroup<ProfileGroup>) => g.name
|
||||
|
||||
iconSearch: OperatorFunction<string, string[]> = (text$: Observable<string>) =>
|
||||
text$.pipe(
|
||||
debounceTime(200),
|
||||
|
@ -86,7 +91,20 @@ export class EditProfileModalComponent<P extends Profile> {
|
|||
)
|
||||
|
||||
save () {
|
||||
this.profile.group ||= undefined
|
||||
if (!this.profileGroup) {
|
||||
this.profile.group = undefined
|
||||
} else {
|
||||
if (typeof this.profileGroup === 'string') {
|
||||
const newGroup: PartialProfileGroup<ProfileGroup> = {
|
||||
id: uuidv4(),
|
||||
name: this.profileGroup
|
||||
}
|
||||
this.groups.push(newGroup)
|
||||
this.profileGroup = newGroup
|
||||
}
|
||||
this.profile.group = this.profileGroup.id
|
||||
}
|
||||
|
||||
this.settingsComponentInstance?.save?.()
|
||||
this.profile.__cleanup()
|
||||
this.modalInstance.close(this._profile)
|
||||
|
|
|
@ -4,16 +4,9 @@ import slugify from 'slugify'
|
|||
import deepClone from 'clone-deep'
|
||||
import { Component, Inject } from '@angular/core'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { ConfigService, HostAppService, Profile, SelectorService, ProfilesService, PromptModalComponent, PlatformService, BaseComponent, PartialProfile, ProfileProvider, TranslateService, Platform, AppHotkeyProvider } from 'tabby-core'
|
||||
import { ConfigService, HostAppService, Profile, SelectorService, ProfilesService, PromptModalComponent, PlatformService, BaseComponent, PartialProfile, ProfileProvider, TranslateService, Platform, AppHotkeyProvider, ProfileGroup, PartialProfileGroup } from 'tabby-core'
|
||||
import { EditProfileModalComponent } from './editProfileModal.component'
|
||||
|
||||
interface ProfileGroup {
|
||||
name?: string
|
||||
profiles: PartialProfile<Profile>[]
|
||||
editable: boolean
|
||||
collapsed: boolean
|
||||
}
|
||||
|
||||
_('Filter')
|
||||
_('Ungrouped')
|
||||
|
||||
|
@ -26,7 +19,7 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
|
|||
profiles: PartialProfile<Profile>[] = []
|
||||
builtinProfiles: PartialProfile<Profile>[] = []
|
||||
templateProfiles: PartialProfile<Profile>[] = []
|
||||
profileGroups: ProfileGroup[]
|
||||
profileGroups: PartialProfileGroup<ProfileGroup>[]
|
||||
filter = ''
|
||||
Platform = Platform
|
||||
|
||||
|
@ -158,55 +151,27 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
|
|||
}
|
||||
}
|
||||
|
||||
refresh (): void {
|
||||
async refresh (): Promise<void> {
|
||||
this.profiles = this.config.store.profiles
|
||||
this.profileGroups = []
|
||||
const profileGroupCollapsed = JSON.parse(window.localStorage.profileGroupCollapsed ?? '{}')
|
||||
|
||||
for (const profile of this.profiles) {
|
||||
// Group null, undefined and empty together
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
let group = this.profileGroups.find(x => x.name === (profile.group || ''))
|
||||
if (!group) {
|
||||
group = {
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
name: profile.group || '',
|
||||
profiles: [],
|
||||
editable: true,
|
||||
collapsed: profileGroupCollapsed[profile.group ?? ''] ?? false,
|
||||
}
|
||||
this.profileGroups.push(group)
|
||||
}
|
||||
group.profiles.push(profile)
|
||||
}
|
||||
|
||||
this.profileGroups.sort((a, b) => a.name?.localeCompare(b.name ?? '') ?? -1)
|
||||
|
||||
const builtIn = {
|
||||
name: this.translate.instant('Built-in'),
|
||||
profiles: this.builtinProfiles,
|
||||
editable: false,
|
||||
collapsed: false,
|
||||
}
|
||||
builtIn.collapsed = profileGroupCollapsed[builtIn.name ?? ''] ?? false
|
||||
this.profileGroups.push(builtIn)
|
||||
const groups = await this.profilesService.getProfileGroups(true, true)
|
||||
groups.sort((a, b) => a.name.localeCompare(b.name))
|
||||
groups.sort((a, b) => (a.id === 'built-in' ? 1 : 0) - (b.id === 'built-in' ? 1 : 0))
|
||||
groups.sort((a, b) => (a.id === 'ungrouped' ? 0 : 1) - (b.id === 'ungrouped' ? 0 : 1))
|
||||
this.profileGroups = groups
|
||||
}
|
||||
|
||||
async editGroup (group: ProfileGroup): Promise<void> {
|
||||
async editGroup (group: PartialProfileGroup<ProfileGroup>): Promise<void> {
|
||||
const modal = this.ngbModal.open(PromptModalComponent)
|
||||
modal.componentInstance.prompt = this.translate.instant('New name')
|
||||
modal.componentInstance.value = group.name
|
||||
const result = await modal.result
|
||||
if (result) {
|
||||
for (const profile of this.profiles.filter(x => x.group === group.name)) {
|
||||
profile.group = result.value
|
||||
}
|
||||
this.config.store.profiles = this.profiles
|
||||
group.name = result.value
|
||||
await this.config.save()
|
||||
}
|
||||
}
|
||||
|
||||
async deleteGroup (group: ProfileGroup): Promise<void> {
|
||||
async deleteGroup (group: PartialProfileGroup<ProfileGroup>): Promise<void> {
|
||||
if ((await this.platform.showMessageBox(
|
||||
{
|
||||
type: 'warning',
|
||||
|
@ -231,18 +196,18 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
|
|||
cancelId: 0,
|
||||
},
|
||||
)).response === 0) {
|
||||
for (const profile of this.profiles.filter(x => x.group === group.name)) {
|
||||
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.name)
|
||||
this.config.store.profiles = this.config.store.profiles.filter(x => x.group !== group.id)
|
||||
}
|
||||
await this.config.save()
|
||||
}
|
||||
}
|
||||
|
||||
isGroupVisible (group: ProfileGroup): boolean {
|
||||
return !this.filter || group.profiles.some(x => this.isProfileVisible(x))
|
||||
isGroupVisible (group: PartialProfileGroup<ProfileGroup>): boolean {
|
||||
return !this.filter || (group.profiles ?? []).some(x => this.isProfileVisible(x))
|
||||
}
|
||||
|
||||
isProfileVisible (profile: PartialProfile<Profile>): boolean {
|
||||
|
@ -270,11 +235,9 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
|
|||
}[this.profilesService.providerForProfile(profile)?.id ?? ''] ?? 'warning'
|
||||
}
|
||||
|
||||
toggleGroupCollapse (group: ProfileGroup): void {
|
||||
toggleGroupCollapse (group: PartialProfileGroup<ProfileGroup>): void {
|
||||
group.collapsed = !group.collapsed
|
||||
const profileGroupCollapsed = JSON.parse(window.localStorage.profileGroupCollapsed ?? '{}')
|
||||
profileGroupCollapsed[group.name ?? ''] = group.collapsed
|
||||
window.localStorage.profileGroupCollapsed = JSON.stringify(profileGroupCollapsed)
|
||||
this.profilesService.saveProfileGroupCollapse(group)
|
||||
}
|
||||
|
||||
async editDefaults (provider: ProfileProvider<Profile>): Promise<void> {
|
||||
|
|
Loading…
Add table
Reference in a new issue