phirepass-widgets 0.0.47 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/cjs/{index-BiurVooY.js → index-DqslB2R4.js} +27 -2
  2. package/dist/cjs/loader.cjs.js +2 -2
  3. package/dist/cjs/phirepass-sftp-client.cjs.entry.js +157 -19
  4. package/dist/cjs/phirepass-terminal.cjs.entry.js +2 -2
  5. package/dist/cjs/phirepass-widgets.cjs.js +2 -2
  6. package/dist/collection/components/phirepass-sftp-client/phirepass-sftp-client.css +243 -0
  7. package/dist/collection/components/phirepass-sftp-client/phirepass-sftp-client.download.svg +7 -0
  8. package/dist/collection/components/phirepass-sftp-client/phirepass-sftp-client.js +167 -18
  9. package/dist/collection/components/phirepass-terminal/phirepass-terminal.js +1 -1
  10. package/dist/components/index.js +1 -1
  11. package/dist/components/phirepass-sftp-client.js +1 -1
  12. package/dist/components/phirepass-terminal.js +1 -1
  13. package/dist/esm/{index-zZMsduaU.js → index-jdexunMF.js} +27 -2
  14. package/dist/esm/loader.js +3 -3
  15. package/dist/esm/phirepass-sftp-client.entry.js +157 -19
  16. package/dist/esm/phirepass-terminal.entry.js +2 -2
  17. package/dist/esm/phirepass-widgets.js +3 -3
  18. package/dist/phirepass-widgets/p-11d53a8d.entry.js +1 -0
  19. package/dist/phirepass-widgets/{p-5b21bc31.entry.js → p-282d5896.entry.js} +5 -5
  20. package/dist/phirepass-widgets/p-jdexunMF.js +2 -0
  21. package/dist/phirepass-widgets/phirepass-widgets.esm.js +1 -1
  22. package/dist/types/components/phirepass-sftp-client/phirepass-sftp-client.d.ts +23 -0
  23. package/package.json +1 -1
  24. package/dist/phirepass-widgets/p-32ca8ca5.entry.js +0 -1
  25. package/dist/phirepass-widgets/p-zZMsduaU.js +0 -2
@@ -272,6 +272,12 @@
272
272
  background-color: hsl(var(--muted));
273
273
  border-bottom: 1px solid hsl(var(--border));
274
274
  line-height: 0.95rem;
275
+
276
+ &.action-col {
277
+ width: 58px;
278
+ min-width: 58px;
279
+ padding: 0 10px;
280
+ }
275
281
  }
276
282
  }
277
283
 
@@ -284,6 +290,51 @@
284
290
  padding: 10px 10px 9px;
285
291
  color: hsl(var(--muted-foreground));
286
292
 
293
+ &.action-col {
294
+ width: 58px;
295
+ min-width: 58px;
296
+ text-align: center;
297
+ padding-left: 1px;
298
+ padding-right: 1px;
299
+
300
+ .file-actions {
301
+ display: flex;
302
+ align-items: center;
303
+ justify-content: center;
304
+ gap: 8px;
305
+ }
306
+
307
+ .file-action {
308
+ border: none;
309
+ background: transparent;
310
+ color: hsl(var(--muted-foreground));
311
+ width: 16px;
312
+ height: 16px;
313
+ border-radius: 3px;
314
+ cursor: pointer;
315
+ opacity: 0;
316
+ visibility: hidden;
317
+ pointer-events: none;
318
+ transition: opacity 120ms ease;
319
+ padding: 0;
320
+
321
+ svg {
322
+ width: 12px;
323
+ height: 12px;
324
+ display: block;
325
+ margin: 0 auto;
326
+ }
327
+
328
+ &:hover {
329
+ color: hsl(var(--primary));
330
+ }
331
+
332
+ &.delete:hover {
333
+ color: hsl(var(--destructive));
334
+ }
335
+ }
336
+ }
337
+
287
338
  .name {
288
339
  &.file {
289
340
  color: rgb(189, 219, 209);
@@ -305,11 +356,24 @@
305
356
  &:hover {
306
357
  cursor: pointer;
307
358
  background-color: hsl(var(--muted) / 0.4);
359
+
360
+ td.action-col .file-action {
361
+ opacity: 1;
362
+ visibility: visible;
363
+ pointer-events: auto;
364
+ color: hsl(var(--primary));
365
+ }
308
366
  }
309
367
 
310
368
  &.selected {
311
369
  background-color: hsl(var(--primary) / 0.3);
312
370
 
371
+ td.action-col .file-action {
372
+ opacity: 1;
373
+ visibility: visible;
374
+ pointer-events: auto;
375
+ }
376
+
313
377
  &:hover {
314
378
  background-color: hsl(var(--primary) / 0.4);
315
379
  }
@@ -434,6 +498,185 @@
434
498
  }
435
499
  }
436
500
  }
501
+
502
+ .upload-modal,
503
+ .download-modal,
504
+ .delete-modal {
505
+ position: absolute;
506
+ inset: 0;
507
+ display: none;
508
+ align-items: center;
509
+ justify-content: center;
510
+ background: rgba(28, 31, 38, 0);
511
+ backdrop-filter: blur(4px);
512
+ z-index: 6;
513
+
514
+ &.visible {
515
+ display: flex;
516
+ }
517
+
518
+ .upload-dialog,
519
+ .download-dialog,
520
+ .delete-dialog {
521
+ width: min(360px, calc(100% - 24px));
522
+ background-color: rgba(21, 24, 30, 0.96);
523
+ border: 1px solid hsl(var(--border));
524
+ border-radius: var(--radius);
525
+ padding: 16px;
526
+ box-shadow:
527
+ rgba(0, 0, 0, 0) 0px 0px 0px 0px,
528
+ rgba(0, 0, 0, 0) 0px 0px 0px 0px,
529
+ rgba(0, 0, 0, 0.5) 0px 25px 50px -12px;
530
+
531
+ .title {
532
+ color: hsl(var(--primary));
533
+ font-size: 0.8rem;
534
+ margin-bottom: 8px;
535
+ }
536
+
537
+ .file-name {
538
+ color: rgb(189, 219, 209);
539
+ font-size: 0.72rem;
540
+ line-height: 1rem;
541
+ margin-bottom: 10px;
542
+ white-space: nowrap;
543
+ overflow: hidden;
544
+ text-overflow: ellipsis;
545
+ }
546
+
547
+ .progress-track {
548
+ width: 100%;
549
+ height: 10px;
550
+ border-radius: 999px;
551
+ background-color: hsl(var(--muted));
552
+ overflow: hidden;
553
+ border: 1px solid hsl(var(--border));
554
+
555
+ .progress-fill {
556
+ height: 100%;
557
+ width: 0;
558
+ background: linear-gradient(90deg, hsl(var(--primary) / 0.7), hsl(var(--primary)));
559
+ transition: width 140ms ease;
560
+ }
561
+ }
562
+
563
+ .progress-value {
564
+ margin-top: 8px;
565
+ color: hsl(var(--muted-foreground));
566
+ font-size: 0.7rem;
567
+ text-align: right;
568
+ }
569
+
570
+ .cancel {
571
+ margin-top: 14px;
572
+ width: 100%;
573
+ height: 2rem;
574
+ border: 1px solid hsl(var(--border));
575
+ border-radius: calc(var(--radius) - 2px);
576
+ background: hsl(var(--muted));
577
+ color: rgb(189, 219, 209);
578
+ font-size: 0.75rem;
579
+ letter-spacing: 0.03em;
580
+ cursor: pointer;
581
+
582
+ &:hover {
583
+ border-color: hsl(var(--primary));
584
+ color: hsl(var(--primary));
585
+ }
586
+
587
+ &.finished {
588
+ background-color: hsl(var(--primary));
589
+ border-color: hsl(var(--primary));
590
+ color: hsl(var(--primary-foreground));
591
+
592
+ &:hover {
593
+ background-color: hsl(var(--primary) / 0.9);
594
+ border-color: hsl(var(--primary) / 0.9);
595
+ color: hsl(var(--primary-foreground));
596
+ }
597
+ }
598
+ }
599
+
600
+ .message {
601
+ color: rgb(189, 219, 209);
602
+ font-size: 0.74rem;
603
+ line-height: 1rem;
604
+ margin-bottom: 8px;
605
+ }
606
+
607
+ .modal-actions {
608
+ margin-top: 14px;
609
+ display: grid;
610
+ grid-template-columns: 1fr 1fr;
611
+ gap: 8px;
612
+
613
+ .btn {
614
+ height: 2rem;
615
+ border: 1px solid hsl(var(--border));
616
+ border-radius: calc(var(--radius) - 2px);
617
+ font-size: 0.75rem;
618
+ letter-spacing: 0.03em;
619
+ cursor: pointer;
620
+
621
+ &:disabled {
622
+ opacity: 0.65;
623
+ cursor: not-allowed;
624
+ }
625
+ }
626
+
627
+ .btn.secondary {
628
+ background: hsl(var(--muted));
629
+ color: rgb(189, 219, 209);
630
+
631
+ &:hover {
632
+ border-color: hsl(var(--primary));
633
+ color: hsl(var(--primary));
634
+ }
635
+ }
636
+
637
+ .btn.destructive {
638
+ background: hsl(var(--destructive));
639
+ border-color: hsl(var(--destructive));
640
+ color: white;
641
+
642
+ &:hover {
643
+ background: hsl(var(--destructive) / 0.9);
644
+ border-color: hsl(var(--destructive) / 0.9);
645
+ }
646
+ }
647
+ }
648
+
649
+ .delete-loading-bar {
650
+ margin-top: 2px;
651
+ width: 100%;
652
+ height: 8px;
653
+ border-radius: 999px;
654
+ border: 1px solid hsl(var(--border));
655
+ background:
656
+ linear-gradient(90deg, hsl(var(--muted)) 0%, hsl(var(--muted)) 100%),
657
+ linear-gradient(90deg, hsl(var(--primary) / 0.3), hsl(var(--primary)), hsl(var(--primary) / 0.3));
658
+ background-repeat: no-repeat;
659
+ background-size:
660
+ 100% 100%,
661
+ 40% 100%;
662
+ animation: delete-loading 1s linear infinite;
663
+ }
664
+ }
665
+ }
666
+ }
667
+
668
+ @keyframes delete-loading {
669
+ from {
670
+ background-position:
671
+ 0 0,
672
+ -45% 0;
673
+ }
674
+
675
+ to {
676
+ background-position:
677
+ 0 0,
678
+ 145% 0;
679
+ }
437
680
  }
438
681
 
439
682
  :host(.max) {
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
2
+ stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
3
+ class="lucide lucide-download w-3 h-3 text-primary">
4
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
5
+ <polyline points="7 10 12 15 17 10"></polyline>
6
+ <line x1="12" x2="12" y1="15" y2="3"></line>
7
+ </svg>
@@ -16,6 +16,9 @@ export class PhirepassSftpClient {
16
16
  runtimeReady = false;
17
17
  connected = false;
18
18
  uploadInputEl;
19
+ uploadProgressHandle;
20
+ downloadProgressHandle;
21
+ deleteLoadingTimeout;
19
22
  // private inputMode: InputMode = InputMode.Default;
20
23
  session_id;
21
24
  // private usernameBuffer = "";
@@ -73,6 +76,17 @@ export class PhirepassSftpClient {
73
76
  version = '';
74
77
  status = 'Disconnected';
75
78
  selected_item = null;
79
+ show_upload_modal = false;
80
+ upload_progress = 0;
81
+ upload_file_name = '';
82
+ upload_finished = false;
83
+ show_download_modal = false;
84
+ download_progress = 0;
85
+ download_file_name = '';
86
+ download_finished = false;
87
+ show_delete_modal = false;
88
+ delete_file_name = '';
89
+ delete_loading = false;
76
90
  toggle_max() {
77
91
  this.maximizeEvent?.emit(!this.max);
78
92
  }
@@ -103,9 +117,30 @@ export class PhirepassSftpClient {
103
117
  this.connected = false;
104
118
  this.domReady = false;
105
119
  this.runtimeReady = false;
120
+ this.clear_upload_progress();
121
+ this.clear_download_progress();
122
+ this.clear_delete_loading_timeout();
106
123
  this.close_comms();
107
124
  // this.destroy_terminal();
108
125
  }
126
+ clear_upload_progress() {
127
+ if (this.uploadProgressHandle !== undefined) {
128
+ window.clearInterval(this.uploadProgressHandle);
129
+ this.uploadProgressHandle = undefined;
130
+ }
131
+ }
132
+ clear_download_progress() {
133
+ if (this.downloadProgressHandle !== undefined) {
134
+ window.clearInterval(this.downloadProgressHandle);
135
+ this.downloadProgressHandle = undefined;
136
+ }
137
+ }
138
+ clear_delete_loading_timeout() {
139
+ if (this.deleteLoadingTimeout !== undefined) {
140
+ window.clearTimeout(this.deleteLoadingTimeout);
141
+ this.deleteLoadingTimeout = undefined;
142
+ }
143
+ }
109
144
  connect() {
110
145
  this.connected = true;
111
146
  this.channel.connect();
@@ -295,25 +330,109 @@ export class PhirepassSftpClient {
295
330
  disconnect_session() {
296
331
  this.close_comms();
297
332
  this.session_id = undefined;
298
- this.status = 'Disconnected';
299
333
  this.show_loader = false;
334
+ this.show_content = false;
335
+ this.breadcrumbs = [];
336
+ this.current_dir = '.';
337
+ this.listing = [];
338
+ this.show_navigation = false;
339
+ this.show_login_screen_username = false;
340
+ this.show_login_screen_password = false;
341
+ this.show_login_screen = false;
342
+ this.version = '';
343
+ this.status = 'Disconnected';
344
+ }
345
+ on_file_row_action(item, event) {
346
+ event.preventDefault();
347
+ event.stopPropagation();
348
+ this.selected_item = item;
349
+ this.download_file_name = item.name;
350
+ this.download_progress = 0;
351
+ this.download_finished = false;
352
+ this.show_download_modal = true;
353
+ this.clear_download_progress();
354
+ this.downloadProgressHandle = window.setInterval(() => {
355
+ if (this.download_progress >= 100) {
356
+ this.clear_download_progress();
357
+ this.download_finished = true;
358
+ return;
359
+ }
360
+ this.download_progress = Math.min(100, this.download_progress + 5);
361
+ }, 180);
362
+ }
363
+ on_file_delete_action(item, event) {
364
+ event.preventDefault();
365
+ event.stopPropagation();
366
+ this.selected_item = item;
367
+ this.delete_file_name = item.name;
368
+ this.delete_loading = false;
369
+ this.show_delete_modal = true;
370
+ }
371
+ cancel_delete() {
372
+ if (this.delete_loading) {
373
+ return;
374
+ }
375
+ this.show_delete_modal = false;
376
+ this.delete_file_name = '';
377
+ this.delete_loading = false;
378
+ }
379
+ confirm_delete() {
380
+ if (this.delete_loading) {
381
+ return;
382
+ }
383
+ this.delete_loading = true;
384
+ const deletingFileName = this.delete_file_name;
385
+ this.clear_delete_loading_timeout();
386
+ this.deleteLoadingTimeout = window.setTimeout(() => {
387
+ this.show_delete_modal = false;
388
+ this.delete_loading = false;
389
+ this.show_error = true;
390
+ this.error_message = `Delete for "${deletingFileName}" is not available yet.`;
391
+ window.setTimeout(() => {
392
+ this.show_error = false;
393
+ }, 2_000);
394
+ this.delete_file_name = '';
395
+ this.deleteLoadingTimeout = undefined;
396
+ }, 1_100);
300
397
  }
301
398
  open_upload_picker() {
302
399
  this.uploadInputEl?.click();
303
400
  }
304
401
  on_upload_selected(event) {
305
402
  const input = event.target;
306
- const file = input.files?.[0];
307
- if (!file) {
403
+ const selectedFile = input.files?.[0];
404
+ if (!selectedFile) {
308
405
  return;
309
406
  }
310
- this.show_error = true;
311
- this.error_message = 'Upload is not available yet in this widget.';
312
- setTimeout(() => {
313
- this.show_error = false;
314
- }, 2_000);
407
+ this.upload_file_name = selectedFile.name;
408
+ this.upload_progress = 0;
409
+ this.upload_finished = false;
410
+ this.show_upload_modal = true;
411
+ this.clear_upload_progress();
412
+ this.uploadProgressHandle = window.setInterval(() => {
413
+ if (this.upload_progress >= 100) {
414
+ this.clear_upload_progress();
415
+ this.upload_finished = true;
416
+ return;
417
+ }
418
+ this.upload_progress = Math.min(100, this.upload_progress + 5);
419
+ }, 180);
315
420
  input.value = '';
316
421
  }
422
+ cancel_upload() {
423
+ this.clear_upload_progress();
424
+ this.show_upload_modal = false;
425
+ this.upload_progress = 0;
426
+ this.upload_file_name = '';
427
+ this.upload_finished = false;
428
+ }
429
+ cancel_download() {
430
+ this.clear_download_progress();
431
+ this.show_download_modal = false;
432
+ this.download_progress = 0;
433
+ this.download_file_name = '';
434
+ this.download_finished = false;
435
+ }
317
436
  is_selected(item) {
318
437
  if (!this.selected_item) {
319
438
  return false;
@@ -344,17 +463,18 @@ export class PhirepassSftpClient {
344
463
  return [item.path, item.name].join('/');
345
464
  }
346
465
  render() {
347
- return (h(Host, { key: 'c19b87e943347cc55424450e7e4f10bc3447e828', class: {
466
+ return (h(Host, { key: '31a797ab81c687e6aaea760d882e8078d4ab226f', class: {
348
467
  'default': !this.max,
349
468
  'max': this.max,
350
- } }, h("section", { key: '88ecbc0d1a1460dd262150706216f7f758fb7981', class: "listing" }, !this.hideHeader &&
351
- h("header", { key: 'dd28677d023aeaf431cb3b99449751f6385c767d' }, h("section", { key: 'ad56b31550d096cb59e92bc6167be11b76a9c368', class: "title" }, h("img", { key: '00ce4e832edfb672b0eadb0462a5a132cfa67e09', src: svg, alt: "SFTP Client" }), h("div", { key: 'ee186cc2c643afefa425bb6ce862686dce5ba6ab', class: "text" }, h("div", { key: '29c5922bf9826930ac33fe6c200bf47fce1e183e', class: "name" }, this.name), h("div", { key: '76d6bba6cb51b9907db533395c258ee7458cf5ce', class: "description" }, this.description))), h("section", { key: 'd3bfbf402aed51cba973830b14b9d4f276011535', class: "actions" }, h("div", { key: '87eb4484d8552a582c35e4960a82003f7570bf26', class: "action", onClick: () => this.toggle_max() }, h("img", { key: '3ff40a471fc54a1d97a4aa5c4746dc837082307d', src: max, alt: "Maximize" })))), h("main", { key: 'a441806676df938682df422acce7b640e452eece' }, this.show_navigation && h("nav", { key: 'd7fe91b30ecd998985301c2f0ac5064ee4bfc9fa', class: "navigation" }, h("div", { key: '17bd0d958fb55b8a89b6af7becbeb1cd892066a5', class: "breadcrumbs" }, this.breadcrumbs.map((crumb, index, breadcrumbs) => (h(h.Fragment, null, h("span", { key: index, onClick: () => this.list_breadcrumb(crumb.path), class: "breadcrumb" }, crumb.label), index < breadcrumbs.length - 1 && h("img", { class: "arrow", src: chevron }))))), h("section", { key: '0f65ff3c51a3aeba3bf046445fc858b05e1e5106', class: "actions", "aria-label": "SFTP actions" }, h("button", { key: '5184ea48385f5b1f235e7fe0a01eed0171782e76', type: "button", class: "action", onClick: () => this.go_to_parent_directory(), title: "Go to parent directory", "aria-label": "Go to parent directory" }, h("img", { key: '345aa00fe17569c8d9037e9304b381868effe862', src: go_up, alt: "Go up" })), h("button", { key: 'eec7a682ed944746eabf939dfff1073bb85dfae6', type: "button", class: "action", onClick: () => this.refresh_directory(), title: "Refresh", "aria-label": "Refresh" }, h("img", { key: 'ab1faf4dc27ca0a85b152c559b2f4953c7fddb15', src: refresh, alt: "Refresh" })), h("button", { key: '529ad0cd6e000978294be16aedb9ec8f2b6d699e', type: "button", class: "action", onClick: () => this.open_upload_picker(), title: "Upload", "aria-label": "Upload" }, h("img", { key: '669ceed59555391014ea531e4398517a1c4bc77a', src: upload, alt: "Upload" })), h("button", { key: '3b0602bd52a1ed066e76f136ba18e67a2e923f05', type: "button", class: "action disconnect", onClick: () => this.disconnect_session(), title: "Disconnect", "aria-label": "Disconnect" }, "DISCONNECT"))), h("input", { key: '272d2fe2f2d61b02c4d2e5c8624f2c0ccc7daa92', type: "file", ref: (el) => this.uploadInputEl = el, onChange: (event) => this.on_upload_selected(event), style: { display: 'none' } }), this.show_content && h("div", { key: '2f080688bfa4c95663c278d875eceebbda78094a', class: "content" }, h("table", { key: '3c10b9615ba21dce3aaa47850d03f083d0ef0107' }, h("thead", { key: '366af5b1b875d394450b78b6490c813ac930f0fa' }, h("tr", { key: 'd3116485a0f02953c96e309f1c44d5e47cea9dcd' }, h("th", { key: '6af47d08c0bac5dd887ceda7b3f75101caeaebc3' }, "Name"), h("th", { key: '3c8c72711429b988e24118810ef3ea30eb779bb7' }, "Size"), h("th", { key: '8dd16c387287e4dd3bf29dbea304f6dd8871686a' }, "Permissions"), h("th", { key: '7b2c6ca49d8dd4150895307a4499d3e083cc8900' }, "Owner"), h("th", { key: '1723d32cf185dbaeea6d3bd9dbe3f72fc055c5a2' }, "Modified"))), h("tbody", { key: '685d9eae4f0ac61e07b44710be235bafaaefa7df' }, this.listing.map((item, index) => (h("tr", { key: index, class: {
469
+ } }, h("section", { key: '0dd1df187509d0f2c3dc172119f97224a1fb8234', class: "listing" }, !this.hideHeader &&
470
+ h("header", { key: 'af24358a2d1d6ec9dc282683b1feff0a29287dd0' }, h("section", { key: 'f0195c9b0f99fe3c7ca64c7db04a3b08255bb58e', class: "title" }, h("img", { key: 'e04889ab957ccddb181850a5a787b6e40191842e', src: svg, alt: "SFTP Client" }), h("div", { key: 'dc364ca7481d3b78e99319c66a6a40dc29100ea4', class: "text" }, h("div", { key: '7b226fe3a81631656e8fce0b5a69854c3aaeb9c5', class: "name" }, this.name), h("div", { key: '8a843a5134ed28a985d2d1787b17ea3c7436bd45', class: "description" }, this.description))), h("section", { key: '73aec9dd75115faf4dfbcdfde1a076c960954923', class: "actions" }, h("div", { key: 'ce75ef7f9c3433e9d6dfadb41e0716a165666ee8', class: "action", onClick: () => this.toggle_max() }, h("img", { key: 'abbba7e239c57a52dfd46ed23aeeac81874f097c', src: max, alt: "Maximize" })))), h("main", { key: 'fbdd529cfb3090f41dba72f7333efe3a1af29aa4' }, this.show_navigation && h("nav", { key: '17601f7bf03f76169a14803ad0cc11b21f72df8d', class: "navigation" }, h("div", { key: '55fffc7a4686e4978002b9edf6334b07fc57322b', class: "breadcrumbs" }, this.breadcrumbs.map((crumb, index, breadcrumbs) => (h(h.Fragment, null, h("span", { key: index, onClick: () => this.list_breadcrumb(crumb.path), class: "breadcrumb" }, crumb.label), index < breadcrumbs.length - 1 && h("img", { class: "arrow", src: chevron }))))), h("section", { key: '163eb105d575eddebad721f4e114ea8f5a8e44a1', class: "actions", "aria-label": "SFTP actions" }, h("button", { key: 'ad9cbebffdc46ba08b3d05adc33a18ad027f1b3d', type: "button", class: "action", onClick: () => this.go_to_parent_directory(), title: "Go to parent directory", "aria-label": "Go to parent directory" }, h("img", { key: '4f1bfd8154df3df70f8892b1f17391f06ac5ea3e', src: go_up, alt: "Go up" })), h("button", { key: '5bcb098f9fcfb61e6af07e9224617e82ce9e8e8b', type: "button", class: "action", onClick: () => this.refresh_directory(), title: "Refresh", "aria-label": "Refresh" }, h("img", { key: '863997b8a0ad3f465b68c10747739aa6bc123934', src: refresh, alt: "Refresh" })), h("button", { key: 'dcae91b637f58f7567709367b4607148ba6c84ce', type: "button", class: "action", onClick: () => this.open_upload_picker(), title: "Upload", "aria-label": "Upload" }, h("img", { key: '75baffc951eb5bef65be10e1b77d782048fe19bc', src: upload, alt: "Upload" })), h("button", { key: '7ce741e5e4538bfa50b330128153584cae966865', type: "button", class: "action disconnect", onClick: () => this.disconnect_session(), title: "Disconnect", "aria-label": "Disconnect" }, "DISCONNECT"))), h("input", { key: '86686c4eb1f5e56e2828687c8843ac0a0f79028b', type: "file", ref: (el) => this.uploadInputEl = el, onChange: (event) => this.on_upload_selected(event), style: { display: 'none' } }), this.show_content && h("div", { key: 'd5be43d27ae7933ad1eea5d9c7d53b3a4fa4d292', class: "content" }, h("table", { key: 'e6f57d64703faef89347da8c412eb4b224878a68' }, h("thead", { key: '89979dd9702878b6d0bccddb971c1e42353c4515' }, h("tr", { key: '9c744d7e8e12bd189ba17f6b2b7a4f371b4932eb' }, h("th", { key: '6f29cf58e3000d3d02881d38ca8065ab4174300d' }, "Name"), h("th", { key: '79ec3f7d0ac3a12a450f275845360576bd1430c6' }, "Size"), h("th", { key: 'ea1718d678f7016472688d7d08d311aad727dcc9' }, "Permissions"), h("th", { key: '6272cb391bd19801f9967b704185520799dc8a11' }, "Owner"), h("th", { key: '91fec7f7e28354e88a12fc7f92c543172800f0b3' }, "Modified"), h("th", { key: '6256a9926941f12ce4807c926e09c3a39c776d2d', class: "action-col", "aria-label": "Actions" }))), h("tbody", { key: 'f1e57f678a8381e4dad5c8daab6624849378b012' }, this.listing.map((item, index) => (h("tr", { key: index, class: {
352
471
  'selected': this.is_selected(item),
353
- }, onClick: () => this.list_directory(item) }, h("td", null, item.kind === 'Folder' ? h("img", { class: "kind", src: folder, alt: "Folder" }) : h("img", { class: "kind", src: file, alt: "File" }), h("span", { class: `name ${item.kind.toLowerCase()}` }, item.name)), h("td", null, item.attributes.size), h("td", null, item.attributes.permissions ?? '-'), h("td", null, item.attributes.user ?? '-'), h("td", null, new Date(item.attributes.mtime * 1000).toLocaleString()))))))), this.show_loader && h("div", { key: '8337354a4cd9ca456d7845ff4934ceebb36f7dc6', class: "loader" }, "Loading..."), this.show_error && h("div", { key: 'c547ad1c0f24de427a77129f77402830910e98b4', class: "error" }, this.error_message)), h("footer", { key: 'e452f0e2f7982049df57498ef9ed1cf63c70e9eb' }, h("section", { key: '00111d90943b2bfb21392dede79af5e009d43524', class: "status" }, h("span", { key: '1c10ae5cb21118059fe61625f9fc4d0aa18be448' }, this.status), this.selected_item && h("span", { key: '82939fb59d72ca3823e8c580578a6f13ce4079b0', class: "selected-item" }, this.get_full_path(this.selected_item))), h("section", { key: '38380847cf818eb024ec5743ffd92e3369b2cc40', class: "version" }, "Version: ", this.version))), this.show_login_screen &&
354
- h("section", { key: '1840f9bae95e8906c38dade1e15f6c52f360829b', class: {
472
+ }, onClick: () => this.list_directory(item) }, h("td", null, item.kind === 'Folder' ? h("img", { class: "kind", src: folder, alt: "Folder" }) : h("img", { class: "kind", src: file, alt: "File" }), h("span", { class: `name ${item.kind.toLowerCase()}` }, item.name)), h("td", null, item.attributes.size), h("td", null, item.attributes.permissions ?? '-'), h("td", null, item.attributes.user ?? '-'), h("td", null, new Date(item.attributes.mtime * 1000).toLocaleString()), h("td", { class: "action-col" }, item.kind === 'File' &&
473
+ h("div", { class: "file-actions" }, h("button", { type: "button", class: "file-action", onClick: (event) => this.on_file_row_action(item, event), title: "Download", "aria-label": "Download" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), h("polyline", { points: "7 10 12 15 17 10" }), h("line", { x1: "12", x2: "12", y1: "15", y2: "3" }))), h("button", { type: "button", class: "file-action delete", onClick: (event) => this.on_file_delete_action(item, event), title: "Delete", "aria-label": "Delete" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("polyline", { points: "3 6 5 6 21 6" }), h("path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), h("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), h("line", { x1: "10", x2: "10", y1: "11", y2: "17" }), h("line", { x1: "14", x2: "14", y1: "11", y2: "17" }))))))))))), this.show_loader && h("div", { key: '141c34cb925c0e42fca1e0397b610071b360c0d1', class: "loader" }, "Loading..."), this.show_error && h("div", { key: 'ebf97cf4b7307514e724c7778c4a9052ec32c68d', class: "error" }, this.error_message)), h("footer", { key: '1f243a6d09afe5380466dec79226bde67679ace8' }, h("section", { key: '59f7e3dd679213d76294c347f1af8ca4f3d5b3e6', class: "status" }, h("span", { key: '4aaebcfa2fea3e69d02814727c63484fd465dfee' }, this.status), this.selected_item && h("span", { key: '5f37d4f9a82a97cd5065651d5f4311104153b8a7', class: "selected-item" }, this.get_full_path(this.selected_item))), h("section", { key: '0a75c580bb9ce63e58e4cd3aef76f13f5d8a6c43', class: "version" }, this.version ? `Version: ${this.version}` : ''))), this.show_login_screen &&
474
+ h("section", { key: 'bf83e07198a7bd7f6b11164261496cee880e8e95', class: {
355
475
  'creds': true,
356
476
  'blurred': this.show_login_screen,
357
- } }, h("form", { key: 'b7b7c3494329a93aafc6c948c879ba8ecd8bd42a', class: "auth", onSubmit: (event) => {
477
+ } }, h("form", { key: 'c0b3f36031b3d0575e0dfc4d4e5c689a3e86093e', class: "auth", onSubmit: (event) => {
358
478
  const formData = new FormData(event.target);
359
479
  let username = undefined;
360
480
  if (this.show_login_screen_username) {
@@ -371,9 +491,27 @@ export class PhirepassSftpClient {
371
491
  this.show_loader = true;
372
492
  event.stopPropagation();
373
493
  event.preventDefault();
374
- } }, h("div", { key: '25a15115fb41d65d59750a176d46a7e844286e00', class: "title" }, "SFTP Connection"), this.show_login_screen_username &&
375
- h("div", { key: '13f5053dbf65445220551f554df5ab03fb7fb7c0' }, h("label", { key: '5016afe8eb38c54800697fbe2d4602269966edc9', htmlFor: "username" }, "Username"), h("input", { key: '48e7e3029b0369e06f5d1bafcf4bc9bc3fccfb1a', id: "username", autoComplete: 'off', name: "username", type: "text", placeholder: "" })), this.show_login_screen_password &&
376
- h("div", { key: 'cd06fc73813094a57899c3be077f3dba0a5ca133' }, h("label", { key: 'f64e3145d4df56d4654dedb0188c2a33db09634b', htmlFor: "password" }, "Password"), h("input", { key: '6e22d7cfbf40b8d2e77a23730d55df2e900d5da7', id: "password", autoComplete: 'off', name: "password", type: "password", placeholder: "" })), h("div", { key: '9405dbf23cb588db9b2368c3155a9230ab046438' }, h("button", { key: 'b8087e7b9a828db3d6b36f8fe06d564c76d01402', type: "submit" }, "Connect"))))));
494
+ } }, h("div", { key: 'f8f811323c0aaa9d2c6e7c70b39e2bc58073f500', class: "title" }, "SFTP Connection"), this.show_login_screen_username &&
495
+ h("div", { key: '9d37d47a0c3d7235711964979389e34e7ae909e4' }, h("label", { key: '870aefcf5b1052663df6564158f85f0a1a6c14fc', htmlFor: "username" }, "Username"), h("input", { key: 'b51ee3b3f4a73c7116ace5d1d111d76e6c2d44a2', id: "username", autoComplete: 'off', name: "username", type: "text", placeholder: "" })), this.show_login_screen_password &&
496
+ h("div", { key: 'f727237549f83c27639f943414665eab507d3e0b' }, h("label", { key: 'e0607fbaa128a26ca8a6ce2be5976c2be66cf1a8', htmlFor: "password" }, "Password"), h("input", { key: '4458ad7c4927bf21e27c9b979c14d5d3ca377514', id: "password", autoComplete: 'off', name: "password", type: "password", placeholder: "" })), h("div", { key: '7e3a5f468cc73a370558d4f447e1e7e91ea9dff2' }, h("button", { key: 'c63922f8ffd4377a13c76f51108e8fc9cfa7cdfa', type: "submit" }, "Connect")))), this.show_upload_modal &&
497
+ h("section", { key: 'b7935f9ab9e2cbfc8ecb66aff2c212e8f008675f', class: {
498
+ 'upload-modal': true,
499
+ 'visible': this.show_upload_modal,
500
+ } }, h("div", { key: 'e7c84c44c5ccec4d7211dd647abee21ba9e4dded', class: "upload-dialog", role: "dialog", "aria-modal": "true", "aria-label": "Upload progress" }, h("div", { key: '42411ccf81daad3d6f94455ec5f39a2ec8bd32ce', class: "title" }, "Uploading File"), h("div", { key: 'd7e6db3d7af27e69533bf2bcc532ab36de241a84', class: "file-name", title: this.upload_file_name }, this.upload_file_name), h("div", { key: '3b1e1eb29e1d9b737bf52c3e9d59c33871d661fc', class: "progress-track", role: "progressbar", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": this.upload_progress }, h("div", { key: '36d23d0a85747aa12f36b05caa4fa047095245b9', class: "progress-fill", style: { width: `${this.upload_progress}%` } })), h("div", { key: 'd981d282d1ad7216eee6a6ea8eaf0b48655d6b00', class: "progress-value" }, this.upload_progress, "%"), h("button", { key: '1e5eb505505098bc88fadad649da78e4f291e8c3', type: "button", class: {
501
+ 'cancel': true,
502
+ 'finished': this.upload_finished,
503
+ }, onClick: () => this.cancel_upload() }, this.upload_finished ? 'Close' : 'Cancel'))), this.show_download_modal &&
504
+ h("section", { key: 'f2d75e7719e5a5ecad1dc37145da05cedefc53eb', class: {
505
+ 'download-modal': true,
506
+ 'visible': this.show_download_modal,
507
+ } }, h("div", { key: '248a10deae9f5869290a362d2ec0dc49480c2f6a', class: "download-dialog", role: "dialog", "aria-modal": "true", "aria-label": "Download progress" }, h("div", { key: '05f2f39b31a59ecb402c8b803b9ba8819d9b41d3', class: "title" }, "Downloading File"), h("div", { key: '9979cfdbd9f0ac1888fbce3050ea51f1ac7fbc13', class: "file-name", title: this.download_file_name }, this.download_file_name), h("div", { key: '5a0edbdb962e730fb8b4ff6ed06d1826e84d6ee4', class: "progress-track", role: "progressbar", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": this.download_progress }, h("div", { key: 'fdb25a6a1a42cb82050b4d6e4da4cae52c09ecc1', class: "progress-fill", style: { width: `${this.download_progress}%` } })), h("div", { key: '2b9d47914221aa0537c0317b87cebedeb5c99b57', class: "progress-value" }, this.download_progress, "%"), h("button", { key: '15dee8510d3468eb00131248d7c2e6d31349b650', type: "button", class: {
508
+ 'cancel': true,
509
+ 'finished': this.download_finished,
510
+ }, onClick: () => this.cancel_download() }, this.download_finished ? 'Close' : 'Cancel'))), this.show_delete_modal &&
511
+ h("section", { key: '5b5fd8c394811a4f5a2c285b331ed0a989729fea', class: {
512
+ 'delete-modal': true,
513
+ 'visible': this.show_delete_modal,
514
+ } }, h("div", { key: 'db2010aa154ececde47f5a5b4c3da485db786b0e', class: "delete-dialog", role: "dialog", "aria-modal": "true", "aria-label": "Delete confirmation" }, h("div", { key: '2fdb21392ad194cf7b72bb07391d6fc469b72cea', class: "title" }, "Delete File"), h("div", { key: '28ea5040b1111a888d230fd9aa6c34ada0003132', class: "message" }, this.delete_loading ? 'Deleting file...' : 'Are you sure you want to delete this file?'), h("div", { key: '123138ed8bf191e0dd4d1d9ab0409a15caa2aec2', class: "file-name", title: this.delete_file_name }, this.delete_file_name), this.delete_loading && h("div", { key: '7a30da76db24c7ecb56877ab055fca6f84ba995b', class: "delete-loading-bar", "aria-hidden": "true" }), h("div", { key: 'c6eda63ce75896cc6540f509c81e895b3317e197', class: "modal-actions" }, h("button", { key: '54e7f01e6858f1ac0a73091ed7a6a3666bfad968', type: "button", class: "btn secondary", onClick: () => this.cancel_delete(), disabled: this.delete_loading }, "Cancel"), h("button", { key: 'f647a2772cb3a14cb42fc6d654c5068bf9e3f7f1', type: "button", class: "btn destructive", onClick: () => this.confirm_delete(), disabled: this.delete_loading }, this.delete_loading ? 'Deleting...' : 'Delete'))))));
377
515
  }
378
516
  static get is() { return "phirepass-sftp-client"; }
379
517
  static get encapsulation() { return "shadow"; }
@@ -604,7 +742,18 @@ export class PhirepassSftpClient {
604
742
  "show_loader": {},
605
743
  "version": {},
606
744
  "status": {},
607
- "selected_item": {}
745
+ "selected_item": {},
746
+ "show_upload_modal": {},
747
+ "upload_progress": {},
748
+ "upload_file_name": {},
749
+ "upload_finished": {},
750
+ "show_download_modal": {},
751
+ "download_progress": {},
752
+ "download_file_name": {},
753
+ "download_finished": {},
754
+ "show_delete_modal": {},
755
+ "delete_file_name": {},
756
+ "delete_loading": {}
608
757
  };
609
758
  }
610
759
  static get events() {
@@ -482,7 +482,7 @@ export class PhirepassTerminal {
482
482
  this.usernameBuffer = "";
483
483
  }
484
484
  render() {
485
- return (h(Host, { key: '13831d1794d5739dcd61460571dbdd86eb3b7368' }, h("div", { key: '1a68fbc0c601df5525e278627567fa1c62c59992', id: "ccc", ref: el => (this.containerEl = el) })));
485
+ return (h(Host, { key: '0df9307a490dc566e41be1e1d169f8862f8569b9' }, h("div", { key: 'c63a16718ef4a559b880c6058bf482db4aeb6af1', id: "ccc", ref: el => (this.containerEl = el) })));
486
486
  }
487
487
  static get is() { return "phirepass-terminal"; }
488
488
  static get encapsulation() { return "shadow"; }