Skip to content

Commit 56ee368

Browse files
authored
SFTP filter bar (#10590)
1 parent b31c2a5 commit 56ee368

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

tabby-ssh/src/components/sftpPanel.component.pug

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
.breadcrumb-spacer.flex-grow-1.h-100((dblclick)='editPath()')
1919

20+
button.btn.btn-link.btn-sm.flex-shrink-0.d-flex(*ngIf='!showFilter', (click)='showFilter = true')
21+
i.fas.fa-filter.me-1
22+
div(translate) Filter
23+
2024
button.btn.btn-link.btn-sm.flex-shrink-0.d-flex((click)='openCreateDirectoryModal()')
2125
i.fas.fa-plus.me-1
2226
div(translate) Create directory
@@ -31,6 +35,19 @@
3135

3236
button.btn.btn-link.text-decoration-none((click)='close()') !{require('../../../tabby-core/src/icons/times.svg')}
3337

38+
.filter-bar.px-3.py-2.border-bottom(*ngIf='showFilter')
39+
.input-group
40+
input.form-control(
41+
type='text',
42+
placeholder='Filter...',
43+
autofocus,
44+
[(ngModel)]='filterText',
45+
(input)='onFilterChange()',
46+
(keydown.escape)='clearFilter()'
47+
)
48+
button.btn.btn-secondary((click)='clearFilter()')
49+
i.fas.fa-times
50+
3451
.body(dropZone, (transfer)='uploadOneFolder($event)')
3552
a.alert.alert-info.d-flex.align-items-center(
3653
*ngIf='shouldShowCWDTip && !cwdDetectionAvailable',
@@ -47,13 +64,13 @@
4764
div(*ngIf='fileList === null', translate) Loading
4865
.list-group.list-group-light(*ngIf='fileList !== null')
4966
.list-group-item.list-group-item-action.d-flex.align-items-center(
50-
*ngIf='path !== "/"',
67+
*ngIf='path !== "/" && (!showFilter || filterText.trim() === "")',
5168
(click)='goUp()'
5269
)
5370
i.fas.fa-fw.fa-level-up-alt
5471
div(translate) Go up
5572
.list-group-item.list-group-item-action.d-flex.align-items-center(
56-
*ngFor='let item of fileList',
73+
*ngFor='let item of filteredFileList',
5774
(contextmenu)='showContextMenu(item, $event)',
5875
(click)='open(item)'
5976
)
@@ -63,3 +80,6 @@
6380
.size(*ngIf='!item.isDirectory') {{item.size|filesize}}
6481
.date {{item.modified|tabbyDate}}
6582
.mode {{getModeString(item)}}
83+
.alert.alert-info.text-center.mt-3(*ngIf='fileList !== null && filteredFileList.length === 0 && showFilter && filterText.trim() !== ""')
84+
i.fas.fa-search.me-2
85+
span(translate) No files match the filter "{{filterText}}"

tabby-ssh/src/components/sftpPanel.component.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
flex: none;
1010
}
1111

12+
> .filter-bar {
13+
flex: none;
14+
}
15+
1216
> .body {
1317
padding: 10px 20px;
1418
flex: 1 1 0;

tabby-ssh/src/components/sftpPanel.component.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,14 @@ export class SFTPPanelComponent {
2323
@Output() closed = new EventEmitter<void>()
2424
sftp: SFTPSession
2525
fileList: SFTPFile[]|null = null
26+
filteredFileList: SFTPFile[] = []
2627
@Input() path = '/'
2728
@Output() pathChange = new EventEmitter<string>()
2829
pathSegments: PathSegment[] = []
2930
@Input() cwdDetectionAvailable = false
3031
editingPath: string|null = null
32+
showFilter = false
33+
filterText = ''
3134

3235
constructor (
3336
private ngbModal: NgbModal,
@@ -54,6 +57,8 @@ export class SFTPPanelComponent {
5457
this.path = newPath
5558
this.pathChange.next(this.path)
5659

60+
this.clearFilter()
61+
5762
let p = newPath
5863
this.pathSegments = []
5964
while (p !== '/') {
@@ -65,6 +70,7 @@ export class SFTPPanelComponent {
6570
}
6671

6772
this.fileList = null
73+
this.filteredFileList = []
6874
try {
6975
this.fileList = await this.sftp.readdir(this.path)
7076
} catch (error) {
@@ -79,6 +85,8 @@ export class SFTPPanelComponent {
7985
this.fileList.sort((a, b) =>
8086
dirKey(b) - dirKey(a) ||
8187
a.name.localeCompare(b.name))
88+
89+
this.updateFilteredList()
8290
}
8391

8492
getFileType (fileExtension: string): string {
@@ -336,4 +344,29 @@ export class SFTPPanelComponent {
336344
this.closed.emit()
337345
}
338346

347+
clearFilter (): void {
348+
this.showFilter = false
349+
this.filterText = ''
350+
this.updateFilteredList()
351+
}
352+
353+
onFilterChange (): void {
354+
this.updateFilteredList()
355+
}
356+
357+
private updateFilteredList (): void {
358+
if (!this.fileList) {
359+
this.filteredFileList = []
360+
return
361+
}
362+
363+
if (!this.showFilter || this.filterText.trim() === '') {
364+
this.filteredFileList = this.fileList
365+
return
366+
}
367+
368+
this.filteredFileList = this.fileList.filter(item =>
369+
item.name.toLowerCase().includes(this.filterText.toLowerCase()),
370+
)
371+
}
339372
}

0 commit comments

Comments
 (0)