From d6f163b0488875115040ead35233d3ea8eb8ae57 Mon Sep 17 00:00:00 2001 From: Eugene Pankov Date: Tue, 4 Sep 2018 22:39:00 +0200 Subject: [PATCH] cleaned up #409 and renamed to Groups --- terminus-core/src/theme.scss | 4 + terminus-ssh/src/api.ts | 9 +- .../editConnectionModal.component.pug | 8 ++ .../src/components/sshModal.component.pug | 26 ++--- .../src/components/sshModal.component.ts | 64 ++++------- .../components/sshSettingsTab.component.pug | 44 ++++---- .../components/sshSettingsTab.component.ts | 102 ++++++------------ 7 files changed, 100 insertions(+), 157 deletions(-) diff --git a/terminus-core/src/theme.scss b/terminus-core/src/theme.scss index 6c1de780..a54bd70c 100644 --- a/terminus-core/src/theme.scss +++ b/terminus-core/src/theme.scss @@ -83,6 +83,10 @@ $list-group-border-color: rgba(255,255,255,.1); $list-group-hover-bg: rgba(255,255,255,.1); $list-group-link-active-bg: rgba(255,255,255,.2); +$list-group-action-color: $body-color; +$list-group-action-bg: rgba(255,255,255,.05); +$list-group-action-active-bg: $list-group-link-active-bg; + $pre-bg: $dropdown-bg; $pre-color: $dropdown-link-color; diff --git a/terminus-ssh/src/api.ts b/terminus-ssh/src/api.ts index 3fe5f201..547404b2 100644 --- a/terminus-ssh/src/api.ts +++ b/terminus-ssh/src/api.ts @@ -12,7 +12,7 @@ export interface SSHConnection { user: string password?: string privateKey?: string - path?: string + group?: string scripts?: LoginScript[] } @@ -21,7 +21,7 @@ export class SSHSession extends BaseSession { constructor (private shell: any, conn: SSHConnection) { super() - this.scripts = conn.scripts.slice(0); + this.scripts = conn.scripts ? [...conn.scripts] : [] } start () { @@ -101,3 +101,8 @@ export class SSHSession extends BaseSession { return null } } + +export interface ISSHConnectionGroup { + name: string + connections: SSHConnection[] +} diff --git a/terminus-ssh/src/components/editConnectionModal.component.pug b/terminus-ssh/src/components/editConnectionModal.component.pug index 04eb297d..a70516a8 100644 --- a/terminus-ssh/src/components/editConnectionModal.component.pug +++ b/terminus-ssh/src/components/editConnectionModal.component.pug @@ -13,6 +13,14 @@ [(ngModel)]='connection.name', ) + .form-group + label Group + input.form-control( + type='text', + placeholder='Ungrouped', + [(ngModel)]='connection.group', + ) + .form-group label Host input.form-control( diff --git a/terminus-ssh/src/components/sshModal.component.pug b/terminus-ssh/src/components/sshModal.component.pug index d9611cb6..e083166b 100644 --- a/terminus-ssh/src/components/sshModal.component.pug +++ b/terminus-ssh/src/components/sshModal.component.pug @@ -4,7 +4,7 @@ [(ngModel)]='quickTarget', autofocus, placeholder='Quick connect: [user@]host[:port]', - (ngModelChange)='filter()', + (ngModelChange)='refresh()', (keyup.enter)='quickConnect()' ) @@ -14,15 +14,15 @@ span {{lastConnection.name}} .list-group.mt-3 - a.list-group-item.list-group-item-action(*ngFor='let folder of childFolders', (click)='cd(folder)') - i.fa.fa-fw.fa-folder - span {{folder}} - a.list-group-item.list-group-item-action(*ngFor='let connection of childConnections', (click)='connect(connection)') - i.fa.fa-fw.fa-globe - span {{connection.name}} - a.list-group-item.list-group-item-action((click)='manageConnections()') - i.fa.fa-fw.fa-wrench - span Manage connections - -//.modal-footer - button.btn.btn-outline-primary((click)='close()') Cancel + ng-container(*ngFor='let group of childGroups') + .list-group-item.list-group-item-action.d-flex.align-items-center( + (click)='groupCollapsed[group.name] = !groupCollapsed[group.name]' + ) + .fa.fa-fw.fa-chevron-right(*ngIf='groupCollapsed[group.name]') + .fa.fa-fw.fa-chevron-down(*ngIf='!groupCollapsed[group.name]') + .ml-2 {{group.name || "Ungrouped"}} + ng-container(*ngIf='!groupCollapsed[group.name]') + .list-group-item.list-group-item-action.pl-5.d-flex.align-items-center( + *ngFor='let connection of group.connections', + (click)='connect(connection)' + ) {{connection.name}} diff --git a/terminus-ssh/src/components/sshModal.component.ts b/terminus-ssh/src/components/sshModal.component.ts index c09a7188..c51d6f1a 100644 --- a/terminus-ssh/src/components/sshModal.component.ts +++ b/terminus-ssh/src/components/sshModal.component.ts @@ -4,19 +4,18 @@ import { ToastrService } from 'ngx-toastr' import { ConfigService, AppService } from 'terminus-core' import { SettingsTabComponent } from 'terminus-settings' import { SSHService } from '../services/ssh.service' -import { SSHConnection } from '../api' +import { SSHConnection, ISSHConnectionGroup } from '../api' @Component({ template: require('./sshModal.component.pug'), - //styles: [require('./sshModal.component.scss')], }) export class SSHModalComponent { connections: SSHConnection[] + childFolders: ISSHConnectionGroup[] quickTarget: string lastConnection: SSHConnection - currentPath: string - childFolders: string[] - childConnections: SSHConnection[] + childGroups: ISSHConnectionGroup[] + groupCollapsed: {[id: string]: boolean} = {} constructor ( public modalInstance: NgbActiveModal, @@ -31,18 +30,7 @@ export class SSHModalComponent { if (window.localStorage.lastConnection) { this.lastConnection = JSON.parse(window.localStorage.lastConnection) } - this.currentPath = "/" - this.findChildren() - } - - filter () { - if (!this.quickTarget) { - this.findChildren() - } - else { - this.childFolders = []; - this.childConnections = this.connections.filter(connection => connection.name.toLowerCase().indexOf(this.quickTarget) >= 0) - } + this.refresh() } quickConnect () { @@ -81,37 +69,25 @@ export class SSHModalComponent { this.modalInstance.close() } - findChildren () { - this.childFolders = [] - this.childConnections = [] + refresh () { + this.childGroups = [] - if (this.currentPath != "/") - this.childFolders.push("..") + let connections = this.connections + if (this.quickTarget) { + connections = connections.filter(connection => (connection.name + connection.group).toLowerCase().indexOf(this.quickTarget) >= 0) + } - for (let connection of this.connections) { - if (!connection.path) - connection.path = "/" - if (connection.path.startsWith(this.currentPath)) { - let folder = connection.path.substr(this.currentPath.length, connection.path.indexOf("/", this.currentPath.length) - this.currentPath.length) - if (folder.length == 0) { - this.childConnections.push(connection) - } - else if (this.childFolders.indexOf(folder) < 0) { - this.childFolders.push(folder) + for (let connection of connections) { + connection.group = connection.group || null + let group = this.childGroups.find(x => x.name === connection.group) + if (!group) { + group = { + name: connection.group, + connections: [], } + this.childGroups.push(group) } + group.connections.push(connection) } } - - cd (path: string) { - if (path == "..") { - path = this.currentPath.substr(0, this.currentPath.lastIndexOf("/", this.currentPath.length - 2) + 1) - } - else { - path = this.currentPath + path + '/' - } - - this.currentPath = path - this.findChildren() - } } diff --git a/terminus-ssh/src/components/sshSettingsTab.component.pug b/terminus-ssh/src/components/sshSettingsTab.component.pug index a510114f..af09e18a 100644 --- a/terminus-ssh/src/components/sshSettingsTab.component.pug +++ b/terminus-ssh/src/components/sshSettingsTab.component.pug @@ -1,33 +1,25 @@ -h3 Connections ({{currentPath}}) +h3 Connections .list-group.mt-3.mb-3 - .list-group-item(*ngFor='let folder of childFolders') - .d-flex.w-100 - a.mr-auto.list-group-item-action((click)='cd(folder)') - div.fa.fa-fw.fa-folder - span.ml-2 {{folder}} - button.btn.btn-outline-info.ml-2(*ngIf='folder != ".."', (click)='editFolder(folder)') + ng-container(*ngFor='let group of childGroups') + .list-group-item.list-group-item-action.d-flex.align-items-center((click)='groupCollapsed[group.name] = !groupCollapsed[group.name]') + .fa.fa-fw.fa-chevron-right(*ngIf='groupCollapsed[group.name]') + .fa.fa-fw.fa-chevron-down(*ngIf='!groupCollapsed[group.name]') + span.ml-3.mr-auto {{group.name || "Ungrouped"}} + button.btn.btn-outline-info.ml-2((click)='editGroup(group)') i.fa.fa-pencil - button.btn.btn-outline-info.disabled.ml-2(*ngIf='folder == ".."') - i.fa.fa-pencil - button.btn.btn-outline-danger.ml-1(*ngIf='folder != ".."', (click)='deleteFolder(folder)') - i.fa.fa-trash-o - button.btn.btn-outline-danger.disabled.ml-1(*ngIf='folder == ".."') - i.fa.fa-trash-o - .list-group-item(*ngFor='let connection of childConnections') - .d-flex.w-100 - .mr-auto - div.fa.fa-fw.fa-globe - span.ml-2 {{connection.name}} - .text-muted {{connection.host}} - button.btn.btn-outline-info.ml-2((click)='editConnection(connection)') - i.fa.fa-pencil - button.btn.btn-outline-danger.ml-1((click)='deleteConnection(connection)') + button.btn.btn-outline-danger.ml-1((click)='deleteGroup(group)') i.fa.fa-trash-o + ng-container(*ngIf='!groupCollapsed[group.name]') + .list-group-item.pl-5.d-flex.align-items-center(*ngFor='let connection of group.connections') + .mr-auto + div {{connection.name}} + .text-muted {{connection.host}} + button.btn.btn-outline-info.ml-2((click)='editConnection(connection)') + i.fa.fa-pencil + button.btn.btn-outline-danger.ml-1((click)='deleteConnection(connection)') + i.fa.fa-trash-o -button.btn.btn-outline-primary((click)='createFolder()') - div.fa.fa-fw.fa-folder - span.ml-2 Add Folder -button.btn.btn-outline-primary.ml-2((click)='createConnection()') +button.btn.btn-outline-primary((click)='createConnection()') div.fa.fa-fw.fa-globe span.ml-2 Add connection diff --git a/terminus-ssh/src/components/sshSettingsTab.component.ts b/terminus-ssh/src/components/sshSettingsTab.component.ts index 22799d1e..40dbd8b1 100644 --- a/terminus-ssh/src/components/sshSettingsTab.component.ts +++ b/terminus-ssh/src/components/sshSettingsTab.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { ConfigService } from 'terminus-core' -import { SSHConnection } from '../api' +import { SSHConnection, ISSHConnectionGroup } from '../api' import { EditConnectionModalComponent } from './editConnectionModal.component' import { PromptModalComponent } from './promptModal.component' @@ -10,17 +10,15 @@ import { PromptModalComponent } from './promptModal.component' }) export class SSHSettingsTabComponent { connections: SSHConnection[] - currentPath: string - childFolders: string[] - childConnections: SSHConnection[] + childGroups: ISSHConnectionGroup[] + groupCollapsed: {[id: string]: boolean} = {} constructor ( public config: ConfigService, private ngbModal: NgbModal, ) { this.connections = this.config.store.ssh.connections - this.currentPath = "/" - this.findChildren() + this.refresh() } createConnection () { @@ -29,7 +27,6 @@ export class SSHSettingsTabComponent { host: '', port: 22, user: 'root', - path: this.currentPath } let modal = this.ngbModal.open(EditConnectionModalComponent) @@ -38,7 +35,7 @@ export class SSHSettingsTabComponent { this.connections.push(result) this.config.store.ssh.connections = this.connections this.config.save() - this.childConnections.push(result) + this.refresh() }) } @@ -48,6 +45,7 @@ export class SSHSettingsTabComponent { modal.result.then(result => { Object.assign(connection, result) this.config.save() + this.refresh() }) } @@ -56,89 +54,49 @@ export class SSHSettingsTabComponent { this.connections = this.connections.filter(x => x !== connection) this.config.store.ssh.connections = this.connections this.config.save() - this.childConnections = this.connections.filter(x => x !== connection) + this.refresh() } } - - createFolder () { + + editGroup (group: ISSHConnectionGroup) { let modal = this.ngbModal.open(PromptModalComponent) - modal.componentInstance.prompt = 'folder name' - modal.componentInstance.password = false + modal.componentInstance.prompt = 'New group name' + modal.componentInstance.value = group modal.result.then(result => { if (result) { - if (!this.childFolders.includes(result)) { - this.childFolders.push(result) + for (let connection of this.connections.filter(x => x.group === group.name)) { + connection.group = result } + this.config.save() + this.refresh() } }) } - editFolder (folder: string) { - let modal = this.ngbModal.open(PromptModalComponent) - modal.componentInstance.prompt = 'folder name' - modal.componentInstance.password = false - modal.componentInstance.value = folder - modal.result.then(result => { - if (result) { - let oldPath = this.currentPath + folder + "/" - let newPath = this.currentPath + result + "/" - for (let connection of this.connections) { - connection.path = connection.path.replace(oldPath, newPath) - } - let i = this.childFolders.indexOf(folder) - if (this.childFolders.includes(result)) { - this.childFolders.splice(i, 1) - } - else { - this.childFolders.splice(i, 1, result) - } - this.config.save() - } - }) - } - - deleteFolder (folder: string) { - if (confirm(`Delete "${folder}"?`)) { - let oldPath = this.currentPath + folder + "/" - for (let connection of this.connections) { - connection.path = connection.path.replace(oldPath, this.currentPath) + deleteGroup (group: ISSHConnectionGroup) { + if (confirm(`Delete "${group}"?`)) { + for (let connection of this.connections.filter(x => x.group === group.name)) { + connection.group = null } this.config.save() - this.findChildren() + this.refresh() } } - findChildren () { - this.childFolders = [] - this.childConnections = [] - - if (this.currentPath != "/") - this.childFolders.push("..") + refresh () { + this.childGroups = [] for (let connection of this.connections) { - if (!connection.path) - connection.path = "/" - if (connection.path.startsWith(this.currentPath)) { - let folder = connection.path.substr(this.currentPath.length, connection.path.indexOf("/", this.currentPath.length) - this.currentPath.length) - if (folder.length == 0) { - this.childConnections.push(connection) - } - else if (this.childFolders.indexOf(folder) < 0) { - this.childFolders.push(folder) + connection.group = connection.group || null + let group = this.childGroups.find(x => x.name === connection.group) + if (!group) { + group = { + name: connection.group, + connections: [], } + this.childGroups.push(group) } + group.connections.push(connection) } } - - cd (path: string) { - if (path == "..") { - path = this.currentPath.substr(0, this.currentPath.lastIndexOf("/", this.currentPath.length - 2) + 1) - } - else { - path = this.currentPath + path + '/' - } - - this.currentPath = path - this.findChildren() - } }