mirror of
https://github.com/Eugeny/tabby.git
synced 2025-06-08 21:40:03 +00:00
SFTP Feature: implement Create Folder
This commit is contained in:
parent
40cf2bde9b
commit
e223effe98
@ -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
|
@ -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();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@ import { SFTPContextMenu } from './tabContextMenu'
|
|||||||
import { SSHProfilesService } from './profiles'
|
import { SSHProfilesService } from './profiles'
|
||||||
import { SFTPContextMenuItemProvider } from './api/contextMenu'
|
import { SFTPContextMenuItemProvider } from './api/contextMenu'
|
||||||
import { CommonSFTPContextMenu } from './sftpContextMenu'
|
import { CommonSFTPContextMenu } from './sftpContextMenu'
|
||||||
|
import { SFTPCreateDirectoryModalComponent } from './components/sftpCreateDirectoryModal.component'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -50,6 +51,7 @@ import { CommonSFTPContextMenu } from './sftpContextMenu'
|
|||||||
entryComponents: [
|
entryComponents: [
|
||||||
SSHProfileSettingsComponent,
|
SSHProfileSettingsComponent,
|
||||||
SFTPDeleteModalComponent,
|
SFTPDeleteModalComponent,
|
||||||
|
SFTPCreateDirectoryModalComponent,
|
||||||
SSHPortForwardingModalComponent,
|
SSHPortForwardingModalComponent,
|
||||||
SSHSettingsTabComponent,
|
SSHSettingsTabComponent,
|
||||||
SSHTabComponent,
|
SSHTabComponent,
|
||||||
@ -58,6 +60,7 @@ import { CommonSFTPContextMenu } from './sftpContextMenu'
|
|||||||
declarations: [
|
declarations: [
|
||||||
SSHProfileSettingsComponent,
|
SSHProfileSettingsComponent,
|
||||||
SFTPDeleteModalComponent,
|
SFTPDeleteModalComponent,
|
||||||
|
SFTPCreateDirectoryModalComponent,
|
||||||
SSHPortForwardingModalComponent,
|
SSHPortForwardingModalComponent,
|
||||||
SSHPortForwardingConfigComponent,
|
SSHPortForwardingConfigComponent,
|
||||||
SSHSettingsTabComponent,
|
SSHSettingsTabComponent,
|
||||||
|
@ -12,6 +12,7 @@ import type { FileEntry, Stats } from 'ssh2-streams'
|
|||||||
export interface SFTPFile {
|
export interface SFTPFile {
|
||||||
name: string
|
name: string
|
||||||
fullPath: string
|
fullPath: string
|
||||||
|
directory: string
|
||||||
isDirectory: boolean
|
isDirectory: boolean
|
||||||
isSymlink: boolean
|
isSymlink: boolean
|
||||||
mode: number
|
mode: number
|
||||||
@ -103,6 +104,7 @@ export class SFTPSession {
|
|||||||
const stats = await wrapPromise(this.zone, promisify<Stats>(f => this.sftp.stat(p, f))())
|
const stats = await wrapPromise(this.zone, promisify<Stats>(f => this.sftp.stat(p, f))())
|
||||||
return {
|
return {
|
||||||
name: posixPath.basename(p),
|
name: posixPath.basename(p),
|
||||||
|
directory: posixPath.dirname(p),
|
||||||
fullPath: p,
|
fullPath: p,
|
||||||
isDirectory: stats.isDirectory(),
|
isDirectory: stats.isDirectory(),
|
||||||
isSymlink: stats.isSymbolicLink(),
|
isSymlink: stats.isSymbolicLink(),
|
||||||
@ -123,6 +125,11 @@ export class SFTPSession {
|
|||||||
await promisify((f: any) => this.sftp.rmdir(p, f))()
|
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> {
|
async rename (oldPath: string, newPath: string): Promise<void> {
|
||||||
this.logger.debug('rename', oldPath, newPath)
|
this.logger.debug('rename', oldPath, newPath)
|
||||||
await promisify((f: any) => this.sftp.rename(oldPath, newPath, f))()
|
await promisify((f: any) => this.sftp.rename(oldPath, newPath, f))()
|
||||||
@ -181,6 +188,7 @@ export class SFTPSession {
|
|||||||
return {
|
return {
|
||||||
fullPath: p,
|
fullPath: p,
|
||||||
name: posixPath.basename(p),
|
name: posixPath.basename(p),
|
||||||
|
directory: posixPath.dirname(p),
|
||||||
isDirectory: (entry.attrs.mode & C.S_IFDIR) === C.S_IFDIR,
|
isDirectory: (entry.attrs.mode & C.S_IFDIR) === C.S_IFDIR,
|
||||||
isSymlink: (entry.attrs.mode & C.S_IFLNK) === C.S_IFLNK,
|
isSymlink: (entry.attrs.mode & C.S_IFLNK) === C.S_IFLNK,
|
||||||
mode: entry.attrs.mode,
|
mode: entry.attrs.mode,
|
||||||
|
@ -5,6 +5,7 @@ import { SFTPSession, SFTPFile } from './session/sftp'
|
|||||||
import { SFTPContextMenuItemProvider } from './api'
|
import { SFTPContextMenuItemProvider } from './api'
|
||||||
import { SFTPDeleteModalComponent } from './components/sftpDeleteModal.component'
|
import { SFTPDeleteModalComponent } from './components/sftpDeleteModal.component'
|
||||||
import { SFTPPanelComponent } from './components/sftpPanel.component'
|
import { SFTPPanelComponent } from './components/sftpPanel.component'
|
||||||
|
import { SFTPCreateDirectoryModalComponent } from './components/sftpCreateDirectoryModal.component'
|
||||||
|
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@ -22,6 +23,12 @@ export class CommonSFTPContextMenu extends SFTPContextMenuItemProvider {
|
|||||||
|
|
||||||
async getItems (item: SFTPFile, panel: SFTPPanelComponent): Promise<MenuItemOptions[]> {
|
async getItems (item: SFTPFile, panel: SFTPPanelComponent): Promise<MenuItemOptions[]> {
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
click: async () => {
|
||||||
|
await this.createDirectory(item, panel);
|
||||||
|
},
|
||||||
|
label: this.translate.instant('Create Directory'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
click: async () => {
|
click: async () => {
|
||||||
if ((await this.platform.showMessageBox({
|
if ((await this.platform.showMessageBox({
|
||||||
@ -49,4 +56,12 @@ export class CommonSFTPContextMenu extends SFTPContextMenuItemProvider {
|
|||||||
modal.componentInstance.sftp = session
|
modal.componentInstance.sftp = session
|
||||||
await modal.result
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user