1
1
mirror of https://github.com/Eugeny/tabby.git synced 2025-01-03 08:04:02 +03:00

serial plugin ui improv

This commit is contained in:
Eugene Pankov 2020-03-01 13:08:16 +01:00
parent 10b21ee085
commit 1b29797a81
13 changed files with 50 additions and 211 deletions

View File

@ -21,7 +21,6 @@ export interface SerialConnection {
xon: boolean
xoff: boolean
xany: boolean
group: string | null
scripts?: LoginScript[]
color?: string
}

View File

@ -11,14 +11,6 @@
[(ngModel)]='connection.name',
)
.form-group
label Group
input.form-control(
type='text',
placeholder='Ungrouped',
[(ngModel)]='connection.group',
)
.form-group
label Path
input.form-control(

View File

@ -15,21 +15,13 @@
button.btn.btn-outline-danger.btn-sm((click)='clearLastConnection(); $event.stopPropagation()')
i.fas.fa-trash
.list-group.mt-3.connections-list(*ngIf='childGroups.length')
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)'
)
.mr-2 {{connection.name}}
.text-muted {{connection.port}}
.list-group.mt-3.connections-list(*ngIf='connections.length')
a.list-group-item.list-group-item-action.d-flex.align-items-center(
*ngFor='let connection of connections',
(click)='connect(connection)'
)
.mr-2 {{connection.name}}
.text-muted {{connection.port}}
.list-group.mt-3(*ngIf='foundPorts.length')
a.list-group-item.list-group-item-action.d-flex.align-items-center(

View File

@ -4,7 +4,7 @@ import { ToastrService } from 'ngx-toastr'
import { ConfigService, AppService } from 'terminus-core'
import { SettingsTabComponent } from 'terminus-settings'
import { SerialService } from '../services/serial.service'
import { SerialConnection, SerialConnectionGroup, SerialPortInfo, BAUD_RATES } from '../api'
import { SerialConnection, SerialPortInfo, BAUD_RATES } from '../api'
/** @hidden */
@Component({
@ -13,11 +13,8 @@ import { SerialConnection, SerialConnectionGroup, SerialPortInfo, BAUD_RATES } f
})
export class SerialModalComponent {
connections: SerialConnection[]
childFolders: SerialConnectionGroup[]
quickTarget: string
lastConnection: SerialConnection|null = null
childGroups: SerialConnectionGroup[]
groupCollapsed: {[id: string]: boolean} = {}
foundPorts: SerialPortInfo[] = []
constructor (
@ -33,8 +30,6 @@ export class SerialModalComponent {
if (window.localStorage.lastSerialConnection) {
this.lastConnection = JSON.parse(window.localStorage.lastSerialConnection)
}
this.refresh()
this.foundPorts = await this.serial.listPorts()
}
@ -47,7 +42,6 @@ export class SerialModalComponent {
}
const connection: SerialConnection = {
name: this.quickTarget,
group: null,
port: path,
baudrate: baudrate,
databits: 8,
@ -87,28 +81,6 @@ export class SerialModalComponent {
this.modalInstance.close()
}
refresh () {
this.childGroups = []
let connections = this.connections
if (this.quickTarget) {
connections = connections.filter((connection: SerialConnection) => (connection.name + connection.group!).toLowerCase().includes(this.quickTarget))
}
for (const 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)
}
}
async connectFoundPort (port: SerialPortInfo) {
const rate = await this.app.showSelector('Baud rate', BAUD_RATES.map(x => ({
name: x.toString(), result: x,

View File

@ -1,27 +1,15 @@
h3 Connections
.list-group.list-group-flush.mt-3.mb-3
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.fas.fa-edit
button.btn.btn-outline-danger.ml-1((click)='deleteGroup(group)')
i.fas.fa-trash
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)='editConnection(connection)'
)
.mr-auto
div {{connection.name}}
.text-muted {{connection.port}}
button.btn.btn-outline-danger.ml-1((click)='$event.stopPropagation(); deleteConnection(connection)')
i.fas.fa-trash
.list-group-item.list-group-item-action.d-flex.align-items-center(
*ngFor='let connection of connections',
(click)='editConnection(connection)'
)
.mr-auto
div {{connection.name}}
.text-muted {{connection.port}}
button.btn.btn-outline-danger.ml-1((click)='$event.stopPropagation(); deleteConnection(connection)')
i.fas.fa-trash
button.btn.btn-primary((click)='createConnection()')
i.fas.fa-fw.fa-plus

View File

@ -1,9 +1,8 @@
import { Component } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { ConfigService, ElectronService, HostAppService } from 'terminus-core'
import { SerialConnection, SerialConnectionGroup } from '../api'
import { SerialConnection } from '../api'
import { EditConnectionModalComponent } from './editConnectionModal.component'
import { PromptModalComponent } from './promptModal.component'
/** @hidden */
@Component({
@ -11,8 +10,6 @@ import { PromptModalComponent } from './promptModal.component'
})
export class SerialSettingsTabComponent {
connections: SerialConnection[]
childGroups: SerialConnectionGroup[]
groupCollapsed: {[id: string]: boolean} = {}
constructor (
public config: ConfigService,
@ -27,7 +24,6 @@ export class SerialSettingsTabComponent {
createConnection () {
const connection: SerialConnection = {
name: '',
group: null,
port: '',
baudrate: 115200,
databits: 8,
@ -77,55 +73,7 @@ export class SerialSettingsTabComponent {
}
}
editGroup (group: SerialConnectionGroup) {
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = 'New group name'
modal.componentInstance.value = group.name
modal.result.then(result => {
if (result) {
for (const connection of this.connections.filter(x => x.group === group.name)) {
connection.group = result.value
}
this.config.store.serial.connections = this.connections
this.config.save()
this.refresh()
}
})
}
async deleteGroup (group: SerialConnectionGroup) {
if ((await this.electron.showMessageBox(
this.hostApp.getWindow(),
{
type: 'warning',
message: `Delete "${group}"?`,
buttons: ['Keep', 'Delete'],
defaultId: 1,
}
)).response === 1) {
for (const connection of this.connections.filter(x => x.group === group.name)) {
connection.group = null
}
this.config.save()
this.refresh()
}
}
refresh () {
this.connections = this.config.store.serial.connections
this.childGroups = []
for (const connection of this.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)
}
}
}

View File

@ -1,10 +1,15 @@
.serial-tab-toolbar
.tab-toolbar
.btn.btn-outline-secondary.reveal-button
i.fas.fa-ellipsis-h
.toolbar(*ngIf='session', [class.show]='!session.open')
i.fas.fa-circle.text-success.mr-2(*ngIf='session.open')
i.fas.fa-circle.text-danger.mr-2(*ngIf='!session.open')
strong.mr-auto(*ngIf='session') {{session.connection.port}} ({{session.connection.baudrate}})
strong(*ngIf='session') {{session.connection.port}} ({{session.connection.baudrate}})
.mr-auto
button.btn.btn-secondary.mr-3((click)='changeBaudRate()', *ngIf='session.open')
span Change baud rate
button.btn.btn-info((click)='reconnect()', *ngIf='!session.open')
i.fas.fa-reload

View File

@ -1,71 +1,7 @@
@import '../../../terminus-ssh/src/components/sshTab.component.scss';
:host {
flex: auto;
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
&> .content {
flex: auto;
position: relative;
display: block;
overflow: hidden;
margin: 15px;
}
.serial-tab-toolbar {
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 4;
pointer-events: none;
.reveal-button {
position: absolute;
top: 10px;
right: 30px;
border-radius: 50%;
width: 35px;
padding: 0;
height: 35px;
line-height: 35px;
transition: 0.125s opacity;
opacity: .5;
pointer-events: all;
}
&:hover .reveal-button {
opacity: 0;
}
&:hover .toolbar {
opacity: 1;
}
.toolbar {
opacity: 0;
background: rgba(0, 0, 0, .75);
padding: 10px 20px;
transition: 0.25s opacity;
display: flex;
align-items: center;
z-index: 1;
will-change: transform;
&>* {
pointer-events: all;
}
}
&.show {
.reveal-button {
opacity: 0;
}
.toolbar {
opacity: 1;
}
}
select {
width: auto;
}
}

View File

@ -1,11 +1,10 @@
import colors from 'ansi-colors'
import { Spinner } from 'cli-spinner'
import { Component } from '@angular/core'
// import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { first } from 'rxjs/operators'
import { BaseTerminalTabComponent } from 'terminus-terminal'
import { SerialService } from '../services/serial.service'
import { SerialConnection, SerialSession } from '../api'
import { SerialConnection, SerialSession, BAUD_RATES } from '../api'
import { Subscription } from 'rxjs'
/** @hidden */
@ -19,12 +18,10 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
connection: SerialConnection
serial: SerialService
session: SerialSession
// private ngbModal: NgbModal
serialPort: any
private homeEndSubscription: Subscription
ngOnInit () {
// this.ngbModal = this.injector.get<NgbModal>(NgbModal)
this.logger = this.log.create('terminalTab')
this.serial = this.injector.get(SerialService)
@ -77,7 +74,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
spinner.start()
try {
await this.serial.connectSession(this.session, (message: string) => {
this.serialPort = await this.serial.connectSession(this.session, (message: string) => {
spinner.stop(true)
this.write(message + '\r\n')
spinner.start()
@ -104,6 +101,14 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
this.initializeSession()
}
async changeBaudRate () {
const rate = await this.app.showSelector('Baud rate', BAUD_RATES.map(x => ({
name: x.toString(), result: x,
})))
this.serialPort.update({ baudRate: rate })
this.connection.baudrate = rate
}
ngOnDestroy () {
this.homeEndSubscription.unsubscribe()
super.ngOnDestroy()

View File

@ -7,7 +7,7 @@ import { SerialTabComponent } from './components/serialTab.component'
@Injectable()
export class RecoveryProvider extends TabRecoveryProvider {
async recover (recoveryToken: any): Promise<RecoveredTab|null> {
if (recoveryToken && recoveryToken.type === 'app:serial-tab') {
if (recoveryToken?.type === 'app:serial-tab') {
return {
type: SerialTabComponent,
options: {

View File

@ -38,7 +38,7 @@ export class SerialService {
return session
}
async connectSession (session: SerialSession, _?: (s: any) => void): Promise<void> {
async connectSession (session: SerialSession, _?: (s: any) => void): Promise<SerialPort> {
const serial = new SerialPort(session.connection.port, { autoOpen: false, baudRate: session.connection.baudrate,
dataBits: session.connection.databits, stopBits: session.connection.stopbits, parity: session.connection.parity,
rtscts: session.connection.rtscts, xon: session.connection.xon, xoff: session.connection.xoff,
@ -68,5 +68,6 @@ export class SerialService {
}
})
return serial
}
}

View File

@ -1,4 +1,4 @@
.ssh-tab-toolbar
.tab-toolbar
.btn.btn-outline-secondary.reveal-button
i.fas.fa-ellipsis-h
.toolbar(*ngIf='session', [class.show]='!session.open')

View File

@ -13,7 +13,7 @@
margin: 15px;
}
.ssh-tab-toolbar {
> .tab-toolbar {
position: absolute;
top: 0;
left: 0;
@ -41,6 +41,7 @@
&:hover .toolbar {
opacity: 1;
transform: translate(0, 0);
}
.toolbar {
@ -52,10 +53,9 @@
align-items: center;
z-index: 1;
will-change: transform;
&>* {
pointer-events: all;
}
transform: translate(0, -100px);
transition: 0.25s transform ease-out;
pointer-events: all;
}
&.show {
@ -65,6 +65,7 @@
.toolbar {
opacity: 1;
transform: translate(0, 0);
}
}
}