@hostlink/nuxt-light 1.13.6 → 1.14.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 (68) hide show
  1. package/dist/module.json +5 -1
  2. package/dist/runtime/components/l-app-main.vue +14 -11
  3. package/dist/runtime/components/l-bar.vue +21 -0
  4. package/dist/runtime/components/l-btn.vue +2 -2
  5. package/dist/runtime/components/l-card.vue +1 -1
  6. package/dist/runtime/components/l-checkbox.vue +1 -1
  7. package/dist/runtime/components/l-customizer.vue +21 -7
  8. package/dist/runtime/components/l-dialog-database-field-add.vue +61 -0
  9. package/dist/runtime/components/l-editor.vue +1 -1
  10. package/dist/runtime/components/l-form.vue +21 -5
  11. package/dist/runtime/components/l-input.vue +1 -1
  12. package/dist/runtime/components/l-item.vue +1 -1
  13. package/dist/runtime/components/l-list.vue +1 -1
  14. package/dist/runtime/components/l-login.vue +54 -72
  15. package/dist/runtime/components/l-page.vue +16 -2
  16. package/dist/runtime/components/l-select.vue +1 -1
  17. package/dist/runtime/components/l-table.vue +2 -1
  18. package/dist/runtime/components/l-tabs.vue +1 -1
  19. package/dist/runtime/formkit/Form.vue +22 -9
  20. package/dist/runtime/index.d.ts +3 -3
  21. package/dist/runtime/{index.mjs → index.js} +2 -2
  22. package/dist/runtime/lib/{SystemValue.mjs → SystemValue.js} +2 -2
  23. package/dist/runtime/lib/defineLightModel.d.ts +1 -1
  24. package/dist/runtime/lib/{defineLightModel.mjs → defineLightModel.js} +1 -1
  25. package/dist/runtime/lib/{f.mjs → f.js} +1 -1
  26. package/dist/runtime/lib/{getApiUrl.mjs → getApiUrl.js} +1 -1
  27. package/dist/runtime/lib/{getCurrentUser.mjs → getCurrentUser.js} +1 -1
  28. package/dist/runtime/lib/{getGQLFields.mjs → getGQLFields.js} +1 -1
  29. package/dist/runtime/lib/{getID.mjs → getID.js} +1 -1
  30. package/dist/runtime/lib/{getModelColumns.mjs → getModelColumns.js} +1 -1
  31. package/dist/runtime/lib/{getModelField.mjs → getModelField.js} +1 -1
  32. package/dist/runtime/lib/{getModelFields.mjs → getModelFields.js} +1 -1
  33. package/dist/runtime/lib/{getObject.mjs → getObject.js} +2 -2
  34. package/dist/runtime/lib/index.d.ts +23 -23
  35. package/dist/runtime/lib/index.js +35 -0
  36. package/dist/runtime/lib/{list.mjs → list.js} +1 -1
  37. package/dist/runtime/lib/{listObject.mjs → listObject.js} +1 -1
  38. package/dist/runtime/lib/{loadObject.mjs → loadObject.js} +1 -1
  39. package/dist/runtime/lib/{m.mjs → m.js} +1 -1
  40. package/dist/runtime/lib/model.d.ts +2 -2
  41. package/dist/runtime/lib/{model.mjs → model.js} +1 -1
  42. package/dist/runtime/lib/{q.mjs → q.js} +2 -2
  43. package/dist/runtime/lib/{sv.mjs → sv.js} +1 -1
  44. package/dist/runtime/pages/System/database/table.vue +125 -6
  45. package/dist/runtime/pages/System/view_as.vue +12 -8
  46. package/dist/runtime/pages/User/_user_id/edit.vue +3 -3
  47. package/dist/runtime/pages/User/index.vue +2 -0
  48. package/dist/runtime/pages/User/profile.vue +4 -12
  49. package/dist/runtime/pages/User/setting/open_id.vue +6 -10
  50. package/dist/runtime/pages/User/setting.vue +1 -1
  51. package/dist/runtime/plugin.d.ts +2 -2
  52. package/dist/runtime/{plugin.mjs → plugin.js} +8 -8
  53. package/dist/types.d.mts +1 -16
  54. package/dist/types.d.ts +1 -16
  55. package/package.json +59 -60
  56. package/dist/runtime/lib/index.mjs +0 -35
  57. /package/dist/runtime/formkit/{index.mjs → index.js} +0 -0
  58. /package/dist/runtime/lib/{GQLFieldBuilder.mjs → GQLFieldBuilder.js} +0 -0
  59. /package/dist/runtime/lib/{api.mjs → api.js} +0 -0
  60. /package/dist/runtime/lib/{isGranted.mjs → isGranted.js} +0 -0
  61. /package/dist/runtime/lib/{t.mjs → t.js} +0 -0
  62. /package/dist/runtime/lib/{tc2sc.mjs → tc2sc.js} +0 -0
  63. /package/dist/runtime/lib/{toJson.mjs → toJson.js} +0 -0
  64. /package/dist/runtime/types/{EventLog.mjs → EventLog.js} +0 -0
  65. /package/dist/runtime/types/{MailLog.mjs → MailLog.js} +0 -0
  66. /package/dist/runtime/types/{SystemValue.mjs → SystemValue.js} +0 -0
  67. /package/dist/runtime/types/{User.mjs → User.js} +0 -0
  68. /package/dist/runtime/types/{UserLog.mjs → UserLog.js} +0 -0
package/dist/module.json CHANGED
@@ -1,5 +1,9 @@
1
1
  {
2
2
  "name": "light",
3
3
  "configKey": "light",
4
- "version": "1.13.6"
4
+ "version": "1.14.0",
5
+ "builder": {
6
+ "@nuxt/module-builder": "0.8.3",
7
+ "unbuild": "2.0.0"
8
+ }
5
9
  }
@@ -1,18 +1,18 @@
1
1
  <script setup>
2
2
  import { useRoute, useRouter } from 'vue-router';
3
3
  import { useLight, q, m } from "#imports";
4
- import { useQuasar, Loading } from 'quasar';
4
+ import { useQuasar } from 'quasar';
5
5
  import { useI18n } from 'vue-i18n';
6
6
  import { ref, computed, reactive, provide, watch, toRaw } from 'vue';
7
7
  import { useRuntimeConfig } from 'nuxt/app';
8
8
 
9
- Loading.show()
9
+ const $q = useQuasar();
10
+ $q.loading.show()
10
11
 
11
12
  const config = useRuntimeConfig();
12
13
 
13
14
  const appVersion = config.public.appVersion ?? '0.0.1';
14
15
 
15
- const quasar = useQuasar();
16
16
  const tt = await q({
17
17
  system: {
18
18
  devMode: true,
@@ -74,7 +74,7 @@ const myFavoritesCount = computed(() => {
74
74
  return light.getMyFavorites().length;
75
75
  });
76
76
 
77
- quasar.dark.set(light.isDarkMode());
77
+ $q.dark.set(light.isDarkMode());
78
78
 
79
79
  const i18n = useI18n();
80
80
  i18n.locale = my.language || 'en';
@@ -172,7 +172,7 @@ watch(() => style.dense, async (value) => await light.setStyle("dense", value))
172
172
 
173
173
 
174
174
  watch(() => light.theme, async () => {
175
- quasar.dark.set(light.isDarkMode());
175
+ $q.dark.set(light.isDarkMode());
176
176
  })
177
177
 
178
178
  watch(() => style.miniState, async (value) => {
@@ -228,7 +228,7 @@ const onToggleFav = async () => {
228
228
  return;
229
229
  }
230
230
 
231
- quasar.dialog({
231
+ $q.dialog({
232
232
  title: 'Add to favorite',
233
233
  message: 'Enter favorite label',
234
234
  prompt: {
@@ -257,7 +257,7 @@ const isFav = computed(() => {
257
257
  return fav;
258
258
  })
259
259
 
260
- Loading.hide()
260
+ $q.loading.hide()
261
261
 
262
262
  const menuWidth = ref(my.styles.menuWidth || 280);
263
263
 
@@ -306,7 +306,7 @@ if (route.fullPath == "/" && my.default_page) {
306
306
  </q-tooltip>
307
307
  </q-btn>
308
308
 
309
- <q-btn v-if="languages.length > 1" round flat icon="language" class="q-mr-xs">
309
+ <q-btn v-if="languages.length > 1" round flat dense icon="language" class="q-mr-xs">
310
310
  <q-tooltip>
311
311
  {{ my.language }}
312
312
  </q-tooltip>
@@ -334,8 +334,11 @@ if (route.fullPath == "/" && my.default_page) {
334
334
  {{ my.first_name }} {{ my.last_name }}
335
335
  </div>
336
336
 
337
- <div class="text-right">
338
- {{ my.roles[0] }}
337
+ <div class="text-right ellipsis" style="max-width: 120px;">
338
+ {{ my.roles.join(", ") }}
339
+ <q-tooltip>
340
+ {{ my.roles.join(", ") }}
341
+ </q-tooltip>
339
342
  </div>
340
343
  </div>
341
344
 
@@ -430,7 +433,7 @@ if (route.fullPath == "/" && my.default_page) {
430
433
  </template>
431
434
  </router-view -->
432
435
  <NuxtLoadingIndicator />
433
-
436
+
434
437
  <NuxtPage />
435
438
 
436
439
 
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import { useLight } from '#imports';
3
+ import type { QBarProps } from 'quasar';
4
+ import { computed } from 'vue';
5
+
6
+ export type LBarProps = QBarProps;
7
+
8
+ const light = useLight();
9
+ const barClass = computed(() => {
10
+ const c = ["text-white"];
11
+ const color = light.color;
12
+ c.push(`bg-${color}`);
13
+ return c;
14
+ });
15
+ </script>
16
+
17
+ <template>
18
+ <q-bar :class="barClass">
19
+ <slot></slot>
20
+ </q-bar>
21
+ </template>
@@ -1,10 +1,10 @@
1
1
  <script setup lang="ts">
2
2
  import { type QBtnProps } from "quasar";
3
- import { computed, inject, unref, toRaw } from "vue";
3
+ import { computed } from "vue";
4
4
  import { useLight } from '#imports';
5
5
  import { useI18n } from "vue-i18n";
6
6
 
7
- export interface LBtnProps extends QBtnProps {
7
+ export interface LBtnProps extends QBtnProps {
8
8
  permission?: string;
9
9
  }
10
10
 
@@ -8,7 +8,7 @@ const emit = defineEmits(["close"]);
8
8
  const minimized = defineModel<boolean>("minimized", { default: false })
9
9
  const maximized = defineModel<boolean>("maximized", { default: false })
10
10
 
11
- export interface LCardProps extends QCardProps {
11
+ export interface LCardProps extends QCardProps {
12
12
  loading?: boolean;
13
13
  title?: string;
14
14
  /**
@@ -2,7 +2,7 @@
2
2
  import { computed } from "vue"
3
3
  import { type QCheckboxProps } from "quasar"
4
4
 
5
- export interface LCheckboxProps extends QCheckboxProps {
5
+ export interface LCheckboxProps extends QCheckboxProps {
6
6
  }
7
7
 
8
8
  const emit = defineEmits(["update:modelValue"]);
@@ -75,11 +75,24 @@ const props = defineProps({
75
75
  const time_diff = ref(new Date().getTime() - new Date(props.time).getTime());
76
76
  const server_time = ref(new Date(props.time).toLocaleTimeString());
77
77
  const server_date = ref(new Date(props.time).toLocaleDateString());
78
+ let start;
78
79
 
79
- setInterval(() => {
80
- server_time.value = new Date(new Date().getTime() - time_diff.value).toLocaleTimeString();
81
- server_date.value = new Date(new Date().getTime() - time_diff.value).toLocaleDateString();
82
- }, 500);
80
+ const refreshServerTime = (timestamp) => {
81
+ if (!start) start = timestamp;
82
+ let elapsed = timestamp - start;
83
+
84
+
85
+ if (elapsed > 1000) {
86
+ server_time.value = new Date(new Date().getTime() - time_diff.value).toLocaleTimeString();
87
+ server_date.value = new Date(new Date().getTime() - time_diff.value).toLocaleDateString();
88
+ start = timestamp;
89
+ }
90
+
91
+ //refresh every second
92
+ requestAnimationFrame(refreshServerTime);
93
+ }
94
+
95
+ requestAnimationFrame(refreshServerTime);
83
96
 
84
97
 
85
98
  </script>
@@ -132,7 +145,8 @@ setInterval(() => {
132
145
  <q-item-label>Menu dense mode</q-item-label>
133
146
  </q-item-section>
134
147
  <q-item-section side>
135
- <q-toggle :model-value="dense" @update:model-value="$emit('update:dense', $event)" :color="$light.color" />
148
+ <q-toggle :model-value="dense" @update:model-value="$emit('update:dense', $event)"
149
+ :color="$light.color" />
136
150
  </q-item-section>
137
151
  </q-item>
138
152
 
@@ -143,8 +157,8 @@ setInterval(() => {
143
157
  <q-item-label>Menu overlay header</q-item-label>
144
158
  </q-item-section>
145
159
  <q-item-section side>
146
- <q-toggle :model-value="menuOverlayHeader" @update:model-value="$emit('update:menuOverlayHeader', $event)"
147
- :color="$light.color" />
160
+ <q-toggle :model-value="menuOverlayHeader"
161
+ @update:model-value="$emit('update:menuOverlayHeader', $event)" :color="$light.color" />
148
162
  </q-item-section>
149
163
  </q-item>
150
164
 
@@ -0,0 +1,61 @@
1
+ <script setup>
2
+ import { useDialogPluginComponent } from 'quasar'
3
+
4
+ const props = defineProps({
5
+ // ...your custom props
6
+ })
7
+
8
+ defineEmits([
9
+ // REQUIRED; need to specify some events that your
10
+ // component will emit through useDialogPluginComponent()
11
+ ...useDialogPluginComponent.emits
12
+ ])
13
+
14
+ const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
15
+ // dialogRef - Vue ref to be applied to QDialog
16
+ // onDialogHide - Function to be used as handler for @hide on QDialog
17
+ // onDialogOK - Function to call to settle dialog with "ok" outcome
18
+ // example: onDialogOK() - no payload
19
+ // example: onDialogOK({ /*...*/ }) - with payload
20
+ // onDialogCancel - Function to call to settle dialog with "cancel" outcome
21
+
22
+ // this is part of our example (so not required)
23
+ function onOKClick(value) {
24
+ // on OK, it is REQUIRED to
25
+ // call onDialogOK (with optional payload)
26
+ onDialogOK(value)
27
+ // or with payload: onDialogOK({ ... })
28
+ // ...and it will also hide the dialog automatically
29
+ }
30
+
31
+ const types = ["varchar", "int", "date", "time", "datetime", "timestamp", "text", "blob", "json", "jsonb", "uuid", "boolean", "decimal", "float", "double", "real", "numeric", "smallint", "bigint", "tinyint", "mediumint", "char", "binary", "varbinary", "enum"]
32
+ </script>
33
+
34
+
35
+ <template>
36
+ <q-dialog ref="dialogRef" @hide="onDialogHide">
37
+ <q-card class="q-dialog-plugin">
38
+ <l-bar>
39
+ <q-space />
40
+ <q-btn dense flat icon="sym_o_close" @click="onDialogCancel" />
41
+ </l-bar>
42
+ <form-kit type="l-form" @submit="onOKClick" :value="{
43
+ name: '',
44
+ type: '',
45
+ length: '',
46
+ default: '',
47
+ nullable: false,
48
+ autoincrement: false
49
+ }">
50
+ <form-kit type="l-input" name="name" label="Name" validation="required" />
51
+ <form-kit type="l-select" name="type" label="Type" :options="types" validation="required" />
52
+ <form-kit type="l-input" name="length" label="Length" />
53
+ <form-kit type="l-input" name="default" label="Default" />
54
+ <form-kit type="l-checkbox" name="nullable" label="Nullable" />
55
+ <form-kit type="l-checkbox" name="autoincrement" label="Autoincrement" />
56
+ </form-kit>
57
+
58
+
59
+ </q-card>
60
+ </q-dialog>
61
+ </template>
@@ -27,7 +27,7 @@ const TextHightlightCMD = ((cmd, name) => {
27
27
  edit.focus()
28
28
  })
29
29
 
30
- export interface LEditorProps extends QEditorProps {
30
+ export interface LEditorProps extends QEditorProps {
31
31
  }
32
32
 
33
33
  const emit = defineEmits(["update:modelValue"]);
@@ -1,4 +1,4 @@
1
- <script setup>
1
+ <script setup lang="ts">
2
2
  import { ref } from "vue";
3
3
  import { useRouter, useRoute } from "vue-router";
4
4
  import { useQuasar } from "quasar";
@@ -28,12 +28,17 @@ const props = defineProps({
28
28
  submitIcon: {
29
29
  type: String,
30
30
  default: "sym_o_save"
31
+ },
32
+ noRedirect: {
33
+ type: Boolean,
34
+ default: false
31
35
  }
36
+
32
37
  });
33
38
 
34
39
  const loading = ref(false)
35
40
 
36
- const emit = defineEmits(["save", "submit"]);
41
+ const emit = defineEmits(["save", "submit", "submitted"]);
37
42
  const save = async () => {
38
43
 
39
44
  let valid = await form.value.validate();
@@ -50,12 +55,23 @@ const save = async () => {
50
55
  try {
51
56
  if (route.params[id_name]) {//edit
52
57
  if (await model(module).update(parseInt(route.params[id_name]), props.modelValue)) {
53
- router.push(`/${module}`);
58
+
59
+ if (!props.noRedirect) {
60
+ router.push(`/${module}`);
61
+ }
62
+
63
+ emit('submitted');
64
+
54
65
  return;
55
66
  }
56
67
  } else {
57
68
  if (await model(module).add(props.modelValue)) {
58
- router.push(`/${module}`);
69
+
70
+ if (!props.noRedirect) {
71
+ router.push(`/${module}`);
72
+ }
73
+
74
+ emit('submitted');
59
75
  return;
60
76
  }
61
77
  }
@@ -78,7 +94,7 @@ const onSubmit = (e) => {
78
94
  </script>
79
95
  <template>
80
96
  <q-form ref="form" @submit="onSubmit">
81
- <l-card :bordered="bordered" >
97
+ <l-card :bordered="bordered">
82
98
  <q-card-section>
83
99
  <div :class="`q-gutter-${gutter}`">
84
100
  <slot></slot>
@@ -5,7 +5,7 @@ import tc2sc from "../lib/tc2sc";
5
5
  import { useLight } from '#imports';
6
6
 
7
7
  import type { QInputProps } from "quasar";
8
- export interface LInputProps extends QInputProps {
8
+ export interface LInputProps extends QInputProps {
9
9
  showPassword?: boolean;
10
10
  translate?: boolean;
11
11
  required?: boolean;
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import type { QItemProps } from 'quasar';
3
3
 
4
- export interface LItemProps extends QItemProps {
4
+ export interface LItemProps extends QItemProps {
5
5
  label?: string;
6
6
  type?: 'text' | 'caption';
7
7
  name?: string;
@@ -2,7 +2,7 @@
2
2
 
3
3
  import type { QListProps } from 'quasar';
4
4
 
5
- export interface LListProps extends QListProps {
5
+ export interface LListProps extends QListProps {
6
6
  fields?: any[];
7
7
  modelValue?: any;
8
8
  }
@@ -1,12 +1,11 @@
1
1
  <script setup>
2
2
  import { useLight } from "#imports";
3
3
  import { ref, reactive, onMounted } from 'vue'
4
- import { useQuasar, Dialog } from 'quasar';
4
+ import { useQuasar } from 'quasar';
5
5
  import { useI18n } from 'vue-i18n';
6
6
  import { m, notify, api } from '#imports';
7
7
 
8
8
 
9
-
10
9
  const light = useLight();
11
10
 
12
11
  const props = defineProps({
@@ -20,7 +19,7 @@ const data = reactive({
20
19
  username: "", password: "", code: ""
21
20
  });
22
21
 
23
- const qua = useQuasar()
22
+ const $q = useQuasar()
24
23
 
25
24
  const submit = async () => {
26
25
  if (await form1.value.validate()) {
@@ -36,83 +35,70 @@ const submit = async () => {
36
35
  }
37
36
 
38
37
  const forgetPassword = async () => {
39
- Dialog.create({
38
+ $q.dialog({
40
39
  title: i18n.t("Forget password"),
41
40
  message: "Please enter your email address, we will send you a code to reset your password",
42
41
  prompt: {
43
- model: "",
44
42
  type: "email",
43
+ required: true,
44
+ isValid: (val) => {
45
+ //test val is email
46
+ const re = /\S+@\S+\.\S+/;
47
+ return re.test(val);
48
+ }
45
49
  },
46
50
  cancel: true
47
51
  }).onOk(async email => {
48
- if (email.length == 0) {
49
- return;
50
- }
51
-
52
+ $q.loading.show();
52
53
  try {
53
- await m("forgetPassword", { email: email });
54
- qua.dialog({
55
- title: "Enter your code",
56
- message: "Please enter the code sent to your email, your code will expire in 10 minutes",
57
- prompt: {
58
- model: "",
59
- type: "text"
60
- },
61
- cancel: true,
62
- persistent: true
63
- }).onOk(async code => {
64
- if (code.length == 0) {
65
- return;
66
- }
67
-
68
- if (await m("verifyCode", { code: code, email: email })) {
69
- qua.dialog({
70
- title: "Reset password",
71
- message: "Please enter your new password",
72
- prompt: {
73
- model: "",
74
- type: "password"
75
- },
76
- }).onOk(async password => {
77
- if (password.length == 0) {
78
- return;
79
- }
80
-
81
- if (await m("resetPassword", { password: password, email: email, code: code })) {
82
- qua.notify({
83
- message: "Your password has been reset successfully",
84
- color: "positive",
85
- icon: "sym_o_check",
86
- position: "top",
87
- timeout: 2000
88
- });
89
- }
90
- });
91
- } else {
92
- qua.notify({
93
- message: "Your code is invalid",
94
- color: "negative",
95
- icon: "sym_o_error",
96
- position: "top",
97
- timeout: 2000
98
- });
99
-
100
- }
101
-
102
-
103
- });
54
+ await api.auth.forgetPassword(email);
104
55
  } catch (e) {
105
- qua.notify({
56
+ $q.notify({
106
57
  message: e.message,
107
58
  color: "negative",
108
59
  icon: "sym_o_error",
109
- position: "top",
110
- timeout: 2000
111
60
  });
61
+ return;
62
+ } finally {
63
+ $q.loading.hide();
112
64
  }
113
- });
114
-
115
65
 
66
+ $q.dialog({
67
+ title: "Enter your code",
68
+ message: "Please enter the code sent to your email, your code will expire in 10 minutes",
69
+ prompt: {
70
+ type: "text",
71
+ required: true
72
+ },
73
+ cancel: true,
74
+ persistent: true
75
+ }).onOk(async code => {
76
+ if (await api.auth.verifyCode(email, code)) {
77
+ $q.dialog({
78
+ title: "Reset password",
79
+ message: "Please enter your new password",
80
+ required: true,
81
+ prompt: {
82
+ type: "password"
83
+ },
84
+ }).onOk(async password => {
85
+ if (await api.auth.resetPassword(email, password, code)) {
86
+ $q.notify({
87
+ message: "Your password has been reset successfully",
88
+ color: "positive",
89
+ icon: "sym_o_check",
90
+ });
91
+ }
92
+ });
93
+ } else {
94
+ $q.notify({
95
+ message: "Your code is invalid",
96
+ color: "negative",
97
+ icon: "sym_o_error",
98
+ });
99
+ }
100
+ });
101
+ });
116
102
  };
117
103
 
118
104
  const hasBioLogin = ref(false);
@@ -122,7 +108,7 @@ if (localStorage.getItem("username")) {
122
108
  }
123
109
  const bioLogin = async () => {
124
110
  try {
125
- await webauthnLogin(localStorage.getItem("username"));
111
+ await api.auth.WebAuthn.login(localStorage.getItem("username"));
126
112
  window.self.location.reload();
127
113
  } catch (e) {
128
114
  notify(e.message, "negative");
@@ -131,7 +117,7 @@ const bioLogin = async () => {
131
117
  }
132
118
  const handleGoogleCredentialResponse = async (response) => {
133
119
  try {
134
- await m("googleLogin", { credential: response.credential });
120
+ await api.auth.googleLogin(response.credential);
135
121
  window.self.location.reload();
136
122
  } catch (e) {
137
123
  notify(e.message, "negative");
@@ -140,15 +126,11 @@ const handleGoogleCredentialResponse = async (response) => {
140
126
 
141
127
  onMounted(() => {
142
128
  if (props.googleClientId) {
143
-
144
-
145
129
  if (!window.google) {
146
- qua.notify({
130
+ $q.notify({
147
131
  message: "Google login is not available", //set script https://accounts.google.com/gsi/client in nuuxt.config.js
148
132
  color: "negative",
149
133
  icon: "sym_o_error",
150
- position: "top",
151
- timeout: 2000
152
134
  });
153
135
  return;
154
136
 
@@ -9,17 +9,20 @@ const router = useRouter();
9
9
  const route = useRoute();
10
10
  const light = useLight();
11
11
 
12
- export interface LPageProps extends QPageProps {
12
+ export type LPageProps = QPageProps & {
13
13
  title?: string;
14
14
  backBtn?: boolean;
15
15
  editBtn?: boolean;
16
16
  deleteBtn?: boolean;
17
17
  addBtn?: boolean;
18
+ gutter?: string;
19
+ padding?: boolean
18
20
  }
19
21
 
20
22
  const props = withDefaults(defineProps<LPageProps>(), {
21
23
  title: "",
22
24
  backBtn: true,
25
+ padding: true,
23
26
  });
24
27
 
25
28
  const showToolbar = computed(() => {
@@ -49,10 +52,21 @@ const onDelete = async () => {
49
52
  useHead({
50
53
  title: light.getCompany() + " - " + title,
51
54
  })
55
+
56
+ const localClass = computed(() => {
57
+ return {
58
+ "q-gutter-none": props.gutter === "none",
59
+ "q-gutter-xs": props.gutter === "xs",
60
+ "q-gutter-sm": props.gutter === "sm",
61
+ "q-gutter-md": props.gutter === "md",
62
+ "q-gutter-lg": props.gutter === "lg",
63
+ "q-gutter-xl": props.gutter === "xl",
64
+ }
65
+ })
52
66
  </script>
53
67
 
54
68
  <template>
55
- <q-page padding>
69
+ <q-page :padding="props.padding" :class="localClass">
56
70
  <!-- q-breadcrumbs>
57
71
  <q-breadcrumbs-el icon="home" to="/" />
58
72
  <q-breadcrumbs-el label="Permission" to="/Permission" />
@@ -8,7 +8,7 @@ const emits = defineEmits(["update:modelValue"]);
8
8
 
9
9
  const { t } = useI18n();
10
10
  const light = useLight();
11
- interface LSelectProps extends QSelectProps {
11
+ interface LSelectProps extends QSelectProps {
12
12
  required?: boolean,
13
13
  }
14
14
 
@@ -428,9 +428,10 @@ const onDelete = async (id: any) => {
428
428
  table.value.requestServerInteraction();
429
429
  }
430
430
  }
431
-
432
431
  const attrs = computed(() => {
433
432
  return {
433
+ ...props,
434
+
434
435
  ...{
435
436
  dense: light.getStyle("tableDense"),
436
437
  flat: light.getStyle("tableFlat"),
@@ -2,7 +2,7 @@
2
2
  import type { QTabsProps } from 'quasar';
3
3
  import { onMounted, useSlots } from '#imports';
4
4
  const model = defineModel<string | number | null | undefined>()
5
- export interface LTabsProps extends QTabsProps {
5
+ export interface LTabsProps extends QTabsProps {
6
6
  }
7
7
  defineProps<LTabsProps>();
8
8
  const slots = useSlots()