profile editor, env vars editor, creating profiles from shell list

This commit is contained in:
Eugene Pankov
2018-12-18 15:08:23 +01:00
parent 4b5b75a57a
commit 137dd0bbe8
17 changed files with 363 additions and 270 deletions

View File

@@ -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

View File

@@ -13,6 +13,10 @@ export class EditProfileModalComponent {
) {
}
ngOnInit () {
this.profile.sessionOptions.env = this.profile.sessionOptions.env || {}
}
save () {
this.modalInstance.close(this.profile)
}

View File

@@ -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

View File

@@ -0,0 +1,3 @@
:host {
display: block;
}

View File

@@ -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()
}
}

View File

@@ -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"

View File

@@ -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()
}
}

View File

@@ -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}}

View File

@@ -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()
}
}

View File

@@ -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',

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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
}
}