@hostlink/nuxt-light 1.60.4 → 1.60.6

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.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "light",
3
3
  "configKey": "light",
4
- "version": "1.60.4",
4
+ "version": "1.60.6",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -41,17 +41,19 @@ const LABLES = [
41
41
  </script>
42
42
 
43
43
  <template>
44
- <q-item-label header>
45
- {{ $t('Labels') }}
46
- </q-item-label>
44
+ <q-list>
45
+ <q-item-label header>
46
+ {{ $t('Labels') }}
47
+ </q-item-label>
47
48
 
48
- <q-item v-for="label in LABLES" :key="label.type" clickable :active="modelValue == label.type"
49
- :active-class="`text-primary`" @click="toggleLabel(label.type)">
50
- <q-item-section avatar>
51
- <q-icon :name="label.icon" />
52
- </q-item-section>
53
- <q-item-section> {{ $t(label.label) }} </q-item-section>
54
- </q-item>
49
+ <q-item v-for="label in LABLES" :key="label.type" clickable :active="modelValue == label.type"
50
+ :active-class="`text-primary`" @click="toggleLabel(label.type)">
51
+ <q-item-section avatar>
52
+ <q-icon :name="label.icon" />
53
+ </q-item-section>
54
+ <q-item-section> {{ $t(label.label) }} </q-item-section>
55
+ </q-item>
56
+ </q-list>
55
57
  </template>
56
58
 
57
59
  <style scoped>
@@ -26,7 +26,12 @@ const file = await api.drive(props.driveIndex).files.get(props.path, {
26
26
  });
27
27
  const size = humanStorageSize(file.size);
28
28
  const copyToClipboard = (text) => {
29
- navigator.clipboard.writeText(text).then(() => {
29
+ let urlToCopy = text;
30
+ if (!text.startsWith("https://") && !text.startsWith("http://")) {
31
+ const baseUrl = window.location.origin;
32
+ urlToCopy = baseUrl + (text.startsWith("/") ? text : "/" + text);
33
+ }
34
+ navigator.clipboard.writeText(urlToCopy).then(() => {
30
35
  quasar.notify({
31
36
  message: "URL copied to clipboard",
32
37
  color: "positive",
@@ -37,16 +42,18 @@ const copyToClipboard = (text) => {
37
42
  console.error("Could not copy text: ", err);
38
43
  });
39
44
  };
40
- const canPreview = computed(() => {
41
- const mime = ["image/jpeg", "image/png", "image/gif"];
42
- return mime.includes(file.mime);
45
+ const isImage = computed(() => {
46
+ return file.mime.startsWith("image/");
47
+ });
48
+ const isVideo = computed(() => {
49
+ return file.mime.startsWith("video/");
43
50
  });
44
51
  </script>
45
52
 
46
53
  <template>
47
- <template v-if="canPreview">
48
- <q-img :src="file.url"></q-img>
49
- </template>
54
+ <q-img :src="file.url" v-if="isImage"></q-img>
55
+ <q-video :src="file.url" v-else-if="isVideo"></q-video>
56
+
50
57
  <q-list dense>
51
58
  <l-item label="Name">{{ file.name }}</l-item>
52
59
  <l-item label="Size">{{ size }} ({{ file.size }})</l-item>
@@ -61,8 +68,8 @@ const canPreview = computed(() => {
61
68
  <q-item-label lines="1">{{ file.url }}</q-item-label>
62
69
  </q-item-section>
63
70
 
64
- <q-item-section top side>
65
- <q-btn size="md" flat danse round icon="sym_o_content_copy" @click="copyToClipboard(file.url)"></q-btn>
71
+ <q-item-section side>
72
+ <q-btn size="md" flat dense round icon="sym_o_content_copy" @click="copyToClipboard(file.url)"></q-btn>
66
73
  </q-item-section>
67
74
  </q-item>
68
75
  </q-list>
@@ -357,22 +357,7 @@ const submitSearch = (e) => {
357
357
  loadItems();
358
358
  };
359
359
  const onDownloadRow = async (row) => {
360
- const app = await q({
361
- app: {
362
- drive: {
363
- __args: {
364
- index: row.driveIndex
365
- },
366
- file: {
367
- __args: {
368
- path: row.path
369
- },
370
- base64Content: true
371
- }
372
- }
373
- }
374
- });
375
- const base64Content = app.app.drive.file.base64Content;
360
+ const base64Content = await getDrive(row.driveIndex).files.readFileAsBase64(row.path);
376
361
  const downloadLink = document.createElement("a");
377
362
  downloadLink.href = `data:application/octet-stream;base64,${base64Content}`;
378
363
  downloadLink.download = row.name;
@@ -456,8 +441,10 @@ watch(selectedNodePath, async () => {
456
441
  await loadItems();
457
442
  });
458
443
  const canPreview = (file) => {
459
- const mime = ["image/jpeg", "image/png", "image/gif"];
460
- return mime.includes(file.mime);
444
+ if (!file.mime) {
445
+ return false;
446
+ }
447
+ return file.mime.startsWith("image/");
461
448
  };
462
449
  const onCheckTotalSize = async (folder) => {
463
450
  const d = $q.dialog({
@@ -479,19 +466,89 @@ const onCheckTotalSize = async (folder) => {
479
466
  }
480
467
  }
481
468
  });
469
+ const size = humanStorageSize(resp.app.drive.folder.totalSize);
482
470
  d.update({
483
- message: humanStorageSize(resp.app.drive.folder.totalSize),
471
+ message: "Total size of folder '" + folder.name + "' is " + size,
484
472
  progress: false
485
473
  });
486
474
  };
487
- selectedNodePath.value = drives[0].index.toString();
475
+ const onDuplicateFile = async (file) => {
476
+ try {
477
+ const newPath = await m("lightDriveDuplicateFile", {
478
+ index: file.driveIndex,
479
+ path: file.path
480
+ });
481
+ $q.notify({
482
+ type: "positive",
483
+ message: "File duplicated to " + newPath
484
+ });
485
+ } catch (e) {
486
+ $q.dialog({
487
+ title: "Error",
488
+ message: e.message
489
+ });
490
+ return;
491
+ }
492
+ await loadItems();
493
+ };
494
+ const onDrop = (event) => {
495
+ event.preventDefault();
496
+ event.stopPropagation();
497
+ if (selectedNodePath.value == null) {
498
+ $q.notify({
499
+ type: "warning",
500
+ message: "Please select a folder to upload files."
501
+ });
502
+ return;
503
+ }
504
+ const files2 = event.dataTransfer.files;
505
+ console.log("Dropped files:", files2);
506
+ uploadFiles.value = [];
507
+ for (let i = 0; i < files2.length; i++) {
508
+ uploadFiles.value.push(files2[i]);
509
+ }
510
+ showUploadFiles.value = true;
511
+ dragzone.value.style.border = "none";
512
+ };
513
+ const dragzone = ref(null);
514
+ const onDragover = (event) => {
515
+ event.preventDefault();
516
+ event.stopPropagation();
517
+ if (selectedNodePath.value == null) {
518
+ return;
519
+ }
520
+ dragzone.value.style.border = "2px dashed #1976d2";
521
+ };
522
+ const onDragLeave = (event) => {
523
+ event.preventDefault();
524
+ event.stopPropagation();
525
+ if (selectedNodePath.value == null) {
526
+ return;
527
+ }
528
+ dragzone.value.style.border = "none";
529
+ };
530
+ const getFileIcon = (file) => {
531
+ if (file.mime.startsWith("image/")) {
532
+ return "sym_o_image";
533
+ } else if (file.mime === "application/pdf") {
534
+ return "sym_o_picture_as_pdf";
535
+ } else if (file.mime.startsWith("video/")) {
536
+ return "sym_o_videocam";
537
+ } else if (file.mime.startsWith("audio/")) {
538
+ return "sym_o_audiotrack";
539
+ } else if (file.mime === "application/zip" || file.mime === "application/x-rar-compressed") {
540
+ return "sym_o_archive";
541
+ } else {
542
+ return "sym_o_description";
543
+ }
544
+ };
488
545
  </script>
489
546
 
490
547
  <template>
491
548
  <q-layout view="hHh lpR fFf" :class="isDark ? '' : 'bg-white'" container :style="{ 'min-height': height }">
492
549
  <q-header bordered :class="isDark ? '' : 'bg-white text-grey-8'" height-hint="64">
493
550
  <q-toolbar>
494
- <q-btn flat round @click="toggleLeftDrawer" aria-label="Menu" icon="menu" class="q-mr-sm" />
551
+ <q-btn flat round @click="toggleLeftDrawer" aria-label="Menu" icon="sym_o_menu" class="q-mr-sm" />
495
552
 
496
553
  <q-toolbar-title v-if="$q.screen.gt.xs" shrink class="row items-center no-wrap">
497
554
  <span class="q-ml-sm">{{ $t('File Manager') }}</span>
@@ -555,180 +612,195 @@ selectedNodePath.value = drives[0].index.toString();
555
612
  </q-drawer>
556
613
 
557
614
  <q-page-container :style="{ height }">
615
+ <div @drop="onDrop" @dragover="onDragover" ref="dragzone" @dragleave="onDragLeave" style="height: 100%;">
558
616
 
559
- <q-dialog v-model="showPreviewImgDialog" full-width full-height auto-close>
560
- <q-card>
561
- <q-card-section>
562
- <q-img :src="previewImg"></q-img>
563
- </q-card-section>
564
- </q-card>
565
- </q-dialog>
566
-
567
- <q-dialog v-model="showUploadFiles" persistent transition-show="scale" transition-hide="scale">
568
- <l-card style="width:300px">
569
- <q-card-section>
570
- <q-file ref="file" v-model="uploadFiles" multiple name="file" label="Files" :color="light.color"></q-file>
571
- </q-card-section>
572
-
573
- <q-card-actions align="right">
574
- <q-btn flat :label="$t('Cancel')" :color="light.color" v-close-popup></q-btn>
575
- <q-btn flat :label="$t('Upload')" :color="light.color" @click="onUploadFiles"></q-btn>
576
- </q-card-actions>
577
- </l-card>
578
- </q-dialog>
617
+ <q-dialog v-model="showPreviewImgDialog" full-width full-height auto-close>
618
+ <q-card>
619
+ <q-card-section>
620
+ <q-img :src="previewImg"></q-img>
621
+ </q-card-section>
622
+ </q-card>
623
+ </q-dialog>
579
624
 
580
- <q-toolbar>
581
- <q-breadcrumbs>
582
- <q-breadcrumbs-el v-for="(b, index) in breadcrumbs" :label="b.label" :key="index"
583
- @click="selectedNodePath = b.path" href="javascript:void(0)"></q-breadcrumbs-el>
584
- </q-breadcrumbs>
585
- <q-space></q-space>
625
+ <q-dialog v-model="showUploadFiles" persistent transition-show="scale" transition-hide="scale">
626
+ <q-card style="min-width: 400px;">
627
+ <q-toolbar>
628
+ <q-toolbar-title>{{ $t('Upload Files') }}</q-toolbar-title>
629
+ <q-space></q-space>
630
+ <q-btn flat round dense icon="sym_o_close" v-close-popup></q-btn>
631
+ </q-toolbar>
632
+ <q-card-section>
633
+ <q-file ref="file" v-model="uploadFiles" multiple name="file" label="Files" color="primary"></q-file>
634
+ </q-card-section>
586
635
 
587
- <q-btn flat round icon="sym_o_drive_file_move" v-if="selected.length > 0">
588
- <l-file-manager-move @selected="moveToFolder($event)" :drive-index="selectedDrive" />
589
- <q-tooltip>
590
- {{ $t('Move to') }}
591
- </q-tooltip>
592
- </q-btn>
593
-
594
- <q-btn flat round icon="sym_o_delete" @click="onDeleteSelected" v-if="selected.length > 0">
595
- <q-tooltip>
596
- {{ $t('Delete') }}
597
- </q-tooltip>
598
- </q-btn>
599
- <q-btn flat round :icon="grid ? 'sym_o_view_list' : 'sym_o_grid_view'" @click="grid = !grid">
600
- <q-tooltip>
601
- {{ grid ? $t('List view') : $t('Grid view') }}
602
- </q-tooltip>
603
- </q-btn>
604
- </q-toolbar>
636
+ <q-card-actions align="right">
637
+ <q-btn flat :label="$t('Cancel')" color="primary" v-close-popup></q-btn>
638
+ <q-btn flat :label="$t('Upload')" color="primary" @click="onUploadFiles"></q-btn>
639
+ </q-card-actions>
640
+ </q-card>
641
+ </q-dialog>
605
642
 
606
- <template v-if="grid">
607
- <q-table :title="$t('Folders')" flat grid :columns="columns" :rows="folders" hide-pagination
608
- :pagination="{ rowsPerPage: 0 }">
609
- <template v-slot:item="props">
610
- <div class="q-pa-xs col-xs-12 col-sm-6 col-md-4" @click="onDblclickRow(null, props.row, null)">
611
- <q-card flat bordered>
612
- <q-item>
613
- <q-item-section avatar>
614
- <q-icon name="sym_o_folder" size="sm"></q-icon>
615
- </q-item-section>
616
- <q-item-section>
617
- {{ props.row.name }}
618
- </q-item-section>
619
- <q-item-section avatar>
620
- <q-checkbox v-model="selected" :val="props.row" />
621
- </q-item-section>
622
- </q-item>
623
- </q-card>
624
- </div>
625
- </template>
626
- </q-table>
627
-
628
- <q-table :title="$t('Files')" flat grid :columns="columns" :rows="files" hide-pagination
629
- :pagination="{ rowsPerPage: 0 }">
630
-
631
- <template v-slot:item="props">
632
- <div class="q-pa-xs col-xs-12 col-sm-6 col-md-4" @click="onClickRow(null, props.row, null)">
633
- <q-card flat bordered>
634
- <q-item>
635
- <q-item-section avatar>
636
- <q-icon name="sym_o_description" size="sm"></q-icon>
637
- </q-item-section>
638
- <q-item-section>
639
- <q-item-label lines="1">
643
+ <q-toolbar>
644
+ <q-breadcrumbs>
645
+ <q-breadcrumbs-el v-for="(b, index) in breadcrumbs" :label="b.label" :key="index"
646
+ @click="selectedNodePath = b.path" href="javascript:void(0)"></q-breadcrumbs-el>
647
+ </q-breadcrumbs>
648
+ <q-space></q-space>
649
+
650
+ <q-btn flat round icon="sym_o_drive_file_move" v-if="selected.length > 0">
651
+ <l-file-manager-move @selected="moveToFolder($event)" :drive-index="selectedDrive" />
652
+ <q-tooltip>
653
+ {{ $t('Move to') }}
654
+ </q-tooltip>
655
+ </q-btn>
656
+
657
+ <q-btn flat round icon="sym_o_delete" @click="onDeleteSelected" v-if="selected.length > 0">
658
+ <q-tooltip>
659
+ {{ $t('Delete') }}
660
+ </q-tooltip>
661
+ </q-btn>
662
+ <q-btn flat round :icon="grid ? 'sym_o_view_list' : 'sym_o_grid_view'" @click="grid = !grid">
663
+ <q-tooltip>
664
+ {{ grid ? $t('List view') : $t('Grid view') }}
665
+ </q-tooltip>
666
+ </q-btn>
667
+ </q-toolbar>
668
+
669
+ <template v-if="grid">
670
+ <q-table :title="$t('Folders')" flat grid :columns="columns" :rows="folders" hide-pagination
671
+ :pagination="{ rowsPerPage: 0 }">
672
+ <template v-slot:item="props">
673
+ <div class="q-pa-xs col-xs-12 col-sm-6 col-md-4" @click="onDblclickRow(null, props.row, null)">
674
+ <q-card flat bordered>
675
+ <q-item>
676
+ <q-item-section avatar>
677
+ <q-icon name="sym_o_folder" size="sm"></q-icon>
678
+ </q-item-section>
679
+ <q-item-section>
640
680
  {{ props.row.name }}
641
- </q-item-label>
642
- </q-item-section>
643
- <q-item-section side>
644
- <q-checkbox v-model="selected" :val="props.row" />
645
- </q-item-section>
646
- </q-item>
647
-
648
- <q-img v-if="canPreview(props.row)" :src="props.row.url"></q-img>
649
-
650
- </q-card>
651
- </div>
652
- </template>
653
- </q-table>
654
- </template>
655
- <template v-else>
656
-
657
- <q-table flat :columns="columns" :rows="items" @row-dblclick="onDblclickRow" @row-click="onClickRow"
658
- :pagination="pagination" row-key="path" selection="multiple" v-model:selected="selected" dense
659
- :loading="loading" :loading-label="$t('Loading...')" :no-data-label="$t('No data available')"
660
- separator="horizontal" :rows-per-page-options="[0]" color="primary">
661
- <template #body-cell-icon="props">
662
- <q-td auto-width>
663
- <q-icon name="sym_o_folder" v-if="props.value == 'folder'" size="sm" />
664
- <q-icon name="sym_o_description" v-else size="sm" />
665
- </q-td>
666
- </template>
667
-
668
- <template #body-cell-action="props">
669
- <q-td auto-width>
670
- <q-btn flat icon="sym_o_more_vert" round dense>
671
- <q-menu>
672
- <q-list>
681
+ </q-item-section>
682
+ <q-item-section avatar>
683
+ <q-checkbox v-model="selected" :val="props.row" />
684
+ </q-item-section>
685
+ </q-item>
686
+ </q-card>
687
+ </div>
688
+ </template>
689
+ </q-table>
673
690
 
674
- <q-item clickable v-close-popup="true" @click="onCheckTotalSize(props.row)"
675
- v-if="props.row.type == 'folder'">
676
- <q-item-section avatar>
677
- <q-icon name="sym_o_info"></q-icon>
678
- </q-item-section>
679
- <q-item-section>{{ $t('Total size') }}</q-item-section>
680
- </q-item>
691
+ <q-table :title="$t('Files')" flat grid :columns="columns" :rows="files" hide-pagination
692
+ :pagination="{ rowsPerPage: 0 }">
681
693
 
682
- <q-item clickable v-close-popup @click="onDeleteRow(props.row)" v-if="canDeleteRow(props.row)">
683
- <q-item-section avatar>
684
- <q-icon name="sym_o_delete"></q-icon>
685
- </q-item-section>
686
- <q-item-section>{{ $t('Delete') }}</q-item-section>
687
- </q-item>
694
+ <template v-slot:item="props">
695
+ <div class="q-pa-xs col-xs-12 col-sm-6 col-md-4" @click="onClickRow(null, props.row, null)">
696
+ <q-card flat bordered>
697
+ <q-item>
698
+ <q-item-section avatar>
699
+ <q-icon :name="getFileIcon(props.row)" size="sm"></q-icon>
700
+ </q-item-section>
701
+ <q-item-section>
702
+ <q-item-label lines="1">
703
+ {{ props.row.name }}
704
+ </q-item-label>
705
+ </q-item-section>
706
+ <q-item-section side>
707
+ <q-checkbox v-model="selected" :val="props.row" />
708
+ </q-item-section>
709
+ </q-item>
688
710
 
689
- <q-item v-if="props.row.type == 'file'" clickable v-close-popup @click="onDownloadRow(props.row)">
690
- <q-item-section avatar>
691
- <q-icon name="sym_o_download"></q-icon>
692
- </q-item-section>
693
- <q-item-section>{{ $t('Download') }}</q-item-section>
694
- </q-item>
711
+ <q-img v-if="canPreview(props.row)" :src="props.row.url"></q-img>
695
712
 
696
- <q-item clickable v-close-popup @click="onRenameRow(props.row)" v-if="canRenameRow(props.row)">
697
- <q-item-section avatar>
698
- <q-icon name="sym_o_edit"></q-icon>
699
- </q-item-section>
700
- <q-item-section>{{ $t('Rename') }}</q-item-section>
701
- </q-item>
713
+ </q-card>
714
+ </div>
715
+ </template>
716
+ </q-table>
717
+ </template>
718
+ <template v-else>
702
719
 
703
- <q-item clickable v-close-popup @click="onPreview(props.row)" v-if="props.row.canPreview">
704
- <q-item-section avatar>
705
- <q-icon name="sym_o_preview"></q-icon>
706
- </q-item-section>
707
- <q-item-section>{{ $t('Preview') }}</q-item-section>
708
- </q-item>
720
+ <q-table flat :columns="columns" :rows="items" @row-dblclick="onDblclickRow" @row-click="onClickRow"
721
+ :pagination="pagination" row-key="path" selection="multiple" v-model:selected="selected" dense
722
+ :loading="loading" :loading-label="$t('Loading...')" :no-data-label="$t('No data available')"
723
+ separator="horizontal" :rows-per-page-options="[0]" color="primary">
724
+ <template #body-cell-icon="props">
725
+ <q-td auto-width>
726
+ <q-icon name="sym_o_folder" v-if="props.value == 'folder'" size="sm" />
727
+ <q-icon :name="getFileIcon(props.row)" v-else size="sm" />
728
+ </q-td>
729
+ </template>
709
730
 
710
- <q-item clickable v-close-popup v-if="props.row.mime == 'application/pdf'"
711
- @click="onPreviewPDF(props.row)">
712
- <q-item-section avatar>
713
- <q-icon name="sym_o_preview"></q-icon>
714
- </q-item-section>
715
- <q-item-section>{{ $t('Preview') }}</q-item-section>
716
- </q-item>
731
+ <template #body-cell-action="props">
732
+ <q-td auto-width>
733
+ <q-btn flat icon="sym_o_more_vert" round dense>
734
+ <q-menu>
735
+ <q-list>
717
736
 
718
- <q-item clickable v-close-popup @click="onClickInfo(props.row)" class="lt-lg">
719
- <q-item-section avatar>
720
- <q-icon name="sym_o_info"></q-icon>
721
- </q-item-section>
722
- <q-item-section>{{ $t('Info') }}</q-item-section>
723
- </q-item>
737
+ <q-item clickable v-close-popup="true" @click="onCheckTotalSize(props.row)"
738
+ v-if="props.row.type == 'folder'">
739
+ <q-item-section avatar>
740
+ <q-icon name="sym_o_info"></q-icon>
741
+ </q-item-section>
742
+ <q-item-section>{{ $t('Total size') }}</q-item-section>
743
+ </q-item>
724
744
 
725
- </q-list>
726
- </q-menu>
727
- </q-btn>
728
- </q-td>
729
- </template>
730
- </q-table>
731
- </template>
745
+ <q-item clickable v-close-popup @click="onDeleteRow(props.row)" v-if="canDeleteRow(props.row)">
746
+ <q-item-section avatar>
747
+ <q-icon name="sym_o_delete"></q-icon>
748
+ </q-item-section>
749
+ <q-item-section>{{ $t('Delete') }}</q-item-section>
750
+ </q-item>
751
+
752
+ <q-item v-if="props.row.type == 'file'" clickable v-close-popup @click="onDownloadRow(props.row)">
753
+ <q-item-section avatar>
754
+ <q-icon name="sym_o_download"></q-icon>
755
+ </q-item-section>
756
+ <q-item-section>{{ $t('Download') }}</q-item-section>
757
+ </q-item>
758
+
759
+ <q-item clickable v-close-popup @click="onRenameRow(props.row)" v-if="canRenameRow(props.row)">
760
+ <q-item-section avatar>
761
+ <q-icon name="sym_o_edit"></q-icon>
762
+ </q-item-section>
763
+ <q-item-section>{{ $t('Rename') }}</q-item-section>
764
+ </q-item>
765
+
766
+ <q-item clickable v-close-popup @click="onDuplicateFile(props.row)"
767
+ v-if="props.row.type == 'file'">
768
+ <q-item-section avatar>
769
+ <q-icon name="sym_o_content_copy"></q-icon>
770
+ </q-item-section>
771
+ <q-item-section>{{ $t('Duplicate') }}</q-item-section>
772
+ </q-item>
773
+
774
+ <q-item clickable v-close-popup @click="onPreview(props.row)" v-if="canPreview(props.row)">
775
+ <q-item-section avatar>
776
+ <q-icon name="sym_o_preview"></q-icon>
777
+ </q-item-section>
778
+ <q-item-section>{{ $t('Preview') }}</q-item-section>
779
+ </q-item>
780
+
781
+ <q-item clickable v-close-popup v-if="props.row.mime == 'application/pdf'"
782
+ @click="onPreviewPDF(props.row)">
783
+ <q-item-section avatar>
784
+ <q-icon name="sym_o_preview"></q-icon>
785
+ </q-item-section>
786
+ <q-item-section>{{ $t('Preview') }}</q-item-section>
787
+ </q-item>
788
+
789
+ <q-item clickable v-close-popup @click="onClickInfo(props.row)" class="lt-lg">
790
+ <q-item-section avatar>
791
+ <q-icon name="sym_o_info"></q-icon>
792
+ </q-item-section>
793
+ <q-item-section>{{ $t('Info') }}</q-item-section>
794
+ </q-item>
795
+
796
+ </q-list>
797
+ </q-menu>
798
+ </q-btn>
799
+ </q-td>
800
+ </template>
801
+ </q-table>
802
+ </template>
803
+ </div>
732
804
  </q-page-container>
733
805
  </q-layout>
734
806
  </template>
@@ -2,12 +2,12 @@ export interface LLoginProps {
2
2
  company: string;
3
3
  companyLogo: string;
4
4
  twoFactorAuthentication: boolean;
5
- forgetPasswordEnabled: boolean;
6
5
  passwordBasedEnabled: boolean;
7
6
  googleClientId?: string;
8
7
  microsoftClientId?: string;
9
8
  microsoftTenantId?: string;
10
9
  facebookAppId?: string;
10
+ forgetPasswordEnabled: boolean;
11
11
  }
12
12
  declare const __VLS_export: import("vue").DefineComponent<LLoginProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, any, string, import("vue").PublicProps, any, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
13
  declare const _default: typeof __VLS_export;
@@ -11,12 +11,12 @@ const props = defineProps({
11
11
  company: { type: String, required: true },
12
12
  companyLogo: { type: String, required: true },
13
13
  twoFactorAuthentication: { type: Boolean, required: true },
14
- forgetPasswordEnabled: { type: Boolean, required: true },
15
14
  passwordBasedEnabled: { type: Boolean, required: true },
16
15
  googleClientId: { type: String, required: false },
17
16
  microsoftClientId: { type: String, required: false },
18
17
  microsoftTenantId: { type: String, required: false },
19
- facebookAppId: { type: String, required: false }
18
+ facebookAppId: { type: String, required: false },
19
+ forgetPasswordEnabled: { type: Boolean, required: true }
20
20
  });
21
21
  useHead({
22
22
  title: props.company
@@ -2,12 +2,12 @@ export interface LLoginProps {
2
2
  company: string;
3
3
  companyLogo: string;
4
4
  twoFactorAuthentication: boolean;
5
- forgetPasswordEnabled: boolean;
6
5
  passwordBasedEnabled: boolean;
7
6
  googleClientId?: string;
8
7
  microsoftClientId?: string;
9
8
  microsoftTenantId?: string;
10
9
  facebookAppId?: string;
10
+ forgetPasswordEnabled: boolean;
11
11
  }
12
12
  declare const __VLS_export: import("vue").DefineComponent<LLoginProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, any, string, import("vue").PublicProps, any, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
13
  declare const _default: typeof __VLS_export;
@@ -4,12 +4,12 @@ import { m, q, useAsyncData } from "#imports";
4
4
  import { useQuasar } from "#imports";
5
5
  const $q = useQuasar();
6
6
  const { data: app, refresh } = await useAsyncData(async () => {
7
- return (await q({
7
+ return await q({
8
8
  app: {
9
9
  driveTypes: true,
10
10
  listFileSystem: true
11
11
  }
12
- })).app;
12
+ }).then((res) => res.app);
13
13
  });
14
14
  const items = computed(() => app.value.listFileSystem);
15
15
  const dialog = ref(false);
@@ -115,8 +115,8 @@ const loading = ref(false);
115
115
 
116
116
  <form-kit type="group" name="data">
117
117
  <form-kit type="l-input" label="Url" name="url"
118
- hint="URL is used to generate the full URL of the file.">
119
- </form-kit>
118
+ hint="URL is used to generate the full URL of the file."
119
+ placeholder="https://example.com/api/"></form-kit>
120
120
 
121
121
  <template v-if="value.type == 'local'">
122
122
  <form-kit type="l-input" label="Location" name="location" validation="required"
@@ -170,6 +170,9 @@ const loading = ref(false);
170
170
  }; dialog = true" flat round dense>
171
171
  <q-tooltip>Add File System</q-tooltip>
172
172
  </q-btn>
173
+ </template>
174
+
175
+ <template #top-selection>
173
176
  <q-btn icon="sym_o_delete" @click="onRemove(selected)" flat round dense :disable="selected.length == 0">
174
177
  <q-tooltip>Remove File System</q-tooltip>
175
178
  </q-btn>
@@ -6,7 +6,11 @@ import { useQuasar } from "quasar";
6
6
  import { computed } from "vue";
7
7
  const quasar = useQuasar();
8
8
  const { t } = useI18n();
9
- const system = await q("system", ["passwordPolicy"]);
9
+ const { system } = await q({
10
+ system: {
11
+ passwordPolicy: true
12
+ }
13
+ });
10
14
  const router = useRouter();
11
15
  const route = useRoute();
12
16
  const id = route.params.user_id;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostlink/nuxt-light",
3
- "version": "1.60.4",
3
+ "version": "1.60.6",
4
4
  "description": "HostLink Nuxt Light Framework",
5
5
  "repository": {
6
6
  "type": "git",
@@ -53,6 +53,7 @@
53
53
  "@nuxt/kit": "^4.2.2",
54
54
  "@nuxt/schema": "^4.2.2",
55
55
  "@nuxt/test-utils": "^3.17.2",
56
+ "@types/google.accounts": "^0.0.18",
56
57
  "@types/node": "^24.10.1",
57
58
  "changelogen": "^0.5.7",
58
59
  "eslint": "^9.39.1",