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