Browse Source

Merge pull request #8663 from Clem-Fern/feat#5688

Eugene 2 years ago
parent
commit
e7f7d9b024

+ 11 - 1
tabby-core/src/services/config.service.ts

@@ -213,7 +213,9 @@ export class ConfigService {
      * Reads config YAML as string
      * Reads config YAML as string
      */
      */
     readRaw (): string {
     readRaw (): string {
-        return yaml.dump(this._store)
+        // Scrub undefined values
+        const cleanStore = JSON.parse(JSON.stringify(this._store))
+        return yaml.dump(cleanStore)
     }
     }
 
 
     /**
     /**
@@ -351,6 +353,14 @@ export class ConfigService {
             delete window.localStorage.lastSerialConnection
             delete window.localStorage.lastSerialConnection
             config.version = 3
             config.version = 3
         }
         }
+        if (config.version < 4) {
+            for (const p of config.profiles ?? []) {
+                if (!p.id) {
+                    p.id = `${p.type}:custom:${uuidv4()}`
+                }
+            }
+            config.version = 4
+        }
     }
     }
 
 
     private async maybeDecryptConfig (store) {
     private async maybeDecryptConfig (store) {

+ 1 - 2
tabby-local/src/index.ts

@@ -21,7 +21,7 @@ import { RecoveryProvider } from './recoveryProvider'
 import { ShellSettingsTabProvider } from './settings'
 import { ShellSettingsTabProvider } from './settings'
 import { TerminalConfigProvider } from './config'
 import { TerminalConfigProvider } from './config'
 import { LocalTerminalHotkeyProvider } from './hotkeys'
 import { LocalTerminalHotkeyProvider } from './hotkeys'
-import { NewTabContextMenu, SaveAsProfileContextMenu } from './tabContextMenu'
+import { NewTabContextMenu } from './tabContextMenu'
 
 
 import { AutoOpenTabCLIHandler, OpenPathCLIHandler, TerminalCLIHandler } from './cli'
 import { AutoOpenTabCLIHandler, OpenPathCLIHandler, TerminalCLIHandler } from './cli'
 import { LocalProfilesService } from './profiles'
 import { LocalProfilesService } from './profiles'
@@ -47,7 +47,6 @@ import { LocalProfilesService } from './profiles'
         { provide: ProfileProvider, useClass: LocalProfilesService, multi: true },
         { provide: ProfileProvider, useClass: LocalProfilesService, multi: true },
 
 
         { provide: TabContextMenuItemProvider, useClass: NewTabContextMenu, multi: true },
         { provide: TabContextMenuItemProvider, useClass: NewTabContextMenu, multi: true },
-        { provide: TabContextMenuItemProvider, useClass: SaveAsProfileContextMenu, multi: true },
 
 
         { provide: CLIHandler, useClass: TerminalCLIHandler, multi: true },
         { provide: CLIHandler, useClass: TerminalCLIHandler, multi: true },
         { provide: CLIHandler, useClass: OpenPathCLIHandler, multi: true },
         { provide: CLIHandler, useClass: OpenPathCLIHandler, multi: true },

+ 1 - 51
tabby-local/src/tabContextMenu.ts

@@ -1,59 +1,9 @@
 import { Inject, Injectable, Optional } from '@angular/core'
 import { Inject, Injectable, Optional } from '@angular/core'
-import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
-import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, NotificationsService, MenuItemOptions, ProfilesService, PromptModalComponent, TranslateService } from 'tabby-core'
+import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, MenuItemOptions, ProfilesService, TranslateService } from 'tabby-core'
 import { TerminalTabComponent } from './components/terminalTab.component'
 import { TerminalTabComponent } from './components/terminalTab.component'
 import { TerminalService } from './services/terminal.service'
 import { TerminalService } from './services/terminal.service'
 import { LocalProfile, UACService } from './api'
 import { LocalProfile, UACService } from './api'
 
 
-/** @hidden */
-@Injectable()
-export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
-    constructor (
-        private config: ConfigService,
-        private ngbModal: NgbModal,
-        private notifications: NotificationsService,
-        private translate: TranslateService,
-    ) {
-        super()
-    }
-
-    async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {
-        if (!(tab instanceof TerminalTabComponent)) {
-            return []
-        }
-        const terminalTab = tab
-        const items: MenuItemOptions[] = [
-            {
-                label: this.translate.instant('Save as profile'),
-                click: async () => {
-                    const modal = this.ngbModal.open(PromptModalComponent)
-                    modal.componentInstance.prompt = this.translate.instant('New profile name')
-                    const name = (await modal.result)?.value
-                    if (!name) {
-                        return
-                    }
-                    const profile = {
-                        options: {
-                            ...terminalTab.profile.options,
-                            cwd: await terminalTab.session?.getWorkingDirectory() ?? terminalTab.profile.options.cwd,
-                        },
-                        name,
-                        type: 'local',
-                    }
-                    this.config.store.profiles = [
-                        ...this.config.store.profiles,
-                        profile,
-                    ]
-                    this.config.save()
-                    this.notifications.info(this.translate.instant('Saved'))
-                },
-            },
-        ]
-
-        return items
-    }
-}
-
 /** @hidden */
 /** @hidden */
 @Injectable()
 @Injectable()
 export class NewTabContextMenu extends TabContextMenuItemProvider {
 export class NewTabContextMenu extends TabContextMenuItemProvider {

+ 2 - 1
tabby-terminal/src/index.ts

@@ -28,7 +28,7 @@ import { PathDropDecorator } from './features/pathDrop'
 import { ZModemDecorator } from './features/zmodem'
 import { ZModemDecorator } from './features/zmodem'
 import { TerminalConfigProvider } from './config'
 import { TerminalConfigProvider } from './config'
 import { TerminalHotkeyProvider } from './hotkeys'
 import { TerminalHotkeyProvider } from './hotkeys'
-import { CopyPasteContextMenu, MiscContextMenu, LegacyContextMenu, ReconnectContextMenu } from './tabContextMenu'
+import { CopyPasteContextMenu, MiscContextMenu, LegacyContextMenu, ReconnectContextMenu, SaveAsProfileContextMenu } from './tabContextMenu'
 
 
 import { Frontend } from './frontends/frontend'
 import { Frontend } from './frontends/frontend'
 import { XTermFrontend, XTermWebGLFrontend } from './frontends/xtermFrontend'
 import { XTermFrontend, XTermWebGLFrontend } from './frontends/xtermFrontend'
@@ -60,6 +60,7 @@ import { DefaultColorSchemes } from './colorSchemes'
         { provide: TabContextMenuItemProvider, useClass: MiscContextMenu, multi: true },
         { provide: TabContextMenuItemProvider, useClass: MiscContextMenu, multi: true },
         { provide: TabContextMenuItemProvider, useClass: LegacyContextMenu, multi: true },
         { provide: TabContextMenuItemProvider, useClass: LegacyContextMenu, multi: true },
         { provide: TabContextMenuItemProvider, useClass: ReconnectContextMenu, multi: true },
         { provide: TabContextMenuItemProvider, useClass: ReconnectContextMenu, multi: true },
+        { provide: TabContextMenuItemProvider, useClass: SaveAsProfileContextMenu, multi: true },
 
 
         { provide: CLIHandler, useClass: TerminalCLIHandler, multi: true },
         { provide: CLIHandler, useClass: TerminalCLIHandler, multi: true },
         { provide: TerminalColorSchemeProvider, useClass: DefaultColorSchemes, multi: true },
         { provide: TerminalColorSchemeProvider, useClass: DefaultColorSchemes, multi: true },

+ 67 - 1
tabby-terminal/src/tabContextMenu.ts

@@ -1,9 +1,12 @@
 import { Injectable, Optional, Inject } from '@angular/core'
 import { Injectable, Optional, Inject } from '@angular/core'
-import { BaseTabComponent, TabContextMenuItemProvider, NotificationsService, MenuItemOptions, TranslateService, SplitTabComponent } from 'tabby-core'
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
+import { BaseTabComponent, TabContextMenuItemProvider, NotificationsService, MenuItemOptions, TranslateService, SplitTabComponent, PromptModalComponent, ConfigService, PartialProfile, Profile } from 'tabby-core'
 import { BaseTerminalTabComponent } from './api/baseTerminalTab.component'
 import { BaseTerminalTabComponent } from './api/baseTerminalTab.component'
 import { TerminalContextMenuItemProvider } from './api/contextMenuProvider'
 import { TerminalContextMenuItemProvider } from './api/contextMenuProvider'
 import { MultifocusService } from './services/multifocus.service'
 import { MultifocusService } from './services/multifocus.service'
 import { ConnectableTerminalTabComponent } from './api/connectableTerminalTab.component'
 import { ConnectableTerminalTabComponent } from './api/connectableTerminalTab.component'
+import { v4 as uuidv4 } from 'uuid'
+import slugify from 'slugify'
 
 
 /** @hidden */
 /** @hidden */
 @Injectable()
 @Injectable()
@@ -150,3 +153,66 @@ export class LegacyContextMenu extends TabContextMenuItemProvider {
     }
     }
 
 
 }
 }
+
+/** @hidden */
+@Injectable()
+export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
+    constructor (
+        private config: ConfigService,
+        private ngbModal: NgbModal,
+        private notifications: NotificationsService,
+        private translate: TranslateService,
+    ) {
+        super()
+    }
+
+    async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {
+        if (tab instanceof BaseTerminalTabComponent) {
+            return [
+                {
+                    label: this.translate.instant('Save as profile'),
+                    click: async () => {
+                        const modal = this.ngbModal.open(PromptModalComponent)
+                        modal.componentInstance.prompt = this.translate.instant('New profile name')
+                        modal.componentInstance.value = tab.profile.name
+                        const name = (await modal.result)?.value
+                        if (!name) {
+                            return
+                        }
+
+                        const options = {
+                            ...tab.profile.options,
+                        }
+
+                        const cwd = await tab.session?.getWorkingDirectory() ?? tab.profile.options.cwd
+                        if (cwd) {
+                            options.cwd = cwd
+                        }
+
+                        const profile: PartialProfile<Profile> = {
+                            type: tab.profile.type,
+                            name,
+                            options,
+                        }
+
+                        profile.id = `${profile.type}:custom:${slugify(name)}:${uuidv4()}`
+                        profile.group = tab.profile.group
+                        profile.icon = tab.profile.icon
+                        profile.color = tab.profile.color
+                        profile.disableDynamicTitle = tab.profile.disableDynamicTitle
+                        profile.behaviorOnSessionEnd = tab.profile.behaviorOnSessionEnd
+
+                        this.config.store.profiles = [
+                            ...this.config.store.profiles,
+                            profile,
+                        ]
+                        this.config.save()
+                        this.notifications.info(this.translate.instant('Saved'))
+                    },
+                },
+            ]
+        }
+
+        return []
+    }
+}