@hostlink/nuxt-light 0.0.3

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 (111) hide show
  1. package/README.md +106 -0
  2. package/dist/module.cjs +5 -0
  3. package/dist/module.d.ts +7 -0
  4. package/dist/module.json +5 -0
  5. package/dist/module.mjs +51 -0
  6. package/dist/runtime/assets/element.css +15925 -0
  7. package/dist/runtime/assets/element.css.map +1 -0
  8. package/dist/runtime/assets/main.css +13 -0
  9. package/dist/runtime/components/l-add-btn.vue +22 -0
  10. package/dist/runtime/components/l-app-main.vue +214 -0
  11. package/dist/runtime/components/l-app.vue +17 -0
  12. package/dist/runtime/components/l-back-btn.vue +7 -0
  13. package/dist/runtime/components/l-btn.vue +19 -0
  14. package/dist/runtime/components/l-card.vue +19 -0
  15. package/dist/runtime/components/l-checkbox.vue +6 -0
  16. package/dist/runtime/components/l-col.vue +14 -0
  17. package/dist/runtime/components/l-customizer.vue +102 -0
  18. package/dist/runtime/components/l-date-picker.vue +78 -0
  19. package/dist/runtime/components/l-delete-btn.vue +23 -0
  20. package/dist/runtime/components/l-edit-btn.vue +3 -0
  21. package/dist/runtime/components/l-file-manager-labels.vue +55 -0
  22. package/dist/runtime/components/l-file-manager-move.vue +185 -0
  23. package/dist/runtime/components/l-file-manager-preview.vue +59 -0
  24. package/dist/runtime/components/l-file-manager.vue +618 -0
  25. package/dist/runtime/components/l-file.vue +33 -0
  26. package/dist/runtime/components/l-form.vue +73 -0
  27. package/dist/runtime/components/l-input.vue +48 -0
  28. package/dist/runtime/components/l-item.vue +14 -0
  29. package/dist/runtime/components/l-link.vue +24 -0
  30. package/dist/runtime/components/l-list.vue +5 -0
  31. package/dist/runtime/components/l-login.vue +128 -0
  32. package/dist/runtime/components/l-menu.vue +37 -0
  33. package/dist/runtime/components/l-page.vue +94 -0
  34. package/dist/runtime/components/l-row.vue +5 -0
  35. package/dist/runtime/components/l-save-btn.vue +3 -0
  36. package/dist/runtime/components/l-select.vue +77 -0
  37. package/dist/runtime/components/l-table.vue +333 -0
  38. package/dist/runtime/components/l-tabs.vue +5 -0
  39. package/dist/runtime/components/l-time-picker.vue +28 -0
  40. package/dist/runtime/components/l-view-btn.vue +3 -0
  41. package/dist/runtime/composables/addObject.d.ts +2 -0
  42. package/dist/runtime/composables/addObject.mjs +6 -0
  43. package/dist/runtime/composables/f.d.ts +1 -0
  44. package/dist/runtime/composables/f.mjs +27 -0
  45. package/dist/runtime/composables/getApiUrl.d.ts +1 -0
  46. package/dist/runtime/composables/getApiUrl.mjs +4 -0
  47. package/dist/runtime/composables/getCurrentUser.d.ts +2 -0
  48. package/dist/runtime/composables/getCurrentUser.mjs +8 -0
  49. package/dist/runtime/composables/getObject.d.ts +1 -0
  50. package/dist/runtime/composables/getObject.mjs +20 -0
  51. package/dist/runtime/composables/id.d.ts +2 -0
  52. package/dist/runtime/composables/id.mjs +12 -0
  53. package/dist/runtime/composables/list.d.ts +1 -0
  54. package/dist/runtime/composables/list.mjs +33 -0
  55. package/dist/runtime/composables/listData.d.ts +1 -0
  56. package/dist/runtime/composables/listData.mjs +30 -0
  57. package/dist/runtime/composables/login.d.ts +2 -0
  58. package/dist/runtime/composables/login.mjs +17 -0
  59. package/dist/runtime/composables/m.d.ts +1 -0
  60. package/dist/runtime/composables/m.mjs +73 -0
  61. package/dist/runtime/composables/mutation.d.ts +1 -0
  62. package/dist/runtime/composables/mutation.mjs +23 -0
  63. package/dist/runtime/composables/q.d.ts +1 -0
  64. package/dist/runtime/composables/q.mjs +18 -0
  65. package/dist/runtime/composables/removeObject.d.ts +1 -0
  66. package/dist/runtime/composables/removeObject.mjs +15 -0
  67. package/dist/runtime/composables/t.d.ts +1 -0
  68. package/dist/runtime/composables/t.mjs +8 -0
  69. package/dist/runtime/composables/updateObject.d.ts +2 -0
  70. package/dist/runtime/composables/updateObject.mjs +10 -0
  71. package/dist/runtime/composables/useLight.d.ts +7 -0
  72. package/dist/runtime/composables/useLight.mjs +17 -0
  73. package/dist/runtime/composables/viewAs.d.ts +1 -0
  74. package/dist/runtime/composables/viewAs.mjs +15 -0
  75. package/dist/runtime/locales/en.json +14 -0
  76. package/dist/runtime/locales/zh-hk.json +140 -0
  77. package/dist/runtime/pages/EventLog/_eventlog_id/view.vue +21 -0
  78. package/dist/runtime/pages/EventLog/index.vue +56 -0
  79. package/dist/runtime/pages/FileManager/index.vue +5 -0
  80. package/dist/runtime/pages/MailLog/index.vue +48 -0
  81. package/dist/runtime/pages/Permission/add.vue +47 -0
  82. package/dist/runtime/pages/Permission/all.vue +85 -0
  83. package/dist/runtime/pages/Permission/index.vue +26 -0
  84. package/dist/runtime/pages/Role/add.vue +28 -0
  85. package/dist/runtime/pages/Role/index.vue +51 -0
  86. package/dist/runtime/pages/System/database/backup.vue +5 -0
  87. package/dist/runtime/pages/System/database/table.vue +19 -0
  88. package/dist/runtime/pages/System/index.vue +8 -0
  89. package/dist/runtime/pages/System/mailtest.vue +22 -0
  90. package/dist/runtime/pages/System/package.vue +8 -0
  91. package/dist/runtime/pages/System/phpinfo.vue +8 -0
  92. package/dist/runtime/pages/System/setting.vue +68 -0
  93. package/dist/runtime/pages/System/view_as.vue +56 -0
  94. package/dist/runtime/pages/User/_user_id/change-password.vue +49 -0
  95. package/dist/runtime/pages/User/_user_id/edit.vue +49 -0
  96. package/dist/runtime/pages/User/_user_id/view.vue +21 -0
  97. package/dist/runtime/pages/User/add.vue +64 -0
  98. package/dist/runtime/pages/User/index.vue +47 -0
  99. package/dist/runtime/pages/User/profile.vue +25 -0
  100. package/dist/runtime/pages/User/update-password.vue +45 -0
  101. package/dist/runtime/pages/UserLog/index.vue +53 -0
  102. package/dist/runtime/pages/index.vue +9 -0
  103. package/dist/runtime/pages/logout.vue +10 -0
  104. package/dist/runtime/plugin.d.ts +4 -0
  105. package/dist/runtime/plugin.mjs +58 -0
  106. package/dist/runtime/routes.d.ts +7 -0
  107. package/dist/runtime/routes.mjs +261 -0
  108. package/dist/runtime/system_menus.d.ts +10 -0
  109. package/dist/runtime/system_menus.mjs +37 -0
  110. package/dist/types.d.ts +15 -0
  111. package/package.json +57 -0
@@ -0,0 +1,618 @@
1
+ <script setup>
2
+ import { VariableType } from "json-to-graphql-query";
3
+ import { useI18n } from "vue-i18n";
4
+ const quasar = useQuasar();
5
+
6
+ const emit = defineEmits(["input", "close"]);
7
+
8
+ defineProps({
9
+ closable: Boolean,
10
+ height: {
11
+ type: String,
12
+ default: "700px",
13
+ },
14
+ defaultAction: {
15
+ default: "preview",
16
+ type: String,
17
+ },
18
+ multiple: {
19
+ default: false,
20
+ type: Boolean,
21
+ },
22
+ });
23
+
24
+ const loading = ref(false);
25
+ const folderTree = ref(null);
26
+
27
+ let i18n = useI18n();
28
+ const pagination = {
29
+ rowsPerPage: 0,
30
+ "rows-per-page-options": [0],
31
+ };
32
+
33
+ const columns = ref([
34
+ {
35
+ name: "icon",
36
+ label: "",
37
+ field: "type",
38
+ },
39
+ {
40
+ name: "name",
41
+ label: i18n.t("Name"),
42
+ field: "name",
43
+ sortable: true,
44
+ align: "left",
45
+ },
46
+ {
47
+ name: "last_modified",
48
+ label: i18n.t("Last Modified"),
49
+ field: "last_modified_human",
50
+ align: "left",
51
+ },
52
+ {
53
+ name: "size_display",
54
+ label: i18n.t("Size"),
55
+ field: "size",
56
+ align: "left",
57
+ },
58
+ { name: "action" },
59
+ ]);
60
+
61
+ const localSearch = ref(null);
62
+
63
+ const leftDrawerOpen = ref(false);
64
+ const showDateOptions = ref(false);
65
+ const exactPhrase = ref("");
66
+ const hasWords = ref("");
67
+ const excludeWords = ref("");
68
+ const byWebsite = ref("");
69
+ const byDate = ref("Any time");
70
+
71
+ function onClear() {
72
+ exactPhrase.value = "";
73
+ hasWords.value = "";
74
+ excludeWords.value = "";
75
+ byWebsite.value = "";
76
+ byDate.value = "Any time";
77
+ }
78
+
79
+ function changeDate(option) {
80
+ byDate.value = option;
81
+ showDateOptions.value = false;
82
+ }
83
+
84
+ function toggleLeftDrawer() {
85
+ leftDrawerOpen.value = !leftDrawerOpen.value;
86
+ }
87
+
88
+ const path = ref("");
89
+
90
+ const onLazyLoad = async ({ node, key, done, fail }) => {
91
+ const data = await q("fsListFolders", { path: node.path }, ["name", "path"]);
92
+ data.map((item) => {
93
+ item.lazy = true;
94
+ return item;
95
+ });
96
+ done(data);
97
+ }
98
+
99
+ const items = ref([]);
100
+
101
+ const loadItems = async () => {
102
+ loading.value = true;
103
+ items.value = [];
104
+
105
+ let filesParams = { path: path.value };
106
+
107
+ if (label.value) {
108
+ filesParams.type = label.value;
109
+ }
110
+
111
+ if (localSearch.value) {
112
+ filesParams.search = localSearch.value;
113
+ }
114
+
115
+ let files = await q("fsListFiles", filesParams, ["name", "size", "mime", "path"]);
116
+ files = files.map((item) => {
117
+ item.type = "file";
118
+ return item;
119
+ });
120
+
121
+ let folders = [];
122
+ if (!label.value && !localSearch.value) {
123
+ folders = await q("fsListFolders", { path: path.value }, ["name", "path"]);
124
+ folders = folders.map((item) => {
125
+ item.type = "folder";
126
+ item.lazy = true;
127
+ return item;
128
+ });
129
+ }
130
+ items.value = folders.concat(files);
131
+
132
+ loading.value = false;
133
+
134
+
135
+
136
+ return {
137
+ files,
138
+ folders,
139
+ }
140
+ }
141
+
142
+ watch(path, async (val) => {
143
+ selected.value = [];
144
+ const items = await loadItems();
145
+ reloadTreeFolder(path.value, items.folders);
146
+
147
+ });
148
+
149
+ const label = ref(null);
150
+
151
+ const initItems = await loadItems();
152
+ const folders = ref(initItems.folders);
153
+
154
+
155
+
156
+ watch(label, () => {
157
+ loadItems();
158
+ })
159
+
160
+ const selected = ref([]);
161
+
162
+ const breadcrumbs = computed(() => {
163
+ let breadcrumbs = [];
164
+
165
+ if (path.value.toString() == "") {
166
+ return [];
167
+ }
168
+
169
+ let paths = path.value.split("/");
170
+
171
+ let ps = [];
172
+ for (let p of paths) {
173
+ if (p) {
174
+ ps.push(p);
175
+ breadcrumbs.push({
176
+ label: p,
177
+ path: "/" + ps.join("/"),
178
+ });
179
+ }
180
+ }
181
+
182
+ return breadcrumbs;
183
+ });
184
+
185
+ const onClickRow = (evt, row, index) => {
186
+ preview.value = row;
187
+ }
188
+
189
+ const grid = ref(false);
190
+
191
+ const onDblclickRow = (evt, row, index) => {
192
+ if (row.type == "folder") {
193
+ path.value = row.path;
194
+ return;
195
+ }
196
+ if (row.type == "file") {
197
+
198
+ emit("input", row.path);
199
+ }
200
+ }
201
+
202
+
203
+ const findFolder = (path, folders) => {
204
+ folders.value.forEach((item) => {
205
+ if (item.path == path) {
206
+ return item;
207
+ }
208
+ //find in children
209
+ let found = findFolder(path, item.children);
210
+ if (found) {
211
+ return found;
212
+ }
213
+ });
214
+ }
215
+
216
+ const reloadTreeFolder = (path, newFolders) => {
217
+
218
+ let node = folderTree.value.getNodeByKey(path);
219
+ if (node) {
220
+ node.lazy = false;
221
+ node.children = newFolders;
222
+ folderTree.value.setExpanded(path, true);
223
+ } else {
224
+
225
+ folders.value = newFolders;
226
+ }
227
+
228
+ }
229
+
230
+ const onDeleteSelected = () => {
231
+ quasar.dialog({
232
+ title: "Delete",
233
+ message: "Are you sure you want to delete this files or folders?",
234
+ cancel: true,
235
+ }).onOk(async () => {
236
+ for (let row of selected.value) {
237
+ if (row.type == "folder") {
238
+ await m("fsDeleteFolder", { path: row.path });
239
+ } else {
240
+ await m("fsDeleteFile", { path: row.path });
241
+ }
242
+ }
243
+ selected.value = [];
244
+ const items = await loadItems();
245
+ reloadTreeFolder(path.value, items.folders);
246
+ });
247
+
248
+ }
249
+
250
+ const onNewFolder = () => {
251
+
252
+ quasar.dialog({
253
+ title: "New Folder",
254
+ prompt: {
255
+ label: "Name",
256
+ },
257
+ cancel: true,
258
+ }).onOk(async (name) => {
259
+ let p = path.value + "/" + name;
260
+ await m("fsCreateFolder", { path: p });
261
+ const items = await loadItems();
262
+ reloadTreeFolder(path.value, items.folders);
263
+ });
264
+ }
265
+
266
+ const onDeleteRow = (row) => {
267
+ if (row.type == "file") {
268
+ quasar.dialog({
269
+ title: "Delete",
270
+ message: "Are you sure you want to delete this file?",
271
+ cancel: true,
272
+ }).onOk(async () => {
273
+ await m("fsDeleteFile", { path: row.path });
274
+ const items = await loadItems();
275
+ reloadTreeFolder(path.value, items.folders);
276
+ });
277
+ } else if (row.type == "folder") {
278
+ quasar.dialog({
279
+ title: "Delete",
280
+ message: "Are you sure you want to delete this folder?",
281
+ cancel: true,
282
+ }).onOk(async () => {
283
+ await m("fsDeleteFolder", { path: row.path });
284
+ const items = await loadItems();
285
+ reloadTreeFolder(path.value, items.folders);
286
+ });
287
+ }
288
+ }
289
+
290
+ const onRenameRow = (row) => {
291
+ quasar.dialog({
292
+ title: "Rename " + row.type,
293
+ prompt: {
294
+ label: "Name",
295
+ model: row.name,
296
+ },
297
+ cancel: true,
298
+ }).onOk(async (name) => {
299
+ try {
300
+ if (row.type == "file") {
301
+ await m("fsRenameFile", { path: row.path, name });
302
+ } else {
303
+ await m("fsRenameFolder", { path: row.path, name });
304
+ }
305
+ } catch (e) {
306
+ quasar.dialog({
307
+ title: "Error",
308
+ message: e.message,
309
+ });
310
+
311
+ return;
312
+ }
313
+
314
+ const items = await loadItems();
315
+ reloadTreeFolder(path.value, items.folders);
316
+
317
+ });
318
+ }
319
+ const uploadFiles = ref([]);
320
+ const showUploadFiles = ref(false);
321
+
322
+
323
+ const onUploadFiles = async () => {
324
+
325
+ quasar.loading.show({
326
+ message: "Uploading files...",
327
+ });
328
+
329
+ for (let file of uploadFiles.value) {
330
+
331
+ await m("fsUploadFile", {
332
+ path: path.value,
333
+ file: new VariableType("file")
334
+ }, [{
335
+ __variables: {
336
+ file: {
337
+ type: "Upload!",
338
+ value: file
339
+ }
340
+ }
341
+ }]);
342
+ }
343
+ uploadFiles.value = [];
344
+
345
+ quasar.loading.hide();
346
+
347
+ showUploadFiles.value = false;
348
+
349
+ const items = await loadItems();
350
+ reloadTreeFolder(path.value, items.folders);
351
+
352
+ }
353
+
354
+ const preview = ref(null);
355
+
356
+ const moveToFolder = async (folder) => {
357
+
358
+ for (let row of selected.value) {
359
+ m("fsMove", { path: row.path, target: folder })
360
+
361
+ }
362
+
363
+ const items = await loadItems();
364
+ reloadTreeFolder(path.value, items.folders);
365
+ }
366
+
367
+ const submitSearch = (e) => {
368
+ localSearch.value = search.value;
369
+ loadItems();
370
+ }
371
+
372
+ /** for grid view */
373
+ const foldersGrid = computed(() => {
374
+ return items.value.filter((item) => {
375
+ return item.type == "folder";
376
+ });
377
+ });
378
+
379
+ const filesGrid = computed(() => {
380
+ return items.value.filter((item) => {
381
+ return item.type == "file";
382
+ });
383
+ });
384
+
385
+
386
+ const onDownloadRow = (row) => {
387
+ // window.open("/api/fs/download?path=" + row.path);
388
+ }
389
+
390
+ const search = ref(null);
391
+
392
+ const reloadStorage = async () => {
393
+ path.value = "";
394
+
395
+ search.value = "";
396
+ localSearch.value = "";
397
+ label.value = null;
398
+ const items = await loadItems();
399
+ reloadTreeFolder(path.value, items.folders);
400
+
401
+ }
402
+ </script>
403
+ <template>
404
+ <q-layout view="hHh lpR fFf" class="bg-white" container :style="{ 'min-height': height }">
405
+ <q-header bordered class="bg-white text-grey-8" height-hint="64">
406
+ <q-toolbar>
407
+ <q-btn flat round @click="toggleLeftDrawer" aria-label="Menu" icon="menu" class="q-mr-sm" />
408
+
409
+ <q-toolbar-title v-if="$q.screen.gt.xs" shrink class="row items-center no-wrap">
410
+ <span class="q-ml-sm">{{ $t('File manager') }}</span>
411
+ </q-toolbar-title>
412
+
413
+ <div>
414
+ <q-input outlined :placeholder="$t('Search for file name')" dense @keyup.enter.native="submitSearch"
415
+ v-model="search">
416
+ <template v-slot:append>
417
+ <q-btn flat dense round icon="sym_o_search"></q-btn>
418
+ </template>
419
+ </q-input>
420
+ </div>
421
+
422
+ <q-space></q-space>
423
+ <q-btn v-if="closable" icon="close" flat round @click="$emit('close')"></q-btn>
424
+ </q-toolbar>
425
+ </q-header>
426
+
427
+ <q-drawer v-model="leftDrawerOpen" show-if-above bordered class="bg-white" :width="257">
428
+ <q-scroll-area class="fit">
429
+ <q-list padding class="text-grey-8">
430
+ <q-item>
431
+ <q-item-section>
432
+ <q-btn icon="add" outline rounded color="primary" :label="$t('New')">
433
+ <q-menu>
434
+ <q-list>
435
+ <q-item clickable v-close-popup @click="onNewFolder">
436
+ <q-item-section avatar>
437
+ <q-icon name="sym_o_create_new_folder"></q-icon>
438
+ </q-item-section>
439
+ <q-item-section>{{ $t('Folder') }}</q-item-section>
440
+ </q-item>
441
+ <q-separator />
442
+ <q-item clickable v-close-popup @click="showUploadFiles = true">
443
+ <q-item-section avatar>
444
+ <q-icon name="sym_o_upload_file"></q-icon>
445
+ </q-item-section>
446
+ <q-item-section>{{ $t('Upload file') }}</q-item-section>
447
+ </q-item>
448
+ </q-list>
449
+ </q-menu>
450
+ </q-btn>
451
+ </q-item-section>
452
+ </q-item>
453
+
454
+ <q-list>
455
+ <q-item>
456
+ <q-item-section avatar>
457
+ <q-icon name="sym_o_storage" />
458
+ </q-item-section>
459
+ <q-item-section>{{ $t('Storage') }}</q-item-section>
460
+ <q-item-section avatar>
461
+ <q-btn dense round flat icon="sym_o_refresh" @click="reloadStorage"></q-btn>
462
+ </q-item-section>
463
+ </q-item>
464
+ <q-item>
465
+ <q-item-section>
466
+ <q-tree ref="folderTree" class="q-pl-md" :nodes="folders" node-key="path" label-key="name"
467
+ @lazy-load="onLazyLoad" v-model:selected="path" no-selection-unset>
468
+ </q-tree>
469
+ </q-item-section>
470
+ </q-item>
471
+ </q-list>
472
+ <!-- q-expansion-item :label="$t('Storage')" default-expand-all default-opened icon="sym_o_storage" selectable
473
+ @click="path = '/'">
474
+ <q-tree ref="folderTree" class="q-pl-md" :nodes="folders" node-key="path" label-key="name"
475
+ @lazy-load="onLazyLoad" v-model:selected="path" no-selection-unset>
476
+ </q-tree>
477
+ </q-expansion-item-->
478
+
479
+ <q-separator inset class="q-my-sm" />
480
+
481
+ <l-file-manager-labels v-model="label" />
482
+ </q-list>
483
+ </q-scroll-area>
484
+ </q-drawer>
485
+
486
+ <q-drawer side="right" show-if-above bordered>
487
+
488
+ <l-file-manager-preview v-model="preview" v-if="preview" :key="preview.path"/>
489
+ </q-drawer>
490
+
491
+ <q-page-container :style="{ height }">
492
+
493
+ <q-dialog v-model="showUploadFiles" persistent transition-show="scale" transition-hide="scale">
494
+ <l-card style="width:300px">
495
+ <q-card-section>
496
+
497
+ <q-file ref="file" v-model="uploadFiles" multiple name="file" label="Files"></q-file>
498
+ </q-card-section>
499
+
500
+ <q-card-actions align="right">
501
+ <q-btn flat label="Cancel" color="primary" v-close-popup></q-btn>
502
+ <q-btn flat label="Upload" color="primary" @click="onUploadFiles"></q-btn>
503
+ </q-card-actions>
504
+ </l-card>
505
+ </q-dialog>
506
+
507
+ <q-toolbar>
508
+ <q-breadcrumbs>
509
+ <q-breadcrumbs-el :label="$t('Storage')" @click="path = ''" href="javascript:void(0)"></q-breadcrumbs-el>
510
+ <q-breadcrumbs-el v-for="(b, index) in breadcrumbs" :label="b.label" :key="index" @click="path = b.path"
511
+ href="javascript:void(0)"></q-breadcrumbs-el>
512
+ </q-breadcrumbs>
513
+ <q-space></q-space>
514
+
515
+
516
+ <q-btn flat round icon="sym_o_drive_file_move" v-if="selected.length > 0">
517
+ <l-file-manager-move @selected="moveToFolder($event)" />
518
+ </q-btn>
519
+
520
+ <q-btn flat round icon="o_delete" @click="onDeleteSelected" v-if="selected.length > 0"></q-btn>
521
+ <q-btn flat round :icon="grid ? 'list_view' : 'grid_view'" @click="grid = !grid"></q-btn>
522
+ </q-toolbar>
523
+
524
+ <template v-if="grid">
525
+ <q-table title="Folders" flat bordered grid :columns="columns" :rows="foldersGrid">
526
+ <template v-slot:item="props">
527
+ <div class="q-pa-xs col-xs-12 col-sm-6 col-md-4">
528
+ <q-card>
529
+ <q-item>
530
+ <q-item-section avatar>
531
+ <q-icon name="sym_o_folder" size="sm"></q-icon>
532
+ </q-item-section>
533
+ <q-item-section>
534
+ {{ props.row.name }}
535
+ </q-item-section>
536
+ <q-item-section avatar>
537
+ <q-checkbox v-model="selected" :val="props.row" />
538
+ </q-item-section>
539
+ </q-item>
540
+ </q-card>
541
+ </div>
542
+ </template>
543
+ </q-table>
544
+
545
+ <q-table title="Files" flat bordered grid :columns="columns" :rows="filesGrid" :pagination="pagination">
546
+
547
+ <template v-slot:item="props">
548
+ <div class="q-pa-xs col-xs-12 col-sm-6 col-md-4">
549
+ <q-card>
550
+ <q-item>
551
+ <q-item-section avatar>
552
+ <q-icon name="sym_o_description" size="sm"></q-icon>
553
+ </q-item-section>
554
+ <q-item-section>
555
+ {{ props.row.name }}
556
+ </q-item-section>
557
+ <q-item-section avatar>
558
+ <q-checkbox v-model="selected" :val="props.row" />
559
+ </q-item-section>
560
+ </q-item>
561
+ </q-card>
562
+ </div>
563
+ </template>
564
+ </q-table>
565
+ </template>
566
+ <template v-else>
567
+
568
+ <q-table flat bordered :columns="columns" :rows="items" @row-dblclick="onDblclickRow" @row-click="onClickRow"
569
+ :pagination="pagination" row-key="path" selection="multiple" v-model:selected="selected" dense
570
+ :loading="loading">
571
+ <template #body-cell-icon="props">
572
+ <q-td auto-width>
573
+ <q-icon name="sym_o_folder" v-if="props.value == 'folder'" size="sm" />
574
+ <q-icon name="sym_o_description" v-else size="sm" />
575
+ </q-td>
576
+ </template>
577
+
578
+ <template #body-cell-action="props">
579
+ <q-td auto-width>
580
+ <q-btn flat icon="sym_o_more_vert" round dense>
581
+ <q-menu>
582
+ <q-list>
583
+ <q-item clickable v-close-popup @click="onDeleteRow(props.row)">
584
+ <q-item-section avatar>
585
+ <q-icon name="sym_o_delete"></q-icon>
586
+ </q-item-section>
587
+ <q-item-section>{{ $t('Delete') }}</q-item-section>
588
+ </q-item>
589
+
590
+ <q-item v-if="props.row.type == 'file'" clickable v-close-popup @click="onDownloadRow(props.row)">
591
+ <q-item-section avatar>
592
+ <q-icon name="sym_o_download"></q-icon>
593
+ </q-item-section>
594
+ <q-item-section>Download</q-item-section>
595
+ </q-item>
596
+
597
+ <q-item clickable v-close-popup @click="onRenameRow(props.row)">
598
+ <q-item-section avatar>
599
+ <q-icon name="sym_o_edit"></q-icon>
600
+ </q-item-section>
601
+ <q-item-section>{{ $t('Rename') }}</q-item-section>
602
+ </q-item>
603
+ </q-list>
604
+ </q-menu>
605
+ </q-btn>
606
+ </q-td>
607
+ </template>
608
+ </q-table>
609
+ </template>
610
+ </q-page-container>
611
+ </q-layout>
612
+ </template>
613
+
614
+ <style>
615
+ .q-item--active {
616
+ background-color: #e0e0e0;
617
+ }
618
+ </style>
@@ -0,0 +1,33 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ modelValue: {
4
+ type: String
5
+ },
6
+ });
7
+
8
+ const emit = defineEmits(["update:modelValue"]);
9
+
10
+ const show = ref(false);
11
+
12
+ const onInput = (value) => {
13
+ localValue.value = value;
14
+ show.value = false;
15
+
16
+ };
17
+
18
+ const localValue = computed({
19
+ get: () => props.modelValue,
20
+ set: (value) => emit("update:modelValue", value),
21
+ })
22
+
23
+ </script>
24
+ <template>
25
+ <q-input v-model="localValue">
26
+ <q-dialog v-model="show" full-height full-width>
27
+ <l-file-manager closable @close="show = false" @input="onInput"></l-file-manager>
28
+ </q-dialog>
29
+ <template v-slot:prepend>
30
+ <q-btn dense flat round icon="sym_o_folder" @click="show = true"></q-btn>
31
+ </template>
32
+ </q-input>
33
+ </template>