mirror of
https://github.com/Eugeny/tabby.git
synced 2025-10-04 22:14:55 +00:00
profile editor, env vars editor, creating profiles from shell list
This commit is contained in:
@@ -21,6 +21,13 @@
|
||||
[(ngModel)]='profile.sessionOptions.cwd',
|
||||
)
|
||||
|
||||
.form-group
|
||||
label Environment
|
||||
environment-editor(
|
||||
type='text',
|
||||
[(model)]='profile.sessionOptions.env',
|
||||
)
|
||||
|
||||
.modal-footer
|
||||
button.btn.btn-outline-primary((click)='save()') Save
|
||||
button.btn.btn-outline-danger((click)='cancel()') Cancel
|
||||
|
@@ -13,6 +13,10 @@ export class EditProfileModalComponent {
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit () {
|
||||
this.profile.sessionOptions.env = this.profile.sessionOptions.env || {}
|
||||
}
|
||||
|
||||
save () {
|
||||
this.modalInstance.close(this.profile)
|
||||
}
|
||||
|
@@ -0,0 +1,9 @@
|
||||
.mb-2.d-flex.align-items-center(*ngFor='let pair of vars')
|
||||
input.form-control.w-50([(ngModel)]='pair.key', (blur)='emitUpdate()', placeholder='Variable name')
|
||||
input.form-control.w-50.mr-1([(ngModel)]='pair.value', (blur)='emitUpdate()', placeholder='Value')
|
||||
button.btn.btn-secondary((click)='removeEnvironmentVar(pair.key)')
|
||||
i.fa.fa-trash-o
|
||||
|
||||
button.btn.btn-secondary((click)='addEnvironmentVar()')
|
||||
i.fa.fa-plus.mr-2
|
||||
span Add
|
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
import { Component, Output, Input } from '@angular/core'
|
||||
import { Subject } from 'rxjs'
|
||||
|
||||
@Component({
|
||||
selector: 'environment-editor',
|
||||
template: require('./environmentEditor.component.pug'),
|
||||
styles: [require('./environmentEditor.component.scss')],
|
||||
})
|
||||
export class EnvironmentEditorComponent {
|
||||
@Output() modelChange = new Subject<any>()
|
||||
vars: {key: string, value: string}[] = []
|
||||
private cachedModel: any
|
||||
|
||||
@Input() get model (): any {
|
||||
return this.cachedModel
|
||||
}
|
||||
|
||||
set model (value) {
|
||||
this.vars = Object.entries(value).map(([k, v]) => ({ key: k, value: v as string }))
|
||||
this.cachedModel = this.getModel()
|
||||
}
|
||||
|
||||
getModel () {
|
||||
let model = {}
|
||||
for (let pair of this.vars) {
|
||||
model[pair.key] = pair.value
|
||||
}
|
||||
return model
|
||||
}
|
||||
|
||||
emitUpdate () {
|
||||
this.cachedModel = this.getModel()
|
||||
this.modelChange.next(this.cachedModel)
|
||||
}
|
||||
|
||||
addEnvironmentVar () {
|
||||
this.vars.push({ key: '', value: '' })
|
||||
}
|
||||
|
||||
removeEnvironmentVar (key: string) {
|
||||
this.vars = this.vars.filter(x => x.key !== key)
|
||||
this.emitUpdate()
|
||||
}
|
||||
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
h3 Saved Profiles
|
||||
|
||||
.list-group.list-group-flush.mt-3.mb-3
|
||||
.list-group-item.list-group-item-action.d-flex.align-items-center(
|
||||
*ngFor='let profile of profiles',
|
||||
(click)='editProfile(profile)',
|
||||
)
|
||||
.mr-auto
|
||||
div {{profile.name}}
|
||||
.text-muted {{profile.sessionOptions.command}}
|
||||
button.btn.btn-outline-danger.ml-1((click)='$event.stopPropagation(); deleteProfile(profile)')
|
||||
i.fa.fa-trash-o
|
||||
|
||||
.text-muted To add a new profile, right-click a tab and select "Save as a profile"
|
@@ -1,34 +0,0 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { ConfigService } from 'terminus-core'
|
||||
import { Profile } from '../api'
|
||||
import { EditProfileModalComponent } from './editProfileModal.component'
|
||||
|
||||
@Component({
|
||||
template: require('./profilesSettingsTab.component.pug'),
|
||||
})
|
||||
export class ProfilesSettingsTabComponent {
|
||||
profiles: Profile[] = []
|
||||
|
||||
constructor (
|
||||
private config: ConfigService,
|
||||
private ngbModal: NgbModal,
|
||||
) {
|
||||
this.profiles = config.store.terminal.profiles
|
||||
}
|
||||
|
||||
editProfile (profile: Profile) {
|
||||
let modal = this.ngbModal.open(EditProfileModalComponent)
|
||||
modal.componentInstance.profile = Object.assign({}, profile)
|
||||
modal.result.then(result => {
|
||||
Object.assign(profile, result)
|
||||
this.config.save()
|
||||
})
|
||||
}
|
||||
|
||||
deleteProfile (profile: Profile) {
|
||||
this.profiles = this.profiles.filter(x => x !== profile)
|
||||
this.config.store.terminal.profiles = this.profiles
|
||||
this.config.save()
|
||||
}
|
||||
}
|
@@ -46,13 +46,22 @@ h3.mb-3 Shell
|
||||
.title Environment
|
||||
.description Inject additional environment variables
|
||||
|
||||
div
|
||||
.mb-2.d-flex.align-items-center(*ngFor='let pair of environmentVars')
|
||||
input.form-control.w-50([(ngModel)]='pair.key', (blur)='saveEnvironment()', placeholder='Variable name')
|
||||
input.form-control.w-50.mr-1([(ngModel)]='pair.value', (blur)='saveEnvironment()', placeholder='Value')
|
||||
button.btn.btn-secondary((click)='removeEnvironmentVar(pair.key)')
|
||||
i.fa.fa-trash-o
|
||||
|
||||
button.btn.btn-secondary((click)='addEnvironmentVar()')
|
||||
i.fa.fa-plus.mr-2
|
||||
span Add
|
||||
environment-editor([(model)]='this.config.store.terminal.environment')
|
||||
|
||||
h3.mt-3 Saved Profiles
|
||||
|
||||
.list-group.list-group-flush.mt-3.mb-3
|
||||
.list-group-item.list-group-item-action.d-flex.align-items-center(
|
||||
*ngFor='let profile of profiles',
|
||||
(click)='editProfile(profile)',
|
||||
)
|
||||
.mr-auto
|
||||
div {{profile.name}}
|
||||
.text-muted {{profile.sessionOptions.command}}
|
||||
button.btn.btn-outline-danger.ml-1((click)='$event.stopPropagation(); deleteProfile(profile)')
|
||||
i.fa.fa-trash-o
|
||||
|
||||
div(ngbDropdown, placement='top-left')
|
||||
button.btn.btn-outline-primary(ngbDropdownToggle) New profile
|
||||
div(ngbDropdownMenu)
|
||||
button.dropdown-item(*ngFor='let shell of shells', (click)='newProfile(shell)') {{shell.name}}
|
||||
|
@@ -1,33 +1,29 @@
|
||||
import { Component, Inject } from '@angular/core'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { Component } from '@angular/core'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { ConfigService, ElectronService } from 'terminus-core'
|
||||
import { IShell, ShellProvider } from '../api'
|
||||
import { EditProfileModalComponent } from './editProfileModal.component'
|
||||
import { IShell, Profile } from '../api'
|
||||
import { TerminalService } from '../services/terminal.service'
|
||||
|
||||
@Component({
|
||||
template: require('./shellSettingsTab.component.pug'),
|
||||
})
|
||||
export class ShellSettingsTabComponent {
|
||||
shells: IShell[] = []
|
||||
|
||||
environmentVars: {key: string, value: string}[] = []
|
||||
private configSubscription: Subscription
|
||||
profiles: Profile[] = []
|
||||
|
||||
constructor (
|
||||
public config: ConfigService,
|
||||
private electron: ElectronService,
|
||||
@Inject(ShellProvider) private shellProviders: ShellProvider[],
|
||||
private terminalService: TerminalService,
|
||||
private ngbModal: NgbModal,
|
||||
) {
|
||||
config.store.terminal.environment = config.store.terminal.environment || {}
|
||||
this.reloadEnvironment()
|
||||
this.configSubscription = config.changed$.subscribe(() => this.reloadEnvironment())
|
||||
this.profiles = config.store.terminal.profiles
|
||||
}
|
||||
|
||||
async ngOnInit () {
|
||||
this.shells = (await Promise.all(this.config.enabledServices(this.shellProviders).map(x => x.provide()))).reduce((a, b) => a.concat(b))
|
||||
}
|
||||
|
||||
ngOnDestroy () {
|
||||
this.configSubscription.unsubscribe()
|
||||
this.shells = await this.terminalService.shells$.toPromise()
|
||||
}
|
||||
|
||||
pickWorkingDirectory () {
|
||||
@@ -42,23 +38,29 @@ export class ShellSettingsTabComponent {
|
||||
}
|
||||
}
|
||||
|
||||
reloadEnvironment () {
|
||||
this.environmentVars = Object.entries(this.config.store.terminal.environment).map(([k, v]) => ({ key: k, value: v as string }))
|
||||
}
|
||||
|
||||
saveEnvironment () {
|
||||
this.config.store.terminal.environment = {}
|
||||
for (let pair of this.environmentVars) {
|
||||
this.config.store.terminal.environment[pair.key] = pair.value
|
||||
newProfile (shell: IShell) {
|
||||
let profile: Profile = {
|
||||
name: shell.name,
|
||||
sessionOptions: this.terminalService.optionsFromShell(shell),
|
||||
}
|
||||
this.profiles.push(profile)
|
||||
this.config.store.terminal.profiles.push(profile)
|
||||
this.config.save()
|
||||
this.editProfile(profile)
|
||||
}
|
||||
|
||||
addEnvironmentVar () {
|
||||
this.environmentVars.push({ key: '', value: '' })
|
||||
editProfile (profile: Profile) {
|
||||
let modal = this.ngbModal.open(EditProfileModalComponent)
|
||||
modal.componentInstance.profile = Object.assign({}, profile)
|
||||
modal.result.then(result => {
|
||||
Object.assign(profile, result)
|
||||
this.config.save()
|
||||
})
|
||||
}
|
||||
|
||||
removeEnvironmentVar (key: string) {
|
||||
this.environmentVars = this.environmentVars.filter(x => x.key !== key)
|
||||
this.saveEnvironment()
|
||||
deleteProfile (profile: Profile) {
|
||||
this.profiles = this.profiles.filter(x => x !== profile)
|
||||
this.config.store.terminal.profiles = this.profiles
|
||||
this.config.save()
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ import { TerminalFrontendService } from '../services/terminalFrontend.service'
|
||||
|
||||
import { TerminalDecorator, ResizeEvent, SessionOptions } from '../api'
|
||||
import { Frontend } from '../frontends/frontend'
|
||||
console.warn(TerminalService)
|
||||
|
||||
@Component({
|
||||
selector: 'terminalTab',
|
||||
|
@@ -12,12 +12,12 @@ import { ToolbarButtonProvider, TabRecoveryProvider, ConfigProvider, HotkeysServ
|
||||
import { SettingsTabProvider } from 'terminus-settings'
|
||||
|
||||
import { AppearanceSettingsTabComponent } from './components/appearanceSettingsTab.component'
|
||||
import { ShellSettingsTabComponent } from './components/shellSettingsTab.component'
|
||||
import { ProfilesSettingsTabComponent } from './components/profilesSettingsTab.component'
|
||||
import { TerminalTabComponent } from './components/terminalTab.component'
|
||||
import { ShellSettingsTabComponent } from './components/shellSettingsTab.component'
|
||||
import { TerminalSettingsTabComponent } from './components/terminalSettingsTab.component'
|
||||
import { ColorPickerComponent } from './components/colorPicker.component'
|
||||
import { EditProfileModalComponent } from './components/editProfileModal.component'
|
||||
import { EnvironmentEditorComponent } from './components/environmentEditor.component'
|
||||
|
||||
import { SessionsService, BaseSession } from './services/sessions.service'
|
||||
import { TerminalFrontendService } from './services/terminalFrontend.service'
|
||||
@@ -27,7 +27,7 @@ import { DockMenuService } from './services/dockMenu.service'
|
||||
import { ButtonProvider } from './buttonProvider'
|
||||
import { RecoveryProvider } from './recoveryProvider'
|
||||
import { TerminalColorSchemeProvider, TerminalDecorator, ShellProvider } from './api'
|
||||
import { TerminalSettingsTabProvider, AppearanceSettingsTabProvider, ShellSettingsTabProvider, ProfilesSettingsTabProvider } from './settings'
|
||||
import { TerminalSettingsTabProvider, AppearanceSettingsTabProvider, ShellSettingsTabProvider } from './settings'
|
||||
import { PathDropDecorator } from './pathDrop'
|
||||
import { TerminalConfigProvider } from './config'
|
||||
import { TerminalHotkeyProvider } from './hotkeys'
|
||||
@@ -64,7 +64,6 @@ import { hterm } from './hterm'
|
||||
|
||||
{ provide: SettingsTabProvider, useClass: AppearanceSettingsTabProvider, multi: true },
|
||||
{ provide: SettingsTabProvider, useClass: ShellSettingsTabProvider, multi: true },
|
||||
{ provide: SettingsTabProvider, useClass: ProfilesSettingsTabProvider, multi: true },
|
||||
{ provide: SettingsTabProvider, useClass: TerminalSettingsTabProvider, multi: true },
|
||||
|
||||
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
|
||||
@@ -96,7 +95,6 @@ import { hterm } from './hterm'
|
||||
TerminalTabComponent,
|
||||
AppearanceSettingsTabComponent,
|
||||
ShellSettingsTabComponent,
|
||||
ProfilesSettingsTabComponent,
|
||||
TerminalSettingsTabComponent,
|
||||
EditProfileModalComponent,
|
||||
],
|
||||
@@ -105,9 +103,13 @@ import { hterm } from './hterm'
|
||||
TerminalTabComponent,
|
||||
AppearanceSettingsTabComponent,
|
||||
ShellSettingsTabComponent,
|
||||
ProfilesSettingsTabComponent,
|
||||
TerminalSettingsTabComponent,
|
||||
EditProfileModalComponent,
|
||||
EnvironmentEditorComponent,
|
||||
],
|
||||
exports: [
|
||||
ColorPickerComponent,
|
||||
EnvironmentEditorComponent,
|
||||
],
|
||||
})
|
||||
export default class TerminalModule {
|
||||
|
@@ -53,16 +53,22 @@ export class TerminalService {
|
||||
|
||||
this.logger.log(`Starting shell ${shell.name}`, shell)
|
||||
let sessionOptions = {
|
||||
command: shell.command,
|
||||
args: shell.args || [],
|
||||
cwd,
|
||||
env: shell.env,
|
||||
...this.optionsFromShell(shell),
|
||||
pauseAfterExit: pause,
|
||||
cwd,
|
||||
}
|
||||
|
||||
return this.openTabWithOptions(sessionOptions)
|
||||
}
|
||||
|
||||
optionsFromShell (shell: IShell) {
|
||||
return {
|
||||
command: shell.command,
|
||||
args: shell.args || [],
|
||||
env: shell.env,
|
||||
}
|
||||
}
|
||||
|
||||
openTabWithOptions (sessionOptions: SessionOptions): TerminalTabComponent {
|
||||
this.logger.log('Using session options:', sessionOptions)
|
||||
|
||||
|
@@ -4,7 +4,6 @@ import { SettingsTabProvider } from 'terminus-settings'
|
||||
import { AppearanceSettingsTabComponent } from './components/appearanceSettingsTab.component'
|
||||
import { ShellSettingsTabComponent } from './components/shellSettingsTab.component'
|
||||
import { TerminalSettingsTabComponent } from './components/terminalSettingsTab.component'
|
||||
import { ProfilesSettingsTabComponent } from './components/profilesSettingsTab.component'
|
||||
|
||||
@Injectable()
|
||||
export class AppearanceSettingsTabProvider extends SettingsTabProvider {
|
||||
@@ -35,13 +34,3 @@ export class TerminalSettingsTabProvider extends SettingsTabProvider {
|
||||
return TerminalSettingsTabComponent
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class ProfilesSettingsTabProvider extends SettingsTabProvider {
|
||||
id = 'profiles'
|
||||
title = 'Profiles'
|
||||
|
||||
getComponentType (): any {
|
||||
return ProfilesSettingsTabComponent
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user