@hostlink/nuxt-light 1.50.0 → 1.51.1

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 (35) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +13 -3
  3. package/dist/runtime/components/l-add-btn.d.vue.ts +2 -2
  4. package/dist/runtime/components/l-add-btn.vue.d.ts +2 -2
  5. package/dist/runtime/components/l-app-main.d.vue.ts +3 -3
  6. package/dist/runtime/components/l-app-main.vue +14 -4
  7. package/dist/runtime/components/l-app-main.vue.d.ts +3 -3
  8. package/dist/runtime/components/l-customizer.d.vue.ts +4 -4
  9. package/dist/runtime/components/l-customizer.vue.d.ts +4 -4
  10. package/dist/runtime/components/l-date-picker.d.vue.ts +1 -1
  11. package/dist/runtime/components/l-date-picker.vue.d.ts +1 -1
  12. package/dist/runtime/components/l-editor.d.vue.ts +1 -1
  13. package/dist/runtime/components/l-editor.vue.d.ts +1 -1
  14. package/dist/runtime/components/l-form-dialog.d.vue.ts +2 -2
  15. package/dist/runtime/components/l-form-dialog.vue.d.ts +2 -2
  16. package/dist/runtime/components/l-table.vue +1 -12
  17. package/dist/runtime/components/l-time-picker.d.vue.ts +1 -1
  18. package/dist/runtime/components/l-time-picker.vue.d.ts +1 -1
  19. package/dist/runtime/composables/useLight.d.ts +8 -8
  20. package/dist/runtime/pages/System/database/check.vue +149 -0
  21. package/dist/runtime/pages/System/database/event.vue +5 -4
  22. package/dist/runtime/pages/System/database/table.vue +2 -3
  23. package/dist/runtime/pages/Translate/index.vue +5 -5
  24. package/dist/runtime/pages/User/setting/favorite.d.vue.ts +2 -0
  25. package/dist/runtime/pages/User/setting/favorite.vue +164 -0
  26. package/dist/runtime/pages/User/setting/favorite.vue.d.ts +2 -0
  27. package/dist/runtime/pages/User/setting/index.vue +0 -1
  28. package/dist/runtime/pages/User/setting/menu.d.vue.ts +2 -0
  29. package/dist/runtime/pages/User/setting/menu.vue +422 -0
  30. package/dist/runtime/pages/User/setting/menu.vue.d.ts +2 -0
  31. package/dist/runtime/pages/User/setting.vue +4 -2
  32. package/package.json +1 -1
  33. package/dist/runtime/pages/User/setting/my_favorite.vue +0 -156
  34. /package/dist/runtime/pages/{User/setting/my_favorite.d.vue.ts → System/database/check.d.vue.ts} +0 -0
  35. /package/dist/runtime/pages/{User/setting/my_favorite.vue.d.ts → System/database/check.vue.d.ts} +0 -0
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "light",
3
3
  "configKey": "light",
4
- "version": "1.50.0",
4
+ "version": "1.51.1",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -131,6 +131,11 @@ const routes = [
131
131
  path: "/SystemValue/add",
132
132
  file: "runtime/pages/SystemValue/add.vue"
133
133
  },
134
+ {
135
+ name: "System-database-check",
136
+ path: "/System/database/check",
137
+ file: "runtime/pages/System/database/check.vue"
138
+ },
134
139
  {
135
140
  name: "System-database-process",
136
141
  path: "/System/database/process",
@@ -226,9 +231,14 @@ const routes = [
226
231
  file: "runtime/pages/User/setting/information.vue"
227
232
  },
228
233
  {
229
- name: "User-setting-my_favorite",
230
- path: "my_favorite",
231
- file: "runtime/pages/User/setting/my_favorite.vue"
234
+ name: "User-setting-favorite",
235
+ path: "favorite",
236
+ file: "runtime/pages/User/setting/favorite.vue"
237
+ },
238
+ {
239
+ name: "User-setting-menu",
240
+ path: "menu",
241
+ file: "runtime/pages/User/setting/menu.vue"
232
242
  },
233
243
  {
234
244
  name: "User-setting-open_id",
@@ -1,11 +1,11 @@
1
1
  declare const _default: import("vue").DefineComponent<{}, {
2
2
  label: string;
3
- to?: string | undefined;
4
3
  color?: string | undefined;
4
+ to?: string | undefined;
5
5
  $props: {
6
6
  readonly label?: string | undefined;
7
- readonly to?: string | undefined;
8
7
  readonly color?: string | undefined;
8
+ readonly to?: string | undefined;
9
9
  };
10
10
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
11
11
  export default _default;
@@ -1,11 +1,11 @@
1
1
  declare const _default: import("vue").DefineComponent<{}, {
2
2
  label: string;
3
- to?: string | undefined;
4
3
  color?: string | undefined;
4
+ to?: string | undefined;
5
5
  $props: {
6
6
  readonly label?: string | undefined;
7
- readonly to?: string | undefined;
8
7
  readonly color?: string | undefined;
8
+ readonly to?: string | undefined;
9
9
  };
10
10
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
11
11
  export default _default;
@@ -1,12 +1,12 @@
1
- declare var __VLS_30: {}, __VLS_180: {}, __VLS_267: {}, __VLS_273: {};
1
+ declare var __VLS_30: {}, __VLS_180: {}, __VLS_271: {}, __VLS_277: {};
2
2
  type __VLS_Slots = {} & {
3
3
  header?: (props: typeof __VLS_30) => any;
4
4
  } & {
5
5
  'user-menu'?: (props: typeof __VLS_180) => any;
6
6
  } & {
7
- 'page-top'?: (props: typeof __VLS_267) => any;
7
+ 'page-top'?: (props: typeof __VLS_271) => any;
8
8
  } & {
9
- 'page-bottom'?: (props: typeof __VLS_273) => any;
9
+ 'page-bottom'?: (props: typeof __VLS_277) => any;
10
10
  };
11
11
  declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
12
12
  logout: (...args: any[]) => void;
@@ -3,7 +3,7 @@ import { useRoute, useRouter } from "vue-router";
3
3
  import { useLight, q, m } from "#imports";
4
4
  import { useQuasar } from "quasar";
5
5
  import { useI18n } from "vue-i18n";
6
- import { ref, computed, reactive, provide, watch, toRaw, onBeforeUnmount } from "vue";
6
+ import { ref, computed, reactive, provide, watch, toRaw } from "vue";
7
7
  import { useRuntimeConfig } from "nuxt/app";
8
8
  import { api } from "#imports";
9
9
  const emits = defineEmits(["logout"]);
@@ -47,7 +47,8 @@ const tt = await q({
47
47
  label: true,
48
48
  path: true,
49
49
  icon: true
50
- }
50
+ },
51
+ menu: true
51
52
  }
52
53
  });
53
54
  let app = tt.app;
@@ -58,7 +59,6 @@ light.init(my.styles);
58
59
  light.setMyRoles(my.roles);
59
60
  light.setPermissions(my.permissions);
60
61
  light.setMyFavorites(toRaw(my.myFavorites));
61
- const _errorTimers = /* @__PURE__ */ new Map();
62
62
  const myFavorites = computed(() => {
63
63
  return light.getMyFavorites();
64
64
  });
@@ -75,6 +75,7 @@ for (let t of app.i18nMessages) {
75
75
  }
76
76
  i18n.setLocaleMessage(i18n.locale, messages);
77
77
  const menus = ref(app.menus);
78
+ const my_menus = ref(my.menu);
78
79
  const leftDrawerOpen = ref(false);
79
80
  const rightDrawerOpen = ref(false);
80
81
  const toggleLeftDrawer = () => {
@@ -126,8 +127,16 @@ const onChangeLocale = async (locale) => {
126
127
  window.location.reload();
127
128
  };
128
129
  const reloadMenu = async () => {
129
- let app2 = await q("app", ["menus"]);
130
+ let { app: app2, my: my2 } = await q({
131
+ app: {
132
+ menus: true
133
+ },
134
+ my: {
135
+ menu: true
136
+ }
137
+ });
130
138
  menus.value = app2.menus;
139
+ my_menus.value.menu = my2.menu;
131
140
  };
132
141
  provide("reloadMenu", reloadMenu);
133
142
  watch(() => style.footer, async (value) => await light.setStyle("footer", value));
@@ -346,6 +355,7 @@ const onLogout = async () => {
346
355
  <!-- drawer content -->
347
356
  <q-scroll-area class="fit">
348
357
  <div class="q-mx-xs q-mt-xs">
358
+ <l-menu :value="my_menus" :dense="style.dense" />
349
359
  <l-fav-menu :value="myFavorites" :dense="style.dense" v-if="myFavoritesCount > 0" />
350
360
  <l-menu :value="menus" :dense="style.dense" />
351
361
  </div>
@@ -1,12 +1,12 @@
1
- declare var __VLS_30: {}, __VLS_180: {}, __VLS_267: {}, __VLS_273: {};
1
+ declare var __VLS_30: {}, __VLS_180: {}, __VLS_271: {}, __VLS_277: {};
2
2
  type __VLS_Slots = {} & {
3
3
  header?: (props: typeof __VLS_30) => any;
4
4
  } & {
5
5
  'user-menu'?: (props: typeof __VLS_180) => any;
6
6
  } & {
7
- 'page-top'?: (props: typeof __VLS_267) => any;
7
+ 'page-top'?: (props: typeof __VLS_271) => any;
8
8
  } & {
9
- 'page-bottom'?: (props: typeof __VLS_273) => any;
9
+ 'page-bottom'?: (props: typeof __VLS_277) => any;
10
10
  };
11
11
  declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
12
12
  logout: (...args: any[]) => void;
@@ -1,19 +1,19 @@
1
1
  declare const _default: import("vue").DefineComponent<{}, {
2
2
  $emit: (event: "update:theme" | "update:menuOverlayHeader" | "update:dense" | "update:color" | "update:miniState" | "update:footer", ...args: any[]) => void;
3
- color: string;
4
3
  time: string;
4
+ color: string;
5
5
  theme: string;
6
6
  dense: boolean;
7
- miniState: boolean;
8
7
  footer: boolean;
8
+ miniState: boolean;
9
9
  menuOverlayHeader: boolean;
10
10
  $props: {
11
- readonly color?: string | undefined;
12
11
  readonly time?: string | undefined;
12
+ readonly color?: string | undefined;
13
13
  readonly theme?: string | undefined;
14
14
  readonly dense?: boolean | undefined;
15
- readonly miniState?: boolean | undefined;
16
15
  readonly footer?: boolean | undefined;
16
+ readonly miniState?: boolean | undefined;
17
17
  readonly menuOverlayHeader?: boolean | undefined;
18
18
  };
19
19
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -1,19 +1,19 @@
1
1
  declare const _default: import("vue").DefineComponent<{}, {
2
2
  $emit: (event: "update:theme" | "update:menuOverlayHeader" | "update:dense" | "update:color" | "update:miniState" | "update:footer", ...args: any[]) => void;
3
- color: string;
4
3
  time: string;
4
+ color: string;
5
5
  theme: string;
6
6
  dense: boolean;
7
- miniState: boolean;
8
7
  footer: boolean;
8
+ miniState: boolean;
9
9
  menuOverlayHeader: boolean;
10
10
  $props: {
11
- readonly color?: string | undefined;
12
11
  readonly time?: string | undefined;
12
+ readonly color?: string | undefined;
13
13
  readonly theme?: string | undefined;
14
14
  readonly dense?: boolean | undefined;
15
- readonly miniState?: boolean | undefined;
16
15
  readonly footer?: boolean | undefined;
16
+ readonly miniState?: boolean | undefined;
17
17
  readonly menuOverlayHeader?: boolean | undefined;
18
18
  };
19
19
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -13,11 +13,11 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
13
13
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
14
14
  "onUpdate:modelValue"?: ((value: any) => any) | undefined;
15
15
  }>, {
16
+ disable: boolean;
16
17
  dark: boolean | null;
17
18
  rounded: boolean;
18
19
  square: boolean;
19
20
  dense: boolean;
20
- disable: boolean;
21
21
  outlined: boolean;
22
22
  filled: boolean;
23
23
  stackLabel: boolean;
@@ -13,11 +13,11 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
13
13
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
14
14
  "onUpdate:modelValue"?: ((value: any) => any) | undefined;
15
15
  }>, {
16
+ disable: boolean;
16
17
  dark: boolean | null;
17
18
  rounded: boolean;
18
19
  square: boolean;
19
20
  dense: boolean;
20
- disable: boolean;
21
21
  outlined: boolean;
22
22
  filled: boolean;
23
23
  stackLabel: boolean;
@@ -6,9 +6,9 @@ declare const _default: import("vue").DefineComponent<LEditorProps, {}, {}, {},
6
6
  }, string, import("vue").PublicProps, Readonly<LEditorProps> & Readonly<{
7
7
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
8
8
  }>, {
9
+ modelValue: string;
9
10
  dense: boolean;
10
11
  placeholder: string;
11
- modelValue: string;
12
12
  fonts: any | undefined;
13
13
  toolbar: readonly any[];
14
14
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -6,9 +6,9 @@ declare const _default: import("vue").DefineComponent<LEditorProps, {}, {}, {},
6
6
  }, string, import("vue").PublicProps, Readonly<LEditorProps> & Readonly<{
7
7
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
8
8
  }>, {
9
+ modelValue: string;
9
10
  dense: boolean;
10
11
  placeholder: string;
11
- modelValue: string;
12
12
  fonts: any | undefined;
13
13
  toolbar: readonly any[];
14
14
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -5,15 +5,15 @@ type __VLS_WithSlots<T, S> = T & (new () => {
5
5
  });
6
6
  declare const __VLS_component: import("vue").DefineComponent<{}, {
7
7
  $emit: (event: "submit", ...args: any[]) => void;
8
- cancel: Function;
9
8
  value: Record<string, any>;
9
+ cancel: Function;
10
10
  width: string;
11
11
  title: string;
12
12
  save: Function;
13
13
  showNotification: boolean;
14
14
  $props: {
15
- readonly cancel?: Function | undefined;
16
15
  readonly value?: Record<string, any> | undefined;
16
+ readonly cancel?: Function | undefined;
17
17
  readonly width?: string | undefined;
18
18
  readonly title?: string | undefined;
19
19
  readonly save?: Function | undefined;
@@ -5,15 +5,15 @@ type __VLS_WithSlots<T, S> = T & (new () => {
5
5
  });
6
6
  declare const __VLS_component: import("vue").DefineComponent<{}, {
7
7
  $emit: (event: "submit", ...args: any[]) => void;
8
- cancel: Function;
9
8
  value: Record<string, any>;
9
+ cancel: Function;
10
10
  width: string;
11
11
  title: string;
12
12
  save: Function;
13
13
  showNotification: boolean;
14
14
  $props: {
15
- readonly cancel?: Function | undefined;
16
15
  readonly value?: Record<string, any> | undefined;
16
+ readonly cancel?: Function | undefined;
17
17
  readonly width?: string | undefined;
18
18
  readonly title?: string | undefined;
19
19
  readonly save?: Function | undefined;
@@ -431,17 +431,6 @@ const getCellStyle = (col, row) => {
431
431
  }
432
432
  return style;
433
433
  };
434
- const getCellClass = (col, row) => {
435
- const cl = [];
436
- if (col.cellClass) {
437
- if (typeof col.cellClass == "function") {
438
- cl.push(col.cellClass(row));
439
- } else {
440
- cl.push(col.cellClass);
441
- }
442
- }
443
- return cl;
444
- };
445
434
  const localSelected = computed({
446
435
  get() {
447
436
  return props.selected;
@@ -574,7 +563,7 @@ const hasFilters = computed(() => {
574
563
  </template>
575
564
  <template v-else>
576
565
  <q-td :key="col.name" :props="props" :auto-width="col.autoWidth ?? false"
577
- :style="getCellStyle(col, props.row)" :class="getCellClass(col, props.row)"><template
566
+ :style="getCellStyle(col, props.row)"><template
578
567
  v-if="col.to" class="bg-primary">
579
568
  <l-link :to="col.to(props.row)" v-if="col.to(props.row)">{{ col.value }}</l-link>
580
569
  </template>
@@ -23,8 +23,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
23
23
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
24
24
  "onUpdate:modelValue"?: ((value: any) => any) | undefined;
25
25
  }>, {
26
- format24h: boolean;
27
26
  required: boolean;
27
+ format24h: boolean;
28
28
  mask: string;
29
29
  hideBottomSpace: boolean;
30
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -23,8 +23,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
23
23
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
24
24
  "onUpdate:modelValue"?: ((value: any) => any) | undefined;
25
25
  }>, {
26
- format24h: boolean;
27
26
  required: boolean;
27
+ format24h: boolean;
28
28
  mask: string;
29
29
  hideBottomSpace: boolean;
30
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -224,6 +224,8 @@ declare const light: {
224
224
  isoName: string;
225
225
  nativeName: string;
226
226
  label: {
227
+ create: string;
228
+ set: string;
227
229
  cancel: string;
228
230
  close: string;
229
231
  reset: string;
@@ -231,11 +233,9 @@ declare const light: {
231
233
  filter: string;
232
234
  update: string;
233
235
  remove: string;
234
- set: string;
235
236
  clear: string;
236
237
  ok: string;
237
238
  search: string;
238
- create: string;
239
239
  refresh: string;
240
240
  expand: (label?: string | undefined) => string;
241
241
  collapse: (label?: string | undefined) => string;
@@ -319,9 +319,9 @@ declare const light: {
319
319
  name: string;
320
320
  type: {
321
321
  info: string;
322
- warning: string;
323
- negative: string;
324
322
  positive: string;
323
+ negative: string;
324
+ warning: string;
325
325
  };
326
326
  arrow: {
327
327
  left: string;
@@ -821,6 +821,8 @@ declare const _default: () => {
821
821
  isoName: string;
822
822
  nativeName: string;
823
823
  label: {
824
+ create: string;
825
+ set: string;
824
826
  cancel: string;
825
827
  close: string;
826
828
  reset: string;
@@ -828,11 +830,9 @@ declare const _default: () => {
828
830
  filter: string;
829
831
  update: string;
830
832
  remove: string;
831
- set: string;
832
833
  clear: string;
833
834
  ok: string;
834
835
  search: string;
835
- create: string;
836
836
  refresh: string;
837
837
  expand: (label?: string | undefined) => string;
838
838
  collapse: (label?: string | undefined) => string;
@@ -916,9 +916,9 @@ declare const _default: () => {
916
916
  name: string;
917
917
  type: {
918
918
  info: string;
919
- warning: string;
920
- negative: string;
921
919
  positive: string;
920
+ negative: string;
921
+ warning: string;
922
922
  };
923
923
  arrow: {
924
924
  left: string;
@@ -0,0 +1,149 @@
1
+ <script setup>
2
+ import { ref } from "vue";
3
+ import { q, m, useAsyncData, useQuasar } from "#imports";
4
+ const $q = useQuasar();
5
+ const { data: system, refresh } = await useAsyncData("database-check", async () => {
6
+ const result = await q({
7
+ system: {
8
+ database: {
9
+ checkResult: true
10
+ }
11
+ }
12
+ });
13
+ return result.system;
14
+ });
15
+ const expanded = ref([]);
16
+ const tableColumns = [
17
+ { name: "table", label: "Table", field: "table", align: "left" },
18
+ { name: "status", label: "Status", field: "status", align: "center" },
19
+ { name: "count", label: "Differences", field: (row) => row.differences.length, align: "center" },
20
+ { name: "action", label: "Action", field: "action", align: "center" }
21
+ ];
22
+ const diffColumns = [
23
+ { name: "type", label: "Type", field: "type", align: "left" },
24
+ { name: "column", label: "Column", field: "column", align: "left" },
25
+ { name: "details", label: "Details", field: "details", align: "left" }
26
+ ];
27
+ const getStatusColor = (status) => status === "OK" ? "positive" : "warning";
28
+ const getDiffDetails = (diff) => {
29
+ if (diff.type === "missing_column") {
30
+ return `Missing: ${diff.expected.name} (${diff.expected.type})`;
31
+ }
32
+ if (diff.type === "extra_column") {
33
+ return `Extra: ${diff.current.type}${diff.current.length ? `(${diff.current.length})` : ""}`;
34
+ }
35
+ if (diff.type === "column_mismatch") {
36
+ return Object.entries(diff.differences).map(([key, val]) => `${key}: ${JSON.stringify(val)}`).join(" | ");
37
+ }
38
+ if (diff.current) {
39
+ return JSON.stringify(diff.current).substring(0, 100) + "...";
40
+ }
41
+ return "";
42
+ };
43
+ const getDiffTypeColor = (type) => {
44
+ switch (type) {
45
+ case "missing_column":
46
+ return "negative";
47
+ case "extra_column":
48
+ return "info";
49
+ case "column_mismatch":
50
+ return "warning";
51
+ default:
52
+ return "grey";
53
+ }
54
+ };
55
+ const toggleExpanded = (tableName) => {
56
+ const index = expanded.value.indexOf(tableName);
57
+ if (index === -1) {
58
+ expanded.value.push(tableName);
59
+ } else {
60
+ expanded.value.splice(index, 1);
61
+ }
62
+ };
63
+ const handleFix = async (tableName) => {
64
+ $q.dialog({
65
+ title: "Confirm Fix",
66
+ message: `Are you sure you want to fix the table "${tableName}"? This action cannot be undone.`,
67
+ cancel: true,
68
+ persistent: true
69
+ }).onOk(async () => {
70
+ await m("fixDatabaseTable", { name: tableName });
71
+ await refresh();
72
+ });
73
+ };
74
+ </script>
75
+
76
+ <template>
77
+ <l-page>
78
+
79
+ <div class="q-mb-md">
80
+ <h5 class="q-ma-none">Database Check Results</h5>
81
+ </div>
82
+
83
+ <q-table :rows="system.database.checkResult" :columns="tableColumns" row-key="table" flat bordered
84
+ class="q-mb-lg" v-model:expanded="expanded" :pagination.sync="{ rowsPerPage: 0 }" hide-bottom>
85
+ <template #body="props">
86
+ <q-tr :props="props"
87
+ :class="{ 'bg-red-1': props.row.status === 'DIFFERENT', 'bg-green-1': props.row.status === 'OK' }">
88
+ <q-td auto-width>
89
+ <q-btn size="sm" flat dense round
90
+ :icon="expanded.includes(props.row.table) ? 'expand_less' : 'expand_more'"
91
+ @click="toggleExpanded(props.row.table)" />
92
+ </q-td>
93
+ <q-td key="table" :props="props" class="text-weight-bold">
94
+ {{ props.row.table }}
95
+ </q-td>
96
+ <q-td key="status" :props="props">
97
+ <q-chip :label="props.row.status" :color="getStatusColor(props.row.status)" text-color="white"
98
+ size="sm" />
99
+ </q-td>
100
+ <q-td key="count" :props="props">
101
+ <q-chip v-if="props.row.differences.length > 0" :label="props.row.differences.length"
102
+ color="warning" text-color="white" size="sm" />
103
+ <span v-else class="text-positive">✓</span>
104
+ </q-td>
105
+ <q-td key="action" :props="props">
106
+ <q-btn v-if="props.row.status !== 'OK'" label="Fix" size="sm" :color="$light.color"
107
+ @click="handleFix(props.row.table)" />
108
+ </q-td>
109
+ </q-tr>
110
+
111
+ <!-- Differences Details Expansion -->
112
+ <q-tr v-show="expanded.includes(props.row.table)" :props="props">
113
+ <q-td colspan="100%" class="q-pa-none">
114
+ <div class="q-pa-md bg-grey-1">
115
+ <q-table v-if="props.row.differences.length > 0" :rows="props.row.differences"
116
+ :columns="diffColumns" row-key="column" flat dense class="q-mb-md"
117
+ :pagination.sync="{ rowsPerPage: 0 }" hide-bottom>
118
+ <template #body-cell-type="cellProps">
119
+ <q-td :props="cellProps">
120
+ <q-chip :label="cellProps.row.type"
121
+ :color="getDiffTypeColor(cellProps.row.type)" text-color="white"
122
+ size="sm" />
123
+ </q-td>
124
+ </template>
125
+ <template #body-cell-details="cellProps">
126
+ <q-td :props="cellProps">
127
+ <q-expansion-item header-class="text-caption" expand-icon-class="text-caption"
128
+ dense>
129
+ <template #header>
130
+ <span class="text-caption">{{ getDiffDetails(cellProps.row) }}</span>
131
+ </template>
132
+ <pre class="q-ma-none text-caption">{{
133
+ JSON.stringify(cellProps.row.differences || cellProps.row.current ||
134
+ cellProps.row.expected, null,
135
+ 2) }}
136
+ </pre>
137
+ </q-expansion-item>
138
+ </q-td>
139
+ </template>
140
+ </q-table>
141
+ <div v-else class="text-positive text-weight-bold">✓ No Differences</div>
142
+ </div>
143
+ </q-td>
144
+ </q-tr>
145
+ </template>
146
+ </q-table>
147
+
148
+ </l-page>
149
+ </template>
@@ -15,7 +15,6 @@ watch(selected, async (newSelected) => {
15
15
  const name = newSelected[0].Db + "." + newSelected[0].Name;
16
16
  const event = await getEvent(name);
17
17
  eventDetail.value = event;
18
- console.log("\u53D6\u5F97\u7684\u4E8B\u4EF6\u8CC7\u6599:", event);
19
18
  } else {
20
19
  eventDetail.value = null;
21
20
  }
@@ -40,7 +39,7 @@ const getEvent = async (name) => {
40
39
  <l-page>
41
40
 
42
41
  <q-table :rows="system.database.events" :pagination="{ rowsPerPage: 0 }" v-model:selected="selected"
43
- selection="single" />
42
+ row-key="Name" selection="single" />
44
43
 
45
44
  <!-- 顯示選中的事件詳細內容 -->
46
45
  <div v-if="eventDetail" class="q-mt-md">
@@ -59,7 +58,8 @@ const getEvent = async (name) => {
59
58
  <div><strong>事件名稱:</strong> {{ eventDetail.Event }}</div>
60
59
  <div>
61
60
  <strong>SQL 模式:</strong>
62
- <div class="q-mt-xs text-caption" style="word-break: break-all; line-height: 1.3;">
61
+ <div class="q-mt-xs text-caption"
62
+ style="word-break: break-all; line-height: 1.3;">
63
63
  {{ eventDetail.sql_mode }}
64
64
  </div>
65
65
  </div>
@@ -76,7 +76,8 @@ const getEvent = async (name) => {
76
76
  <q-card-section>
77
77
  <div class="text-subtitle1 text-weight-bold">事件定義</div>
78
78
  <q-separator class="q-my-sm" />
79
- <pre class="q-pa-sm bg-grey-1" style="white-space: pre-wrap; font-size: 12px;">{{ eventDetail['Create Event'] }}</pre>
79
+ <pre class="q-pa-sm bg-grey-1" style="white-space: pre-wrap; font-size: 12px;">{{
80
+ eventDetail['Create Event'] }}</pre>
80
81
  </q-card-section>
81
82
  </q-card>
82
83
  </div>
@@ -64,11 +64,10 @@ const removeField = async (table) => {
64
64
  ok: "Yes",
65
65
  cancel: "No"
66
66
  }).onOk(async () => {
67
- const fields = selected[table].map((field) => field.Field);
68
67
  try {
69
68
  await m("lightDatabaseRemoveFields", {
70
69
  table,
71
- fields
70
+ fields: selected[table].map((field) => field.name)
72
71
  });
73
72
  light.notify({
74
73
  type: "positive",
@@ -218,7 +217,7 @@ const truncatTable = async () => {
218
217
  <q-list separator bordered>
219
218
  <q-expansion-item :label="table.name" v-for="table in data.table" dense>
220
219
  <div class="q-ma-sm">
221
- <q-table row-key="Field" :rows="table.columns" :rows-per-page-options="[0]" hide-pagination flat
220
+ <q-table row-key="name" :rows="table.columns" :rows-per-page-options="[0]" hide-pagination flat
222
221
  bordered selection="multiple" v-model:selected="selected[table.name]" :color="$light.color">
223
222
  <template #top-left>
224
223
  <q-btn icon="sym_o_add" @click="add(table.name)" round flat size="sm">