SFTP Feature: implement Create Folder

This commit is contained in:
Thomas Peterson 2022-03-29 18:26:57 +02:00
parent 40cf2bde9b
commit e223effe98
5 changed files with 81 additions and 0 deletions

View File

@ -0,0 +1,13 @@
.modal-body
label(translate) Create Directory
.form-group.w-100.mr-2
label(translate) Name
input.form-control(
type='text',
[(ngModel)]='directoryName',
)
.modal-footer
button.btn.btn-success((click)='create()', translate) Create
button.btn.btn-danger((click)='cancel()', translate) Cancel

View File

@ -0,0 +1,42 @@
import { Component } from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import path from 'path'
import { BaseComponent } from 'tabby-core'
import { SFTPFile, SFTPSession } from '../session/sftp'
import { SFTPPanelComponent } from './sftpPanel.component'
/** @hidden */
@Component({
template: require('./sftpCreateDirectoryModal.component.pug'),
})
export class SFTPCreateDirectoryModalComponent extends BaseComponent {
sftp: SFTPSession
item: SFTPFile
panel: SFTPPanelComponent
directoryName: string
constructor (
private modalInstance: NgbActiveModal,
) {
super()
}
async ngOnInit (): Promise<void> {
}
create (): void {
this.createDirectory(this.item.directory);
}
cancel (): void {
this.modalInstance.close()
}
async createDirectory (currentDirectory: string): Promise<void> {
this.sftp.mkdir(path.join(currentDirectory, this.directoryName)).finally(() => {
this.panel.navigate(path.join(currentDirectory, this.directoryName));
this.cancel();
});
}
}

View File

@ -26,6 +26,7 @@ import { SFTPContextMenu } from './tabContextMenu'
import { SSHProfilesService } from './profiles'
import { SFTPContextMenuItemProvider } from './api/contextMenu'
import { CommonSFTPContextMenu } from './sftpContextMenu'
import { SFTPCreateDirectoryModalComponent } from './components/sftpCreateDirectoryModal.component'
/** @hidden */
@NgModule({
@ -50,6 +51,7 @@ import { CommonSFTPContextMenu } from './sftpContextMenu'
entryComponents: [
SSHProfileSettingsComponent,
SFTPDeleteModalComponent,
SFTPCreateDirectoryModalComponent,
SSHPortForwardingModalComponent,
SSHSettingsTabComponent,
SSHTabComponent,
@ -58,6 +60,7 @@ import { CommonSFTPContextMenu } from './sftpContextMenu'
declarations: [
SSHProfileSettingsComponent,
SFTPDeleteModalComponent,
SFTPCreateDirectoryModalComponent,
SSHPortForwardingModalComponent,
SSHPortForwardingConfigComponent,
SSHSettingsTabComponent,

View File

@ -12,6 +12,7 @@ import type { FileEntry, Stats } from 'ssh2-streams'
export interface SFTPFile {
name: string
fullPath: string
directory: string
isDirectory: boolean
isSymlink: boolean
mode: number
@ -103,6 +104,7 @@ export class SFTPSession {
const stats = await wrapPromise(this.zone, promisify<Stats>(f => this.sftp.stat(p, f))())
return {
name: posixPath.basename(p),
directory: posixPath.dirname(p),
fullPath: p,
isDirectory: stats.isDirectory(),
isSymlink: stats.isSymbolicLink(),
@ -123,6 +125,11 @@ export class SFTPSession {
await promisify((f: any) => this.sftp.rmdir(p, f))()
}
async mkdir (p: string): Promise<void> {
this.logger.debug('mkdir', p)
await promisify((f: any) => this.sftp.mkdir(p, f))()
}
async rename (oldPath: string, newPath: string): Promise<void> {
this.logger.debug('rename', oldPath, newPath)
await promisify((f: any) => this.sftp.rename(oldPath, newPath, f))()
@ -181,6 +188,7 @@ export class SFTPSession {
return {
fullPath: p,
name: posixPath.basename(p),
directory: posixPath.dirname(p),
isDirectory: (entry.attrs.mode & C.S_IFDIR) === C.S_IFDIR,
isSymlink: (entry.attrs.mode & C.S_IFLNK) === C.S_IFLNK,
mode: entry.attrs.mode,

View File

@ -5,6 +5,7 @@ import { SFTPSession, SFTPFile } from './session/sftp'
import { SFTPContextMenuItemProvider } from './api'
import { SFTPDeleteModalComponent } from './components/sftpDeleteModal.component'
import { SFTPPanelComponent } from './components/sftpPanel.component'
import { SFTPCreateDirectoryModalComponent } from './components/sftpCreateDirectoryModal.component'
/** @hidden */
@ -22,6 +23,12 @@ export class CommonSFTPContextMenu extends SFTPContextMenuItemProvider {
async getItems (item: SFTPFile, panel: SFTPPanelComponent): Promise<MenuItemOptions[]> {
return [
{
click: async () => {
await this.createDirectory(item, panel);
},
label: this.translate.instant('Create Directory'),
},
{
click: async () => {
if ((await this.platform.showMessageBox({
@ -49,4 +56,12 @@ export class CommonSFTPContextMenu extends SFTPContextMenuItemProvider {
modal.componentInstance.sftp = session
await modal.result
}
async createDirectory (item: SFTPFile, panel: SFTPPanelComponent): Promise<void> {
const modal = this.ngbModal.open(SFTPCreateDirectoryModalComponent)
modal.componentInstance.item = item
modal.componentInstance.sftp = panel.sftp
modal.componentInstance.panel = panel
await modal.result
}
}