@hostlink/nuxt-light 0.0.98 → 0.0.99

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,5 +1,5 @@
1
1
  {
2
2
  "name": "light",
3
3
  "configKey": "light",
4
- "version": "0.0.98"
4
+ "version": "0.0.99"
5
5
  }
@@ -2,7 +2,7 @@
2
2
  import { useLight } from "#imports";
3
3
  import { useQuasar } from 'quasar';
4
4
  import { useI18n } from 'vue-i18n';
5
- import { q, getCurrentUser, m, f } from '../';
5
+ import { q, m, f } from '../';
6
6
  import { ref, computed, reactive, provide, watch } from 'vue';
7
7
  import { useRuntimeConfig } from 'nuxt/app';
8
8
 
@@ -15,39 +15,37 @@ const config = useRuntimeConfig();
15
15
  const appVersion = config.public.appVersion ?? '0.0.1';
16
16
 
17
17
  const quasar = useQuasar();
18
- quasar.dark.set(false);
19
- const light = useLight();
20
-
21
18
  const tt = await q({
22
19
  app: ["menus", "viewAsMode", "languages", { i18nMessages: ["name", "value"] }],
23
- my: ["styles", "language", f('granted_storage:granted', { right: "system.storage" }, [])],
20
+ my: ['username', 'first_name', 'last_name', 'roles', "styles", "language", f('granted_storage:granted', { right: "system.storage" }, [])],
24
21
  })
25
22
 
26
-
27
23
  let app = tt.app
28
24
  let my = tt.my
29
- let system = null
30
- if (my.granted_storage) {
31
- system = await q("system", ["diskFreeSpace", "diskUsageSpace", "diskTotalSpace", "diskFreeSpacePercent"]);
32
- }
33
-
34
- light.setStyles(my.styles);
35
25
 
26
+ const light = useLight();
27
+ light.init(my.styles);
36
28
 
37
- const menus = ref(app.menus)
29
+ quasar.dark.set(light.isDarkMode());
38
30
 
39
31
  const i18n = useI18n();
40
32
  i18n.locale = my.language || 'en';
41
33
 
42
- let messages = i18n.messages.value[i18n.locale];
34
+ let system = null
35
+ if (my.granted_storage) {
36
+ system = await q("system", ["diskFreeSpace", "diskUsageSpace", "diskTotalSpace", "diskFreeSpacePercent"]);
37
+ }
43
38
 
39
+ // message
40
+ let messages = i18n.messages.value[i18n.locale];
44
41
  for (let t of app.i18nMessages) {
45
42
  messages[t.name] = t.value;
46
43
  }
47
-
48
44
  i18n.setLocaleMessage(i18n.locale, messages);
49
45
 
50
- const user = ref(await getCurrentUser());
46
+ //menu
47
+ const menus = ref(app.menus)
48
+
51
49
 
52
50
  const leftDrawerOpen = ref(false)
53
51
  const rightDrawerOpen = ref(false)
@@ -61,7 +59,7 @@ const toggleRightDrawer = () => {
61
59
  }
62
60
 
63
61
  let showViewAs = false;
64
- if (user.value && user.value.roles.indexOf('Administrators') != -1) {
62
+ if (my && my.roles.indexOf('Administrators') != -1) {
65
63
  showViewAs = true;
66
64
  }
67
65
 
@@ -74,10 +72,9 @@ const layoutView = computed(() => {
74
72
  })
75
73
 
76
74
  const style = reactive({
77
- color: my.styles?.color || 'bg-primary',
78
- theme: my.styles?.theme || 'semi-dark',
79
75
  miniState: my.styles?.miniState || false,
80
- dense: my.styles?.dense || false
76
+ dense: my.styles?.dense || false,
77
+ footer: my.styles?.footer || false
81
78
  });
82
79
 
83
80
  const isMouseOnDrawer = ref(false)
@@ -93,10 +90,11 @@ const isMini = computed(() => {
93
90
  })
94
91
 
95
92
  const menuDark = computed(() => {
96
- if (style.theme == 'dark') {
93
+
94
+ if (light.theme == 'dark') {
97
95
  return true
98
96
  }
99
- if (style.theme == 'semi-dark') {
97
+ if (light.theme == 'semi-dark') {
100
98
  return true
101
99
  }
102
100
  return false
@@ -123,29 +121,12 @@ const reloadMenu = async () => {
123
121
 
124
122
  provide('reloadMenu', reloadMenu)
125
123
 
124
+ watch(() => style.footer, async (value) => await light.setStyle("footer", value))
125
+ watch(() => style.dense, async (value) => await light.setStyle("dense", value))
126
126
 
127
- watch(() => style.dense, async (value) => {
128
- await m("updateMyStyle", {
129
- name: "dense",
130
- value: value
131
- });
132
- })
133
-
134
- watch(() => style.color, async (value) => {
135
- await m("updateMyStyle", {
136
- name: "color",
137
- value: value
138
- })
139
127
 
140
- my.styles["color"] = value;
141
- light.setStyles(my.styles);
142
- })
143
-
144
- watch(() => style.theme, async (value) => {
145
- await m("updateMyStyle", {
146
- name: "theme",
147
- value: value
148
- })
128
+ watch(() => light.theme, async () => {
129
+ quasar.dark.set(light.isDarkMode());
149
130
  })
150
131
 
151
132
  watch(() => style.miniState, async (value) => {
@@ -190,11 +171,24 @@ const storageUsagePercent = computed(() => {
190
171
  return 0;
191
172
  })
192
173
 
174
+ const containerClass = computed(() => {
175
+ return (light.theme == 'dark') ? {} : { 'bg-grey-2': true }
176
+ })
177
+
178
+ const containerStyle = computed(() => {
179
+ if (light.theme == 'dark') {
180
+ return {};
181
+ }
182
+ return {
183
+ color: '#1f1f1f'
184
+ }
185
+ })
186
+
193
187
  </script>
194
188
 
195
189
  <template>
196
190
  <q-layout :view="layoutView">
197
- <q-header bordered class="text-white" :class="`bg-${style.color}`">
191
+ <q-header bordered class="text-white" :class="`bg-${light.color}`">
198
192
  <q-toolbar>
199
193
  <q-btn dense flat round icon="menu" class="q-mr-sm" @click="toggleLeftDrawer" />
200
194
 
@@ -218,7 +212,7 @@ const storageUsagePercent = computed(() => {
218
212
  </q-btn>
219
213
 
220
214
  <q-btn icon="sym_o_storage" flat round dense class="q-mr-sm" v-if="my.granted_storage"
221
- :color="storageColor">
215
+ :color="storageColor" >
222
216
  <q-menu>
223
217
  <q-card style="width:250px">
224
218
  <q-card-section>
@@ -234,13 +228,13 @@ const storageUsagePercent = computed(() => {
234
228
 
235
229
  </q-btn>
236
230
 
237
- <div class="q-mx-sm" v-if="$q.platform.is.desktop">
231
+ <div class="q-mx-sm" v-if="$q.screen.gt.xs">
238
232
  <div class="text-bold text-right">
239
- {{ user.first_name }} {{ user.last_name }}
233
+ {{ my.first_name }} {{ my.last_name }}
240
234
  </div>
241
235
 
242
236
  <div class="text-right">
243
- {{ user.roles[0] }}
237
+ {{ my.roles[0] }}
244
238
  </div>
245
239
  </div>
246
240
 
@@ -303,13 +297,14 @@ const storageUsagePercent = computed(() => {
303
297
  <q-drawer overlay v-model="rightDrawerOpen" side="right" bordered>
304
298
  <!-- drawer content -->
305
299
  <q-scroll-area class="fit">
306
- <l-customizer v-model:headerColor="style.color" v-model:theme="style.theme"
307
- v-model:miniState="style.miniState" v-model:dense="style.dense"
308
- v-model:menuOverlayHeader="style.menuOverlayHeader" />
300
+ <l-customizer v-model:color="light.color" v-model:theme="light.theme" v-model:miniState="style.miniState"
301
+ v-model:dense="style.dense" v-model:menuOverlayHeader="style.menuOverlayHeader"
302
+ v-model:footer="style.footer" />
309
303
  </q-scroll-area>
310
304
  </q-drawer>
311
305
 
312
- <q-page-container class="bg-grey-2" style="color:#1f1f1f">
306
+ <q-page-container :class="containerClass" :style="containerStyle">
307
+
313
308
  <!-- Error message -->
314
309
  <q-banner dense inline-actions class="bg-grey-4 q-ma-md" v-for="error in errors" rounded>
315
310
  {{ error }}
@@ -330,7 +325,7 @@ const storageUsagePercent = computed(() => {
330
325
  </q-page-container>
331
326
 
332
327
 
333
- <q-footer class="bg-white text-grey" bordered>
328
+ <q-footer bordered v-if="style.footer">
334
329
  <q-item>
335
330
  <q-item-section>
336
331
  {{ light.getCompany() }} {{ appVersion }} - Copyright 2023 HostLink(HK). Build {{ light.getVersion() }}
@@ -1,7 +1,6 @@
1
1
  <script setup>
2
2
  import { useLight } from '../'
3
3
  import { useAttrs, ref, computed } from 'vue'
4
- import Style from '../pages/User/setting/style.vue';
5
4
 
6
5
  defineProps({
7
6
  loading: Boolean,
@@ -10,7 +9,6 @@ defineProps({
10
9
 
11
10
  const light = useLight();
12
11
 
13
-
14
12
  const attrs = {
15
13
  ...{
16
14
  flat: light.getStyle("cardFlat", true),
@@ -19,9 +17,12 @@ const attrs = {
19
17
  }, ...useAttrs()
20
18
  }
21
19
 
22
- const color = light.getStyle("color", 'primary');
23
-
24
- const cl = ["text-white", `bg-${color}`];
20
+ const cl = computed(() => {
21
+ const c = ["text-white"];
22
+ const color = light.color;
23
+ c.push(`bg-${color}`);
24
+ return c;
25
+ });
25
26
 
26
27
  const minimize = ref(false);
27
28
 
@@ -39,7 +40,6 @@ const showBody = computed(() => !minimize.value || fullScreen.value);
39
40
  <q-bar :class="cl" v-if="title">
40
41
  <div>{{ title }}</div>
41
42
  <q-space />
42
-
43
43
  <!-- q-btn-dropdown dense flat icon="sym_o_search" persistent>
44
44
  <div class="q-ma-md">
45
45
  <q-input></q-input>
@@ -1,4 +1,5 @@
1
1
  <script setup>
2
+ import { defineModel } from 'vue'
2
3
  const COLORS = [
3
4
  'primary',
4
5
  'secondary',
@@ -26,10 +27,12 @@ const COLORS = [
26
27
  'brown',
27
28
  'grey',
28
29
  'blue-grey'
29
-
30
30
  ]
31
31
 
32
- defineEmits(['update:theme', 'update:menuOverlayHeader', 'update:dense', 'update:headerColor', 'update:miniState'])
32
+ defineEmits(['update:theme', 'update:menuOverlayHeader', 'update:dense', 'update:color', 'update:miniState', 'update:footer'])
33
+
34
+ const color = defineModel("color", { type: String, default: "primary" })
35
+
33
36
 
34
37
  const props = defineProps({
35
38
  menuOverlayHeader: {
@@ -44,13 +47,13 @@ const props = defineProps({
44
47
  type: Boolean,
45
48
  default: false
46
49
  },
47
- headerColor: {
48
- type: String,
49
- default: 'bg-primary'
50
- },
51
50
  dense: {
52
51
  type: Boolean,
53
52
  default: false
53
+ },
54
+ footer: {
55
+ type: Boolean,
56
+ default: false
54
57
  }
55
58
  })
56
59
 
@@ -80,10 +83,10 @@ const props = defineProps({
80
83
  <q-separator />
81
84
  <q-item>
82
85
  <q-item-section>
83
- <q-item-label>Header color</q-item-label>
86
+ <q-item-label>Color</q-item-label>
84
87
  <div class="row">
85
88
  <div v-for="c in COLORS" :key="c" :class="`bg-${c}`" style="width: 1.5rem; height: 1.5rem;"
86
- class="q-ma-xs cursor-pointer rounded-borders" @click="$emit('update:headerColor', c)" />
89
+ class="q-ma-xs cursor-pointer rounded-borders" @click="$emit('update:color', c)" />
87
90
  </div>
88
91
  </q-item-section>
89
92
  </q-item>
@@ -118,5 +121,17 @@ const props = defineProps({
118
121
  @update:model-value="$emit('update:menuOverlayHeader', $event)" />
119
122
  </q-item-section>
120
123
  </q-item>
124
+
125
+ <q-separator />
126
+
127
+ <q-item>
128
+ <q-item-section>
129
+ <q-item-label>Show footer</q-item-label>
130
+ </q-item-section>
131
+ <q-item-section side>
132
+ <q-toggle :model-value="footer" @update:model-value="$emit('update:footer', $event)" />
133
+ </q-item-section>
134
+ </q-item>
135
+
121
136
  </q-list>
122
137
  </template>
@@ -3,7 +3,7 @@ import { VariableType } from "json-to-graphql-query";
3
3
  import { useI18n } from "vue-i18n";
4
4
  import { ref, watch, computed } from 'vue';
5
5
  import { useQuasar } from 'quasar';
6
- import { q, m } from '../';
6
+ import { q, m, useLight } from '../';
7
7
  import {
8
8
  fsListFolders, fsCreateFolder, fsDeleteFolder, fsDeleteFile, fsRenameFile, fsRenameFolder, fsReadFile,
9
9
  granted
@@ -11,6 +11,7 @@ import {
11
11
  } from "@hostlink/light";
12
12
 
13
13
 
14
+ const light = useLight();
14
15
  const i18n = useI18n();
15
16
  const quasar = useQuasar();
16
17
  const emit = defineEmits(["input", "close"]);
@@ -456,10 +457,14 @@ const canRenameRow = (row) => {
456
457
  /* const perm = await q("granted", {
457
458
  rights: ["fs.folder.create"]
458
459
  }) */
460
+
461
+
462
+ const isDark = computed(() => light.isDarkMode());
463
+
459
464
  </script>
460
465
  <template>
461
- <q-layout view="hHh lpR fFf" class="bg-white" container :style="{ 'min-height': height }">
462
- <q-header bordered class="bg-white text-grey-8" height-hint="64">
466
+ <q-layout view="hHh lpR fFf" :class="isDark ? '' : 'bg-white'" container :style="{ 'min-height': height }">
467
+ <q-header bordered :class="isDark?'':'bg-white text-grey-8'" height-hint="64">
463
468
  <q-toolbar>
464
469
  <q-btn flat round @click="toggleLeftDrawer" aria-label="Menu" icon="menu" class="q-mr-sm" />
465
470
 
@@ -481,7 +486,7 @@ const canRenameRow = (row) => {
481
486
  </q-toolbar>
482
487
  </q-header>
483
488
 
484
- <q-drawer v-model="leftDrawerOpen" show-if-above bordered class="bg-white" :width="257">
489
+ <q-drawer v-model="leftDrawerOpen" show-if-above bordered :width="257">
485
490
  <q-scroll-area class="fit">
486
491
  <q-list padding class="text-grey-8">
487
492
  <q-item>
@@ -42,7 +42,7 @@ const new_rules = props.rules || [];
42
42
 
43
43
  //has required prop (in properties)
44
44
  if (props.required) {
45
- new_rules.push(val => !!val || 'Required.');
45
+ new_rules.push(val => !!val || i18n.t('input_required',[i18n.t(props.label)]));
46
46
  }
47
47
 
48
48
  if (props.type == "email") {
@@ -172,7 +172,7 @@ onMounted(() => {
172
172
  </script>
173
173
 
174
174
  <template>
175
- <q-card bordered flat style="min-width:400px;max-width: 400px;" class="fixed-center">
175
+ <q-card bordered flat style="min-width:360px;max-width: 400px;" class="fixed-center">
176
176
  <q-card-section>
177
177
  <q-img :src="light.getCompanyLogo()" class="full-width" />
178
178
  <div class="text-h6">
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { reactive } from 'vue'
2
3
  import { useQuasar, QTable } from 'quasar';
3
4
  import { ref, computed, onMounted, useSlots, useAttrs } from "vue";
4
5
  import { t, deleteObject, q, useLight, GQLFieldBuilder } from '../';
@@ -288,10 +289,10 @@ const onRequest = async (p: any) => {
288
289
 
289
290
  let localFilters = getFilterValue();
290
291
 
291
- /* console.log("merge filters", filters)
292
-
293
- console.log("local filters", getFilterValue())
294
- */ //merge the filters
292
+ /* console.log("merge filters", filters)
293
+
294
+ console.log("local filters", getFilterValue())
295
+ */ //merge the filters
295
296
  if (filters) {
296
297
  localFilters = {
297
298
  ...localFilters,
@@ -400,9 +401,6 @@ const onDelete = async (id: any) => {
400
401
  }
401
402
  }
402
403
 
403
-
404
- //style
405
-
406
404
  const attrs = {
407
405
  ...{
408
406
  dense: light.getStyle("tableDense", false),
@@ -429,6 +427,11 @@ const filterFn = (val, update, abort) {
429
427
  })
430
428
  },
431
429
  */
430
+
431
+ const isDark = computed(() => {
432
+ return light.theme == "dark";
433
+
434
+ })
432
435
  </script>
433
436
 
434
437
  <template>
@@ -455,7 +458,8 @@ const filterFn = (val, update, abort) {
455
458
 
456
459
  <q-table v-bind="attrs" :row-key="rowKey" :loading="loading" :rows="rows" ref="table" @request="onRequest"
457
460
  :rows-per-page-label="$t(props.rowsPerPageLabel)" :columns="renderColumns"
458
- :rows-per-page-options="rowsPerPageOptions" :selection="selection" v-model:pagination="pagination" :filter="filter">
461
+ :rows-per-page-options="rowsPerPageOptions" :selection="selection" v-model:pagination="pagination" :filter="filter"
462
+ :no-data-label="$t('No data available')" :loading-label="$t('Loading...')">
459
463
 
460
464
  <template #top-right="props" v-if="fullscreen || searchable">
461
465
  <q-input v-if="searchable" outlined dense debounce="300" v-model="filter" placeholder="Search">
@@ -482,7 +486,7 @@ const filterFn = (val, update, abort) {
482
486
 
483
487
  <template #body-cell-_actions="props">
484
488
  <q-td :props="props" auto-width>
485
- <div class="text-grey-8">
489
+ <div :class="{ 'text-grey-8': !isDark }">
486
490
 
487
491
  <l-view-btn v-if="actionView && props.row.canView"
488
492
  :to="`/${modelName}/${props.row[primaryKey]}/view`" />
@@ -1,16 +1,26 @@
1
- interface Light {
1
+ export declare const useLight: () => {
2
+ company: string;
3
+ companyLogo: string;
4
+ color: string;
5
+ theme: string;
6
+ isDarkMode: () => boolean;
7
+ setCompany: (company: string) => void;
8
+ getCompany: () => string;
9
+ setCompanyLogo: (logo: string) => void;
10
+ getCompanyLogo: () => string;
11
+ getVersion: () => any;
2
12
  addError: (error: String) => void;
3
13
  getErrors: () => String[];
4
14
  removeError: (error: String) => void;
5
- getStyle: (name: String, defaultValue: any) => any;
6
- setStyles: (styles: Object) => void;
7
- getVersion(): string;
8
- getCompany(): string;
9
- setCompany(company: string): void;
10
- getCompanyLogo(): string;
11
- setCompanyLogo(logo: string): void;
12
- setCurrentRoute(to: any, from: any): void;
13
- getID(): Number | null;
14
- }
15
- export declare const useLight: () => Light;
15
+ getStyle: (name: String, defaultdefaultValue: any) => any;
16
+ setStyles: (s: Object) => void;
17
+ getStyles: () => {
18
+ theme?: String | undefined;
19
+ color?: String | undefined;
20
+ };
21
+ setStyle: (name: String, value: any) => Promise<void>;
22
+ setCurrentRoute: (to: any, from: any) => void;
23
+ getID: () => number | null;
24
+ init: (styles: any) => void;
25
+ };
16
26
  export * from "./lib";
@@ -1,62 +1,88 @@
1
1
  import packageJson from "../../package.json";
2
+ import { watch, reactive } from "vue";
3
+ import { m } from "./lib/index.mjs";
2
4
  const errors = [];
3
5
  let styles = {};
4
- const app = {
6
+ const app = reactive({
5
7
  company: "",
6
- companyLogo: ""
7
- };
8
+ companyLogo: "",
9
+ color: "primary",
10
+ theme: "light",
11
+ isDarkMode: () => {
12
+ return app.theme == "dark";
13
+ },
14
+ setCompany: (company) => {
15
+ app.company = company;
16
+ },
17
+ getCompany: () => {
18
+ return app.company;
19
+ },
20
+ setCompanyLogo: (logo) => {
21
+ app.companyLogo = logo;
22
+ },
23
+ getCompanyLogo: () => {
24
+ return app.companyLogo;
25
+ },
26
+ getVersion: () => {
27
+ return packageJson.version;
28
+ },
29
+ addError: (error) => {
30
+ errors.push(error);
31
+ },
32
+ getErrors: () => {
33
+ return errors;
34
+ },
35
+ removeError: (error) => {
36
+ const index = errors.indexOf(error);
37
+ if (index > -1) {
38
+ errors.splice(index, 1);
39
+ }
40
+ },
41
+ getStyle(name, defaultdefaultValue) {
42
+ if (styles[name] === void 0) {
43
+ return defaultdefaultValue;
44
+ }
45
+ return styles[name];
46
+ },
47
+ setStyles(s) {
48
+ styles = s;
49
+ },
50
+ getStyles() {
51
+ return styles;
52
+ },
53
+ async setStyle(name, value) {
54
+ await m("updateMyStyle", {
55
+ name,
56
+ value
57
+ });
58
+ styles[name] = value;
59
+ },
60
+ setCurrentRoute(to, from) {
61
+ currentRoute = to;
62
+ },
63
+ getID() {
64
+ if (currentRoute == null)
65
+ return null;
66
+ let name = currentRoute.name?.toString();
67
+ if (name == void 0)
68
+ return 0;
69
+ let parts = name.split("-");
70
+ const keyname = parts[1];
71
+ return parseInt(currentRoute.params[keyname]);
72
+ },
73
+ init(styles2) {
74
+ app.color = styles2.color || "primary";
75
+ app.theme = styles2.theme || "semi-dark";
76
+ watch(() => app.color, async () => {
77
+ await app.setStyle("color", app.color);
78
+ });
79
+ watch(() => app.theme, async () => {
80
+ await app.setStyle("theme", app.theme);
81
+ });
82
+ }
83
+ });
8
84
  let currentRoute = null;
9
85
  export const useLight = () => {
10
- return {
11
- setCompany: (company) => {
12
- app.company = company;
13
- },
14
- getCompany: () => {
15
- return app.company;
16
- },
17
- setCompanyLogo: (logo) => {
18
- app.companyLogo = logo;
19
- },
20
- getCompanyLogo: () => {
21
- return app.companyLogo;
22
- },
23
- getVersion: () => {
24
- return packageJson.version;
25
- },
26
- addError: (error) => {
27
- errors.push(error);
28
- },
29
- getErrors: () => {
30
- return errors;
31
- },
32
- removeError: (error) => {
33
- const index = errors.indexOf(error);
34
- if (index > -1) {
35
- errors.splice(index, 1);
36
- }
37
- },
38
- getStyle(name, defaultdefaultValue) {
39
- if (styles[name] === void 0) {
40
- return defaultdefaultValue;
41
- }
42
- return styles[name];
43
- },
44
- setStyles(s) {
45
- styles = s;
46
- },
47
- setCurrentRoute(to, from) {
48
- currentRoute = to;
49
- },
50
- getID() {
51
- if (currentRoute == null)
52
- return null;
53
- let name = currentRoute.name?.toString();
54
- if (name == void 0)
55
- return 0;
56
- let parts = name.split("-");
57
- const keyname = parts[1];
58
- return parseInt(currentRoute.params[keyname]);
59
- }
60
- };
86
+ return app;
61
87
  };
62
88
  export * from "./lib/index.mjs";
@@ -11,5 +11,6 @@
11
11
  "Theme Customizer": "Theme Customizer",
12
12
  "Customize & Preview in Real Time": "Customize & Preview in Real Time",
13
13
  "Permission": "Permission",
14
- "storage_usage":"{0} free of {1}"
14
+ "storage_usage":"{0} free of {1}",
15
+ "input_required": "Please input {0}"
15
16
  }
@@ -156,6 +156,10 @@
156
156
  "Export": "匯出",
157
157
  "Event Log": "事件紀錄",
158
158
  "Mail Log": "郵件紀錄",
159
- "User Log": "使用者紀錄"
159
+ "User Log": "使用者紀錄",
160
+ "input_required": "{0}為必填",
161
+ "Invalid email format": "電郵格式錯誤",
162
+ "No data available": "沒有資料",
163
+ "Loading...": "載入中..."
160
164
 
161
165
  }
@@ -1,7 +1,7 @@
1
1
  <script setup>
2
2
  import { reactive } from 'vue'
3
3
  import { getObject } from '../../../'
4
- const obj = reactive(await getObject(["first_name", "last_name", "email", "phone",
4
+ const obj = reactive(await getObject(["username", "first_name", "last_name", "email", "phone",
5
5
  "addr1", "addr2", "addr3", "join_date", "expiry_date", "status", "language", "default_page"
6
6
  ]))
7
7
  </script>
@@ -11,9 +11,10 @@ const obj = reactive(await getObject(["first_name", "last_name", "email", "phone
11
11
  <l-form v-model="obj" gutter="none">
12
12
  <l-row>
13
13
  <l-col md="6" gutter="md">
14
+ <l-input label="Username" v-model="obj.username" required />
14
15
  <l-input label="First name" v-model="obj.first_name" required />
15
16
  <l-input label="Last name" v-model="obj.last_name" />
16
- <l-input label="Email" v-model="obj.email" required type="email" />
17
+ <l-input label="Email" v-model="obj.email" required type="email" />
17
18
  </l-col>
18
19
  <l-col md="6" gutter="md">
19
20
  <l-input label="Phone" v-model="obj.phone" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostlink/nuxt-light",
3
- "version": "0.0.98",
3
+ "version": "0.0.99",
4
4
  "description": "HostLink Nuxt Light Framework",
5
5
  "repository": "@hostlink/nuxt-light",
6
6
  "license": "MIT",