@hostlink/nuxt-light 1.22.1 → 1.22.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.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "light",
3
3
  "configKey": "light",
4
- "version": "1.22.1",
4
+ "version": "1.22.3",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.4",
7
7
  "unbuild": "2.0.0"
@@ -53,4 +53,9 @@ const LABLES = [
53
53
  </q-item-section>
54
54
  <q-item-section> {{ $t(label.label) }} </q-item-section>
55
55
  </q-item>
56
- </template>
56
+ </template>
57
+
58
+
59
+ <style scoped>
60
+ .q-item--active{background-color:#e0e0e0}
61
+ </style>
@@ -145,6 +145,7 @@ function toggleLeftDrawer() {
145
145
  leftDrawerOpen.value = !leftDrawerOpen.value;
146
146
  }
147
147
  const loadItems = async () => {
148
+
148
149
  let path = selectedPath.value;
149
150
 
150
151
  files.value = [];
@@ -201,13 +202,15 @@ const loadItems = async () => {
201
202
  item.id = selectedDrive.value + "/" + item.path;
202
203
  return item;
203
204
  });
205
+ reloadTreeFolder(selectedNodePath.value, folders.value);
204
206
  }
205
207
 
208
+
206
209
  loading.value = false;
207
210
 
208
211
 
209
212
 
210
- reloadTreeFolder(selectedNodePath.value, folders.value);
213
+
211
214
  }
212
215
 
213
216
 
@@ -292,6 +295,7 @@ const findFolder = (path, folders) => {
292
295
 
293
296
  const reloadTreeFolder = (path, newFolders) => {
294
297
  let node = folderTree.value.getNodeByKey(path);
298
+
295
299
  if (node) {
296
300
  node.lazy = false;
297
301
  node.children = newFolders;
@@ -876,7 +880,3 @@ selectedNodePath.value = drives[0].index.toString();
876
880
  </q-page-container>
877
881
  </q-layout>
878
882
  </template>
879
-
880
- <style>
881
- .q-item--active{background-color:#e0e0e0}
882
- </style>
@@ -0,0 +1,115 @@
1
+ <script setup>
2
+ import collect from "collect.js";
3
+
4
+ import { computed, onMounted, useAttrs, ref } from "vue";
5
+
6
+ const props = defineProps({
7
+ options: {
8
+ type: Array,
9
+ required: true,
10
+ },
11
+ emitValue: {
12
+ type: Boolean,
13
+ default: true,
14
+ },
15
+ mapOptions: {
16
+ type: Boolean,
17
+ default: true,
18
+ },
19
+ });
20
+
21
+ const userString = ref("");
22
+ const items = computed(() => {
23
+
24
+ //filter out items based on user input
25
+
26
+ const filteredItems = collect(props.options)
27
+ .filter((item) => {
28
+ if (userString.value === "") {
29
+ return true;
30
+ }
31
+ return item.label.toLowerCase().includes(userString.value);
32
+ })
33
+ .toArray();
34
+
35
+ const groups = collect(filteredItems).unique("group").pluck("group").sort();
36
+
37
+ const options = collect();
38
+ groups.each((group) => {
39
+ const items = collect(filteredItems).where("group", group).toArray();
40
+ options
41
+ .push({ label: group, is_group: true, disable: true })
42
+ .push(...items);
43
+ });
44
+
45
+ return options.toArray();
46
+ });
47
+
48
+ const model = defineModel();
49
+
50
+ const attrs = useAttrs();
51
+ const handleItemUniqueByGroup = (items) => {
52
+ return;
53
+ if (!attrs.hasOwnProperty("multiple") || attrs.multiple === false) {
54
+ return;
55
+ }
56
+ /*
57
+ model.value = collect(items)
58
+ .unique((item) => {
59
+ // Allow selecting multiple items that are not grouped
60
+ if (item.group === null) {
61
+ return item.value;
62
+ }
63
+
64
+ return item.group;
65
+ })
66
+ .toArray(); */
67
+ };
68
+
69
+ onMounted(() => {
70
+ //這個功能是為了避免在多選的情況下,選擇同一個group的item
71
+ // handleItemUniqueByGroup(model.value);
72
+
73
+ });
74
+
75
+ const filterFn = (val, update, abort) => {
76
+ if (val === "") {
77
+ update(() => {
78
+ userString.value = "";
79
+ });
80
+ return;
81
+ }
82
+
83
+ const needle = val.toLowerCase();
84
+ update(() => {
85
+ userString.value = needle;
86
+ });
87
+ };
88
+
89
+ </script>
90
+
91
+ <template>
92
+
93
+
94
+ <q-select v-model="model" v-bind="$light.getInputProps($props)" :options="items" @update:model-value="handleItemUniqueByGroup"
95
+ input-debounce="0" @filter="filterFn" :color="$light.color" :style="$light.styles.input"
96
+ :emit-value="emitValue" :map-options="mapOptions">
97
+ <template v-slot:option="scope">
98
+ <q-item v-if="scope.opt.is_group" v-bind="{ ...scope.itemProps }" class="text-xs bg-grey-4" :key="scope.opt.label">
99
+ <q-item-section class="!cursor-default">
100
+ {{ scope.opt.label || "Ungroup" }}
101
+ </q-item-section>
102
+ </q-item>
103
+ <q-item v-else v-bind="{ ...scope.itemProps }" :key="scope.opt.value">
104
+ <q-item-section class="q-pl-md">{{ scope.opt.label }}</q-item-section>
105
+ </q-item>
106
+ </template>
107
+ <template v-slot:no-option>
108
+ <q-item>
109
+ <q-item-section class="text-grey">
110
+ No results
111
+ </q-item-section>
112
+ </q-item>
113
+ </template>
114
+ </q-select>
115
+ </template>
@@ -293,20 +293,20 @@ const facebookLogin = (accessToken) => {
293
293
  </div>
294
294
  <q-form ref="form1" v-if="passwordBasedEnabled">
295
295
  <div class="q-gutter-sm">
296
- <l-input v-model.trim="data.username" label="Username" :rules="[v => !!v || $t('Username is required')]"
296
+ <l-input color="primary" v-model.trim="data.username" label="Username" :rules="[v => !!v || $t('Username is required')]"
297
297
  clearable :outlined="false" stackLabel autocomplete="username">
298
298
  <template v-slot:prepend>
299
299
  <q-icon name="sym_o_person" />
300
300
  </template>
301
301
  </l-input>
302
- <l-input v-model="data.password" label="Password" type="password" clearable show-password stackLabel
302
+ <l-input color="primary" v-model="data.password" label="Password" type="password" clearable show-password stackLabel
303
303
  :rules="[v => !!v || $t('Password is required')]" @keydown.enter.prevent="submit" :outlined="false"
304
304
  autocomplete="off">
305
305
  <template v-slot:prepend>
306
306
  <q-icon name="sym_o_lock" />
307
307
  </template>
308
308
  </l-input>
309
- <l-input v-if="twoFactorAuthentication" v-model="data.code" label="2FA code"
309
+ <l-input color="primary" v-if="twoFactorAuthentication" v-model="data.code" label="2FA code"
310
310
  :rules="[v => !!v || $t('2FA code is required')]" type="text" clearable stackLabel :outlined="false">
311
311
  <template v-slot:prepend>
312
312
  <q-icon name="sym_o_key" />
@@ -0,0 +1,34 @@
1
+ <script setup>
2
+ import { getErrorMessage } from 'formkit-quasar';
3
+ import { computed } from 'vue'
4
+ const props = defineProps({
5
+ context: Object
6
+ });
7
+
8
+ const { error, errorMessage } = getErrorMessage(props.context.node);
9
+
10
+
11
+
12
+ const value = computed({
13
+ get: () => props.context.value,
14
+ set: (val) => props.context.node.input(val)
15
+ })
16
+
17
+
18
+ let clearable = false;
19
+ if (props.context.state.required) { //no clearable
20
+ clearable = false;
21
+ } else {
22
+ clearable = true;
23
+ }
24
+
25
+ </script>
26
+ <template>
27
+ <l-group-select v-model="value" :label="context.label" v-bind="context.attrs" :error="error"
28
+ :error-message="errorMessage" :required="context.state.required"
29
+ :disable="context.disabled">
30
+ <template v-for="(s, name) in $slots" v-slot:[name]="props" :key="name">
31
+ <slot :name="name" v-bind="props ?? {}"></slot>
32
+ </template>
33
+ </l-group-select>
34
+ </template>
@@ -14,6 +14,7 @@ import InputXlsxVue from "./InputXlsx.vue";
14
14
  import FileUploadVue from "./FileUpload.vue";
15
15
  import EditorVue from "./Editor.vue";
16
16
  import ToggleVue from "./Toggle.vue";
17
+ import GroupSelect from "./GroupSelect.vue";
17
18
  export const createLightPlugin = () => {
18
19
  return (node) => {
19
20
  let type = node.props.type + "";
@@ -79,6 +80,11 @@ export const createLightPlugin = () => {
79
80
  type: "input",
80
81
  component: SelectVue
81
82
  });
83
+ case "l-group-select":
84
+ return node.define({
85
+ type: "input",
86
+ component: GroupSelect
87
+ });
82
88
  case "l-repeater":
83
89
  return node.define({
84
90
  type: "input",
@@ -2,7 +2,14 @@
2
2
  import { q } from '#imports'
3
3
  const { system } = await q({
4
4
  system: {
5
- server: true
5
+ server: true,
6
+ arch: true,
7
+ os: true,
8
+ CPUCores: true,
9
+ hostname: true,
10
+ memoryTotal: true,
11
+ memoryFree: true,
12
+ memoryAvailable: true,
6
13
  }
7
14
  })
8
15
 
@@ -22,6 +29,20 @@ const columns = [
22
29
  </script>
23
30
  <template>
24
31
  <l-page>
32
+ <l-card>
33
+ <l-list>
34
+ <l-item label="Arch">{{ system.arch }}</l-item>
35
+ <l-item label="OS">{{ system.os }}</l-item>
36
+ <l-item label="CPUCores">{{ system.CPUCores }}</l-item>
37
+ <l-item label="Hostname">{{ system.hostname }}</l-item>
38
+ <l-item label="Memory Total">{{ system.memoryTotal }}</l-item>
39
+ <l-item label="Memory Free">{{ system.memoryFree }}</l-item>
40
+ <l-item label="Memory Available">{{ system.memoryAvailable }}</l-item>
41
+ </l-list>
42
+ </l-card>
43
+
44
+
45
+
25
46
  <l-table searchable :rows="system.server" :columns="columns" :rows-per-page-options="[0]"
26
47
  hide-pagination></l-table>
27
48
  </l-page>
@@ -237,7 +237,7 @@ const menusOnly = computed(() => {
237
237
  </q-dialog>
238
238
 
239
239
  <l-card>
240
- <q-toolbar class="q-gutter-xs">
240
+ <q-card-actions class="q-gutter-y-sm">
241
241
  <l-btn @click="onSave" label="Save" icon="sym_o_save" />
242
242
  <l-btn @click="onReload" label="Reload" icon="sym_o_refresh" />
243
243
 
@@ -298,7 +298,7 @@ const menusOnly = computed(() => {
298
298
  </q-btn-dropdown>
299
299
  </template>
300
300
  </template>
301
- </q-toolbar>
301
+ </q-card-actions>
302
302
  <q-splitter v-model="splitterModel" style="height:680px">
303
303
  <template #before>
304
304
 
@@ -360,8 +360,6 @@ const menusOnly = computed(() => {
360
360
 
361
361
  </q-splitter>
362
362
 
363
-
364
-
365
363
  </l-card>
366
364
 
367
365
  </l-page>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostlink/nuxt-light",
3
- "version": "1.22.1",
3
+ "version": "1.22.3",
4
4
  "description": "HostLink Nuxt Light Framework",
5
5
  "repository": {
6
6
  "type": "git",