@hostlink/nuxt-light 1.29.0 → 1.31.0

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 (33) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +1 -1
  3. package/dist/runtime/components/L/Fieldset.vue.d.ts +1 -3
  4. package/dist/runtime/components/l-alert.vue.d.ts +1 -3
  5. package/dist/runtime/components/l-app.vue.d.ts +1 -3
  6. package/dist/runtime/components/l-customizer.vue +1 -0
  7. package/dist/runtime/components/l-drag-drop-group.vue.d.ts +1 -3
  8. package/dist/runtime/components/l-form-dialog.vue.d.ts +1 -3
  9. package/dist/runtime/components/l-input.vue +10 -10
  10. package/dist/runtime/components/l-input.vue.d.ts +15 -3
  11. package/dist/runtime/components/l-link.vue.d.ts +1 -3
  12. package/dist/runtime/components/l-table.vue +10 -0
  13. package/dist/runtime/formkit/Checkbox.vue.d.ts +1 -4
  14. package/dist/runtime/formkit/DatePicker.vue.d.ts +1 -4
  15. package/dist/runtime/formkit/Editor.vue.d.ts +1 -3
  16. package/dist/runtime/formkit/File.vue.d.ts +1 -4
  17. package/dist/runtime/formkit/FilePicker.vue.d.ts +1 -4
  18. package/dist/runtime/formkit/FileUpload.vue.d.ts +1 -4
  19. package/dist/runtime/formkit/GroupSelect.vue.d.ts +1 -4
  20. package/dist/runtime/formkit/InputXlsx.vue.d.ts +1 -3
  21. package/dist/runtime/formkit/Radio.vue.d.ts +1 -3
  22. package/dist/runtime/formkit/Repeater.vue.d.ts +1 -7
  23. package/dist/runtime/formkit/Select.vue.d.ts +1 -4
  24. package/dist/runtime/formkit/TimePicker.vue.d.ts +1 -4
  25. package/dist/runtime/pages/MailLog/index.vue +16 -5
  26. package/dist/runtime/pages/Permission/all.vue +49 -43
  27. package/dist/runtime/pages/System/database/backup.vue +21 -19
  28. package/dist/runtime/pages/System/database/process.vue +11 -13
  29. package/dist/runtime/pages/System/database/table.vue +12 -12
  30. package/dist/runtime/pages/User/setting/style.vue +1 -0
  31. package/dist/runtime/plugin.d.ts +1 -0
  32. package/dist/runtime/plugin.js +3 -22
  33. package/package.json +2 -1
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "light",
3
3
  "configKey": "light",
4
- "version": "1.29.0",
4
+ "version": "1.31.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.1",
7
7
  "unbuild": "3.5.0"
package/dist/module.mjs CHANGED
@@ -315,7 +315,7 @@ const module = defineNuxtModule({
315
315
  }
316
316
  }
317
317
  },
318
- plugins: ["Dialog", "Loading", "LoadingBar", "Notify"]
318
+ plugins: ["Dialog", "Loading", "LoadingBar", "Notify", "AppFullscreen"]
319
319
  });
320
320
  nuxt.options.imports = nuxt.options.imports || {};
321
321
  nuxt.options.imports.presets = nuxt.options.imports.presets || [];
@@ -11,6 +11,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
11
11
  readonly gutter?: string | undefined;
12
12
  };
13
13
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
14
- type __VLS_Slots = {
15
- default?: ((props: {}) => any) | undefined;
16
- };
14
+ type __VLS_Slots = any;
@@ -9,6 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly type?: string | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- default?: ((props: {}) => any) | undefined;
14
- };
12
+ type __VLS_Slots = any;
@@ -4,6 +4,4 @@ type __VLS_WithSlots<T, S> = T & (new () => {
4
4
  $slots: S;
5
5
  });
6
6
  declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
7
- type __VLS_Slots = {
8
- header?: ((props: {}) => any) | undefined;
9
- };
7
+ type __VLS_Slots = any;
@@ -175,6 +175,7 @@ requestAnimationFrame(refreshServerTime);
175
175
  <q-item-label>{{ server_date }} {{ server_time }} </q-item-label>
176
176
  </q-item-section>
177
177
  </q-item>
178
+
178
179
 
179
180
  </q-list>
180
181
  </template>
@@ -9,6 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  getGroupName: () => symbol;
10
10
  findAllItems: () => any[];
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- default?: ((props: {}) => any) | undefined;
14
- };
12
+ type __VLS_Slots = any;
@@ -20,6 +20,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
20
20
  readonly showNotification?: boolean | undefined;
21
21
  };
22
22
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
23
- type __VLS_Slots = {
24
- default?: ((props: any) => any) | undefined;
25
- };
23
+ type __VLS_Slots = any;
@@ -60,8 +60,8 @@ const props = defineProps({
60
60
  onBlur: { type: Function, required: false },
61
61
  onClear: { type: Function, required: false }
62
62
  });
63
- const modelValue = props.modelValue;
64
- const new_rules = props.rules || [];
63
+ const modelValue = defineModel();
64
+ const new_rules = Array.isArray(props.rules) ? [...props.rules] : [];
65
65
  if (props.required) {
66
66
  new_rules.push((val) => !!val || t("input_required", [t(props.label ?? "")]));
67
67
  }
@@ -72,28 +72,29 @@ if (props.type == "email") {
72
72
  }
73
73
  });
74
74
  }
75
- if (new_rules.indexOf("containUpper") >= 0) {
75
+ const stringRules = new_rules.filter((r) => typeof r === "string");
76
+ if (stringRules.includes("containUpper")) {
76
77
  new_rules.push((val) => {
77
78
  if (val && !val.match(/[A-Z]/)) {
78
79
  return t("Must contain at least one uppercase letter");
79
80
  }
80
81
  });
81
82
  }
82
- if (new_rules.indexOf("containLower") >= 0) {
83
+ if (stringRules.includes("containLower")) {
83
84
  new_rules.push((val) => {
84
85
  if (val && !val.match(/[a-z]/)) {
85
86
  return t("Must contain at least one lowercase letter");
86
87
  }
87
88
  });
88
89
  }
89
- if (new_rules.indexOf("containNumber") >= 0) {
90
+ if (stringRules.includes("containNumber")) {
90
91
  new_rules.push((val) => {
91
92
  if (val && !val.match(/[0-9]/)) {
92
93
  return t("Must contain at least one number");
93
94
  }
94
95
  });
95
96
  }
96
- if (new_rules.indexOf("containSpecial") >= 0) {
97
+ if (stringRules.includes("containSpecial")) {
97
98
  new_rules.push((val) => {
98
99
  if (val && !val.match(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/)) {
99
100
  return t("Must contain at least one symbol");
@@ -154,10 +155,9 @@ const onClickTc2Sc = () => {
154
155
  </template>
155
156
 
156
157
  <template v-if="localShowPassword" v-slot:append>
157
- <q-icon name="sym_o_visibility" class="cursor-pointer" :color="showPassword ? 'primary' : 'grey-5'"
158
- @click="isShowPassword = false" v-if="isShowPassword" />
159
- <q-icon name="sym_o_visibility_off" class="cursor-pointer" :color="showPassword ? 'grey-5' : 'primary'"
160
- @click="isShowPassword = true" v-else />
158
+ <q-icon name="sym_o_visibility" class="cursor-pointer" @click="isShowPassword = false"
159
+ v-if="isShowPassword" />
160
+ <q-icon name="sym_o_visibility_off" class="cursor-pointer" @click="isShowPassword = true" v-else />
161
161
  </template>
162
162
 
163
163
  </q-input>
@@ -4,23 +4,31 @@ export interface LInputProps extends QInputProps {
4
4
  translate?: boolean;
5
5
  required?: boolean;
6
6
  }
7
+ type __VLS_Props = LInputProps;
7
8
  declare const new_rules: import("quasar").ValidationRule[];
8
9
  declare const isShowPassword: import("vue").Ref<boolean, boolean>;
9
10
  declare const localType: import("vue").ComputedRef<"number" | "textarea" | "time" | "text" | "search" | "date" | "url" | "email" | "file" | "datetime-local" | "password" | "tel" | undefined>;
10
11
  declare const localShowPassword: import("vue").ComputedRef<boolean>;
11
12
  declare const onClickTc2Sc: () => void;
13
+ type __VLS_PublicProps = __VLS_Props & {
14
+ modelValue?: any;
15
+ };
12
16
  declare const __VLS_ctx: InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>;
13
17
  declare var __VLS_31: string | number, __VLS_32: any;
14
18
  type __VLS_Slots = __VLS_PrettifyGlobal<__VLS_OmitStringIndex<typeof __VLS_ctx.$slots> & {
15
19
  [K in NonNullable<typeof __VLS_31>]?: (props: typeof __VLS_32) => any;
16
20
  }>;
17
- declare const __VLS_self: import("vue").DefineComponent<LInputProps, {
21
+ declare const __VLS_self: import("vue").DefineComponent<__VLS_PublicProps, {
18
22
  new_rules: typeof new_rules;
19
23
  isShowPassword: typeof isShowPassword;
20
24
  localType: typeof localType;
21
25
  localShowPassword: typeof localShowPassword;
22
26
  onClickTc2Sc: typeof onClickTc2Sc;
23
- }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<LInputProps> & Readonly<{}>, {
27
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
28
+ "update:modelValue": (value: any) => any;
29
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
30
+ "onUpdate:modelValue"?: ((value: any) => any) | undefined;
31
+ }>, {
24
32
  dense: boolean;
25
33
  dark: boolean | null;
26
34
  rounded: boolean;
@@ -31,7 +39,11 @@ declare const __VLS_self: import("vue").DefineComponent<LInputProps, {
31
39
  standout: string | boolean;
32
40
  stackLabel: boolean;
33
41
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
34
- declare const __VLS_component: import("vue").DefineComponent<LInputProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<LInputProps> & Readonly<{}>, {
42
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
43
+ "update:modelValue": (value: any) => any;
44
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
45
+ "onUpdate:modelValue"?: ((value: any) => any) | undefined;
46
+ }>, {
35
47
  dense: boolean;
36
48
  dark: boolean | null;
37
49
  rounded: boolean;
@@ -11,6 +11,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
11
11
  readonly to?: string | undefined;
12
12
  };
13
13
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
14
- type __VLS_Slots = {
15
- default?: ((props: {}) => any) | undefined;
16
- };
14
+ type __VLS_Slots = any;
@@ -240,12 +240,22 @@ const onLocalRequest = async (p) => {
240
240
  pagination.value.descending = p.pagination.descending;
241
241
  pagination.value.rowsPerPage = p.pagination.rowsPerPage;
242
242
  loading.value = false;
243
+ if (modelName.value) {
244
+ localStorage.setItem(`l-table-rowsPerPage-${modelName.value}`, String(pagination.value.rowsPerPage));
245
+ }
243
246
  validateData();
244
247
  },
245
248
  loadObjects(model2, filters2 = null, fields = []) {
246
249
  return this.loadData(model2, filters2, fields);
247
250
  },
248
251
  async loadData(model2, filters2 = null, fields = []) {
252
+ const saved = Number(localStorage.getItem(`l-table-rowsPerPage-${model2}`));
253
+ if (saved && props.rowsPerPageOptions.includes(saved) && saved !== pagination.value.rowsPerPage) {
254
+ pagination.value.rowsPerPage = saved;
255
+ if (typeof p !== "undefined" && p.pagination) {
256
+ p.pagination.rowsPerPage = saved;
257
+ }
258
+ }
249
259
  fields.forEach((f) => {
250
260
  builder.add(f);
251
261
  });
@@ -9,7 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- [x: string]: ((props: any) => any) | undefined;
14
- [x: number]: ((props: any) => any) | undefined;
15
- };
12
+ type __VLS_Slots = any;
@@ -9,7 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- [x: string]: ((props: any) => any) | undefined;
14
- [x: number]: ((props: any) => any) | undefined;
15
- };
12
+ type __VLS_Slots = any;
@@ -9,6 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- default?: ((props: {}) => any) | undefined;
14
- };
12
+ type __VLS_Slots = any;
@@ -9,7 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- [x: string]: ((props: any) => any) | undefined;
14
- [x: number]: ((props: any) => any) | undefined;
15
- };
12
+ type __VLS_Slots = any;
@@ -9,7 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- [x: string]: ((props: any) => any) | undefined;
14
- [x: number]: ((props: any) => any) | undefined;
15
- };
12
+ type __VLS_Slots = any;
@@ -9,7 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- [x: string]: ((props: any) => any) | undefined;
14
- [x: number]: ((props: any) => any) | undefined;
15
- };
12
+ type __VLS_Slots = any;
@@ -9,7 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- [x: string]: ((props: any) => any) | undefined;
14
- [x: number]: ((props: any) => any) | undefined;
15
- };
12
+ type __VLS_Slots = any;
@@ -9,6 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- default?: ((props: {}) => any) | undefined;
14
- };
12
+ type __VLS_Slots = any;
@@ -9,6 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- default?: ((props: {}) => any) | undefined;
14
- };
12
+ type __VLS_Slots = any;
@@ -9,10 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- default?: ((props: {
14
- value: any;
15
- index: number;
16
- node: any;
17
- }) => any) | undefined;
18
- };
12
+ type __VLS_Slots = any;
@@ -9,7 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- [x: string]: ((props: any) => any) | undefined;
14
- [x: number]: ((props: any) => any) | undefined;
15
- };
12
+ type __VLS_Slots = any;
@@ -9,7 +9,4 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
9
9
  readonly context?: Record<string, any> | undefined;
10
10
  };
11
11
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
- type __VLS_Slots = {
13
- [x: string]: ((props: any) => any) | undefined;
14
- [x: number]: ((props: any) => any) | undefined;
15
- };
12
+ type __VLS_Slots = any;
@@ -8,17 +8,28 @@ const columns = model("MailLog").columns({
8
8
  created_time: true,
9
9
  body: true
10
10
  });
11
+ function requestMailLog(event) {
12
+ event.loadObjects("MailLog", {}, ["body"]);
13
+ }
11
14
  </script>
12
15
 
13
16
  <template>
14
17
  <l-page>
15
- <l-table row-key="maillog_id" @request-data="$event.loadObjects('MailLog', {}, ['body'])" :columns="columns"
16
- sort-by="maillog_id:desc">
17
-
18
+ <l-table
19
+ row-key="maillog_id"
20
+ @request-data="requestMailLog"
21
+ :columns="columns"
22
+ sort-by="maillog_id:desc"
23
+ >
18
24
  <template #row-expand="props">
19
- <iframe width="100%" height="300px" :srcdoc="props.row.body" frameborder="0"></iframe>
25
+ <iframe
26
+ width="100%"
27
+ height="300px"
28
+ :srcdoc="props.row.body"
29
+ frameborder="0"
30
+ sandbox
31
+ ></iframe>
20
32
  </template>
21
-
22
33
  </l-table>
23
34
  </l-page>
24
35
  </template>
@@ -1,67 +1,73 @@
1
1
  <script setup>
2
- import { reactive } from "vue";
2
+ import { computed, ref } from "vue";
3
3
  import { m, api } from "#imports";
4
4
  import { useI18n } from "vue-i18n";
5
5
  const { t } = useI18n();
6
- const { app } = await api.query({
7
- app: {
8
- permissions: true,
9
- roles: {
10
- name: true,
11
- permissions: true
6
+ const fetchApp = async () => {
7
+ const { app: app2 } = await api.query({
8
+ app: {
9
+ permissions: true,
10
+ roles: {
11
+ name: true,
12
+ permissions: true
13
+ }
12
14
  }
13
- }
14
- });
15
- const roles = app.roles;
16
- const columns = [{
17
- label: t("Permission"),
18
- field: "permission",
19
- align: "left"
20
- }];
21
- roles.forEach((role) => {
22
- columns.push({
15
+ });
16
+ return app2;
17
+ };
18
+ const app = ref(await fetchApp());
19
+ const roles = computed(() => app.value.roles);
20
+ const columns = computed(() => [
21
+ { label: t("Permission"), field: "permission", align: "left" },
22
+ ...roles.value.map((role) => ({
23
23
  label: role.name,
24
24
  field: role.name,
25
25
  align: "left"
26
- });
27
- });
28
- const rows = reactive([]);
29
- app.permissions.forEach((permission) => {
30
- let row = {
31
- permission
32
- };
33
- roles.forEach((role) => {
34
- if (role.permissions.indexOf(permission) != -1) {
35
- row[role.name] = true;
36
- } else {
37
- row[role.name] = false;
38
- }
39
- });
40
- rows.push(row);
41
- });
42
- const onUpdate = (value, role, permission) => {
26
+ }))
27
+ ]);
28
+ const rows = computed(
29
+ () => app.value.permissions.map((permission) => {
30
+ const row = { permission };
31
+ roles.value.forEach((role) => {
32
+ row[role.name] = role.permissions.includes(permission);
33
+ });
34
+ return row;
35
+ })
36
+ );
37
+ const onUpdate = async (value, role, permission) => {
43
38
  if (value) {
44
- m("addPermission", { value: permission, role });
39
+ await m("addPermission", { value: permission, role });
45
40
  } else {
46
- m("removePermission", { value: permission, role });
41
+ await m("removePermission", { value: permission, role });
47
42
  }
48
- rows.forEach((row) => {
49
- if (row.permission == permission) {
50
- row[role] = value;
51
- }
52
- });
43
+ app.value = await fetchApp();
53
44
  };
45
+ const filter = ref("");
46
+ const filteredRows = computed(() => {
47
+ if (!filter.value) return rows.value;
48
+ return rows.value.filter(
49
+ (row) => row.permission.toLowerCase().includes(filter.value.toLowerCase())
50
+ );
51
+ });
54
52
  </script>
55
53
 
56
54
  <template>
57
55
  <l-page>
58
- <q-table :columns="columns" flat bordered :rows="rows" :pagination="{ rowsPerPage: 0 }" dense>
56
+ <q-table :columns="columns" flat bordered :rows="filteredRows" :pagination="{ rowsPerPage: 0 }" dense>
57
+ <template #top-left>
58
+ <q-input :color="$light.color" v-model="filter" :placeholder="t('Filter permissions')" dense clearable
59
+ outlined>
60
+ <template v-slot:append>
61
+ <q-icon name="sym_o_search" />
62
+ </template>
63
+ </q-input>
64
+ </template>
59
65
  <template #body="props">
60
66
  <q-tr :props="props">
61
67
  <q-td>
62
68
  {{ props.row.permission }}
63
69
  </q-td>
64
- <q-td v-for="role in roles">
70
+ <q-td v-for="role in roles" :key="role.name">
65
71
  <q-checkbox v-model="props.row[role.name]"
66
72
  @update:model-value="onUpdate($event, role.name, props.row.permission)"
67
73
  :color="$light.color" />
@@ -1,26 +1,28 @@
1
1
  <script setup>
2
2
  import { q } from "#imports";
3
- import { Loading } from "quasar";
3
+ import { Loading, Notify } from "quasar";
4
4
  const onClickDownload = async () => {
5
- Loading.show({
6
- message: "Exporting database..."
7
- });
8
- const data = await q({
9
- system: {
10
- database: {
11
- export: true
5
+ Loading.show({ message: "Exporting database..." });
6
+ try {
7
+ const data = await q({
8
+ system: {
9
+ database: {
10
+ export: true
11
+ }
12
12
  }
13
- }
14
- });
15
- Loading.hide();
16
- const file = new File([data.system.database.export], "backup.sql", {
17
- type: "text/plain;charset=utf-8"
18
- });
19
- const a = document.createElement("a");
20
- a.download = file.name;
21
- a.href = URL.createObjectURL(file);
22
- a.click();
23
- URL.revokeObjectURL(a.href);
13
+ });
14
+ const blob = new Blob([data.system.database.export], { type: "text/plain;charset=utf-8" });
15
+ const url = URL.createObjectURL(blob);
16
+ const a = document.createElement("a");
17
+ a.download = "backup.sql";
18
+ a.href = url;
19
+ a.click();
20
+ setTimeout(() => URL.revokeObjectURL(url), 1e3);
21
+ } catch (e) {
22
+ Notify.create({ type: "negative", message: "\u4E0B\u8F09\u5931\u6557\uFF0C\u8ACB\u7A0D\u5F8C\u518D\u8A66\u3002" });
23
+ } finally {
24
+ Loading.hide();
25
+ }
24
26
  };
25
27
  </script>
26
28
 
@@ -15,28 +15,28 @@ const { data, refresh } = await useAsyncData(async () => {
15
15
  return system;
16
16
  });
17
17
  const autoRefresh = ref(0);
18
- let interval = null;
18
+ const interval = ref(null);
19
19
  watch(autoRefresh, (value) => {
20
- if (interval)
21
- clearInterval(interval);
20
+ if (interval.value)
21
+ clearInterval(interval.value);
22
22
  if (value) {
23
- interval = setInterval(refresh, value);
23
+ interval.value = setInterval(() => {
24
+ refresh();
25
+ }, value);
24
26
  }
25
- });
27
+ }, { immediate: true });
26
28
  onUnmounted(() => {
27
- if (interval)
28
- clearInterval(interval);
29
+ if (interval.value)
30
+ clearInterval(interval.value);
29
31
  });
30
32
  </script>
31
33
 
32
34
  <template>
33
35
  <l-page title="System Database Process">
34
- <q-table :rows="data.database.processList" hide-bottom v-bind="$light.styles.table" :loading="loading">
36
+ <q-table :rows="data?.database?.processList || []" hide-bottom v-bind="$light.styles.table" :loading="loading">
35
37
  <template #top-left>
36
38
  <q-btn label="Reload" outline :color="$light.color" icon="sym_o_refresh" @click="refresh"></q-btn>
37
-
38
39
  </template>
39
-
40
40
  <template #top-right>
41
41
  <q-select label="Auto Refresh" v-model="autoRefresh" :options="[
42
42
  { label: 'Off', value: 0 },
@@ -48,11 +48,9 @@ onUnmounted(() => {
48
48
  { label: '10m', value: 600000 },
49
49
  { label: '30m', value: 1800000 },
50
50
  { label: '1h', value: 3600000 }
51
- ]" @input="autoRefresh && refresh" outlined :color="$light.color" dense="" style="min-width: 200px"
51
+ ]" @update:model-value="autoRefresh && refresh()" outlined :color="$light.color" dense style="min-width: 200px"
52
52
  map-options emit-value></q-select>
53
-
54
53
  </template>
55
54
  </q-table>
56
-
57
55
  </l-page>
58
56
  </template>
@@ -16,10 +16,10 @@ const { data, refresh } = await useAsyncData("database", async () => {
16
16
  });
17
17
  const SYSTEM_TABLES = ["Config", "EventLog", "MailLog", "Permission", "Role", "SystemValue", "Translate", "User", "UserLog", "UserRole", "MyFavorite", "CustomField"];
18
18
  const custom_tables = computed(() => {
19
- return data.value.tableStatus.filter((table) => !SYSTEM_TABLES.includes(table.Name));
19
+ return (data.value?.tableStatus ?? []).filter((table) => !SYSTEM_TABLES.includes(table.Name));
20
20
  });
21
21
  const systables = computed(() => {
22
- return data.value.tableStatus.filter((table) => SYSTEM_TABLES.includes(table.Name));
22
+ return (data.value?.tableStatus ?? []).filter((table) => SYSTEM_TABLES.includes(table.Name));
23
23
  });
24
24
  const field_add = resolveComponent("l-dialog-database-field-add");
25
25
  const table_add = resolveComponent("l-database-create-table-dialog");
@@ -51,8 +51,10 @@ const add = async (table) => {
51
51
  });
52
52
  };
53
53
  const selected = reactive({});
54
- for (let table of data.value.table) {
55
- selected[table.name] = [];
54
+ if (data.value?.table) {
55
+ for (let table of data.value.table) {
56
+ selected[table.name] = [];
57
+ }
56
58
  }
57
59
  const removeField = async (table) => {
58
60
  light.dialog({
@@ -173,14 +175,14 @@ const truncatTable = async () => {
173
175
  </l-list>
174
176
  </l-card>
175
177
 
176
- <q-card flat bordered>
178
+ <q-card>
177
179
  <q-list separator bordered>
178
180
  <q-expansion-item label="Table Status" dense>
179
- <div class="q-ma-sm q-gutter-y-sm">
181
+ <div s>
180
182
 
181
183
  <q-table :rows="custom_tables" hide-pagination flat bordered separator="cell" dense
182
184
  :rows-per-page-options="[0]" v-model:selected="selectedTable" selection="multiple"
183
- row-key="Name">
185
+ row-key="Name" :color="$light.color">
184
186
 
185
187
  <template #top-left>
186
188
  <q-btn icon="sym_o_add" @click="createTable()" round flat size="sm">
@@ -210,13 +212,12 @@ const truncatTable = async () => {
210
212
  </q-list>
211
213
  </q-card>
212
214
 
213
- <q-card flat bordered>
215
+ <q-card>
214
216
  <q-list separator bordered>
215
217
  <q-expansion-item :label="table.name" v-for="table in data.table" dense>
216
218
  <div class="q-ma-sm">
217
- <q-table row-key="Field" separator="cell" dense :rows="table.columns"
218
- :rows-per-page-options="[0]" hide-pagination flat bordered selection="multiple"
219
- v-model:selected="selected[table.name]">
219
+ <q-table row-key="Field" :rows="table.columns" :rows-per-page-options="[0]" hide-pagination flat
220
+ bordered selection="multiple" v-model:selected="selected[table.name]" :color="$light.color">
220
221
  <template #top-left>
221
222
  <q-btn icon="sym_o_add" @click="add(table.name)" round flat size="sm">
222
223
  <q-tooltip>Add field</q-tooltip>
@@ -233,6 +234,5 @@ const truncatTable = async () => {
233
234
  </q-list>
234
235
  </q-card>
235
236
 
236
-
237
237
  </l-page>
238
238
  </template>
@@ -100,6 +100,7 @@ const inputDesign = computed({
100
100
  { label: 'None', value: 'none' },
101
101
  ]" :color="$light.color" />
102
102
  </q-field>
103
+
103
104
  </q-card-section>
104
105
  </l-card>
105
106
 
@@ -1,3 +1,4 @@
1
+ import '@quasar/quasar-ui-qmarkdown/dist/index.css';
1
2
  import "./assets/main.css.js";
2
3
  declare const _default: import("#app").Plugin<Record<string, unknown>> & import("#app").ObjectPlugin<Record<string, unknown>>;
3
4
  export default _default;
@@ -1,4 +1,5 @@
1
- import { Quasar, Dialog, Notify, Loading, AppFullscreen } from "quasar";
1
+ import QMarkdownVuePlugin from "@quasar/quasar-ui-qmarkdown";
2
+ import "@quasar/quasar-ui-qmarkdown/dist/index.css";
2
3
  import { createI18n } from "vue-i18n";
3
4
  import createLight from "./composables/createLight.js";
4
5
  import { defineNuxtPlugin } from "#app";
@@ -44,6 +45,7 @@ export default defineNuxtPlugin((nuxtApp) => {
44
45
  light.addError(new Error(err));
45
46
  }
46
47
  };
48
+ nuxtApp.vueApp.use(QMarkdownVuePlugin);
47
49
  const i18n = createI18n({
48
50
  legacy: false,
49
51
  locale: localStorage.getItem("locale") || "en",
@@ -59,27 +61,6 @@ export default defineNuxtPlugin((nuxtApp) => {
59
61
  i18n
60
62
  }));
61
63
  nuxtApp.vueApp.use(i18n);
62
- nuxtApp.vueApp.use(Quasar, {
63
- config: {
64
- brand: {
65
- primary: "#7367f0",
66
- secondary: "#82868b",
67
- accent: "#9C27B0",
68
- dark: "#4b4b4b",
69
- darkPage: "#121212",
70
- positive: "#28c76f",
71
- negative: "#ea5455",
72
- info: "#00cfe8",
73
- warning: "#ff9f43"
74
- }
75
- },
76
- plugins: {
77
- Dialog,
78
- Notify,
79
- Loading,
80
- AppFullscreen
81
- }
82
- });
83
64
  let locale = localStorage.getItem("locale") || "en";
84
65
  if (locale == "zh-hk") {
85
66
  locale = "zhTW";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostlink/nuxt-light",
3
- "version": "1.29.0",
3
+ "version": "1.31.0",
4
4
  "description": "HostLink Nuxt Light Framework",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,6 +35,7 @@
35
35
  "@hostlink/light": "^2.5.2",
36
36
  "@nuxt/module-builder": "^1.0.1",
37
37
  "@quasar/extras": "^1.16.11",
38
+ "@quasar/quasar-ui-qmarkdown": "^2.0.5",
38
39
  "axios": "^1.5.0",
39
40
  "defu": "^6.1.4",
40
41
  "diff2html": "^3.4.47",