@hostlink/nuxt-light 0.0.27 → 0.0.29

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.27"
4
+ "version": "0.0.29"
5
5
  }
package/dist/module.mjs CHANGED
@@ -10,7 +10,6 @@ const module = defineNuxtModule({
10
10
  defaults: {},
11
11
  setup(options, nuxt) {
12
12
  const resolver = createResolver(import.meta.url);
13
- nuxt.options.css.push("element-plus/dist/index.css");
14
13
  nuxt.options.css.push("quasar/dist/quasar.prod.css");
15
14
  nuxt.options.css.push("@quasar/extras/material-icons/material-icons.css");
16
15
  nuxt.options.css.push("@quasar/extras/material-icons-outlined/material-icons-outlined.css");
@@ -1,9 +1,12 @@
1
1
  <script setup>
2
+ import { useQuasar } from 'quasar';
2
3
  import { useI18n } from 'vue-i18n';
3
4
  import { useLight, q, getCurrentUser, m } from '../';
4
5
  import { ref, computed, reactive, provide, watch } from 'vue';
5
6
  //import packageJson from '../../package.json'
6
7
 
8
+ const quasar = useQuasar();
9
+ quasar.dark.set(false);
7
10
  const light = useLight();
8
11
  const props = defineProps({
9
12
  company: {
@@ -13,6 +16,10 @@ const props = defineProps({
13
16
 
14
17
  let app = await q("app", ["menus", "viewAsMode", "languages"]);
15
18
  let my = await q("my", ["styles", "language"]);
19
+ let system = await q("system", ["diskFreeSpace", "diskTotalSpace", "diskFreeSpacePercent"]);
20
+
21
+ light.setStyles(my.styles);
22
+
16
23
  const menus = ref(app.menus)
17
24
 
18
25
  const i18n = useI18n();
@@ -50,9 +57,9 @@ const layoutView = computed(() => {
50
57
 
51
58
  const style = reactive({
52
59
  color: my.styles?.color || 'bg-primary',
53
- theme: 'semi-dark',
54
- miniState: false,
55
- dense: my.styles?.dense
60
+ theme: my.styles?.theme || 'semi-dark',
61
+ miniState: my.styles?.miniState || false,
62
+ dense: my.styles?.dense || false
56
63
  });
57
64
 
58
65
 
@@ -100,6 +107,7 @@ const reloadMenu = async () => {
100
107
 
101
108
  provide('reloadMenu', reloadMenu)
102
109
 
110
+
103
111
  watch(() => style.dense, async (value) => {
104
112
  await m("updateMyStyle", {
105
113
  name: "dense",
@@ -111,14 +119,31 @@ watch(() => style.color, async (value) => {
111
119
  await m("updateMyStyle", {
112
120
  name: "color",
113
121
  value: value
114
- });
122
+ })
123
+ })
124
+
125
+ watch(() => style.theme, async (value) => {
126
+ await m("updateMyStyle", {
127
+ name: "theme",
128
+ value: value
129
+ })
115
130
  })
116
131
 
132
+ watch(() => style.miniState, async (value) => {
133
+ await m("updateMyStyle", {
134
+ name: "miniState",
135
+ value: value
136
+ })
137
+ });
138
+
117
139
  const exitViewAs = async () => {
118
140
  await m("cancelViewAs");
119
141
  window.location.reload();
120
142
  }
121
143
 
144
+
145
+
146
+
122
147
  </script>
123
148
 
124
149
 
@@ -134,7 +159,7 @@ const exitViewAs = async () => {
134
159
 
135
160
  <q-space />
136
161
 
137
- <q-btn v-if="languages.length > 1" rounded flat icon="language" :label="my.language">
162
+ <q-btn v-if="languages.length > 1" rounded flat icon="language" :label="my.language" class="q-mr-sm">
138
163
  <q-menu>
139
164
  <q-list>
140
165
  <q-item v-for="language in languages" :key="language.value" v-close-popup clickable
@@ -147,7 +172,26 @@ const exitViewAs = async () => {
147
172
  </q-menu>
148
173
  </q-btn>
149
174
 
150
- <div class="q-mx-sm">
175
+ <q-btn icon="sym_o_storage" flat round dense class="q-mr-sm">
176
+ <q-menu>
177
+ <q-card style="width:200px">
178
+ <q-card-section>
179
+ Storage
180
+ <q-linear-progress rounded size="20px" :value="system.diskFreeSpacePercent" color="primary"
181
+ class="q-mt-sm" />
182
+
183
+ {{ system.diskFreeSpace }} / {{ system.diskTotalSpace }}
184
+
185
+
186
+ </q-card-section>
187
+
188
+ </q-card>
189
+ </q-menu>
190
+
191
+
192
+ </q-btn>
193
+
194
+ <div class="q-mx-sm" v-if="$q.platform.is.desktop">
151
195
  <div class="text-bold text-right">
152
196
  {{ user.first_name }} {{ user.last_name }}
153
197
  </div>
@@ -158,6 +202,8 @@ const exitViewAs = async () => {
158
202
  </div>
159
203
 
160
204
 
205
+
206
+
161
207
  <q-btn flat round dense icon="sym_o_person" class="q-mr-sm">
162
208
  <q-menu max-width="250px">
163
209
  <q-list>
@@ -232,7 +278,6 @@ const exitViewAs = async () => {
232
278
  </q-card-section>
233
279
  </q-card>
234
280
 
235
-
236
281
  <router-view v-slot="{ Component }">
237
282
  <template v-if="Component">
238
283
  <suspense>
@@ -70,7 +70,7 @@ const props = defineProps({
70
70
  <q-separator />
71
71
  <q-item>
72
72
  <q-item-section>
73
- <q-item-label>Mini mode</q-item-label>
73
+ <q-item-label>{{ $t('Mini mode') }}</q-item-label>
74
74
  </q-item-section>
75
75
  <q-item-section side>
76
76
  <q-toggle :model-value="miniState" @update:model-value="$emit('update:miniState', $event)" />
@@ -1,5 +1,5 @@
1
1
  <script setup>
2
- import { computed } from "vue";
2
+ import { computed, ref } from "vue";
3
3
  import { useI18n } from 'vue-i18n';
4
4
  const i18n = useI18n();
5
5
 
@@ -22,6 +22,10 @@ const props = defineProps({
22
22
  type: String,
23
23
  default: "text"
24
24
  },
25
+ showPassword: {
26
+ type: Boolean,
27
+ default: false
28
+ }
25
29
  });
26
30
  const emit = defineEmits(["update:modelValue"]);
27
31
 
@@ -54,10 +58,45 @@ const localLabel = computed(() => {
54
58
 
55
59
  });
56
60
 
61
+ const isShowPassword = ref(false);
62
+
63
+ const localType = computed(() => {
64
+ if (props.type == "password" && isShowPassword.value) {
65
+ return "text";
66
+ }
67
+ return props.type;
68
+ });
69
+
70
+
71
+
72
+ const localShowPassword = computed(() => {
73
+ if (props.type != "password") {
74
+ return false;
75
+ }
76
+
77
+ if (!props.showPassword) {
78
+ return false;
79
+ }
80
+
81
+ if (!localValue.value) {
82
+ return false;
83
+ }
84
+
85
+ return true;
86
+
87
+ });
88
+
57
89
 
58
90
 
59
91
 
60
92
  </script>
61
93
  <template>
62
- <q-input :label="localLabel" v-model="localValue" hide-bottom-space :rules="new_rules" :type="type"></q-input>
94
+ <q-input :label="localLabel" v-model="localValue" hide-bottom-space :rules="new_rules" :type="localType">
95
+ <template v-if="localShowPassword" v-slot:append>
96
+ <q-icon name="sym_o_visibility" class="cursor-pointer" :color="showPassword ? 'primary' : 'grey-5'"
97
+ @click="isShowPassword = false" v-if="isShowPassword" />
98
+ <q-icon name="sym_o_visibility_off" class="cursor-pointer" :color="showPassword ? 'grey-5' : 'primary'"
99
+ @click="isShowPassword = true" v-else />
100
+ </template>
101
+ </q-input>
63
102
  </template>
@@ -112,8 +112,8 @@ const forgetPassword = async () => {
112
112
  {{ company }}
113
113
  </div>
114
114
  <q-form ref="form1">
115
- <q-input v-model.trim="data.username" label="Username" :rules="[v => !!v || 'Username is required']" clearable />
116
- <q-input v-model="data.password" label="Password" type="password" clearable
115
+ <l-input v-model.trim="data.username" label="Username" :rules="[v => !!v || 'Username is required']" clearable />
116
+ <l-input v-model="data.password" label="Password" type="password" clearable show-password
117
117
  :rules="[v => !!v || 'Password is required']" @keydown.enter.prevent="submit" />
118
118
  <q-input v-if="twoFactorAuthentication" v-model="data.code" label="2FA code" required type="text" clearable>
119
119
  </q-input>
@@ -1,3 +1,3 @@
1
1
  <template>
2
- <q-btn color="primary" flat rounded icon="sym_o_save" label="Save" />
2
+ <q-btn color="primary" outline rounded icon="sym_o_save" :label="$t('Save')" />
3
3
  </template>
@@ -2,12 +2,16 @@
2
2
  import { useQuasar, QTable } from 'quasar';
3
3
  import { useRoute } from 'vue-router';
4
4
  import { ref, computed, onMounted, useSlots, reactive } from "vue";
5
- import { t, deleteObject, q, f } from '../';
5
+ import { t, deleteObject, q, f, useLight } from '../';
6
6
 
7
7
  const route = useRoute();
8
8
  const module = route.path.split("/")[1];
9
9
  const errors = ref<InstanceType<any>>([]);
10
10
 
11
+ const light = useLight();
12
+
13
+ const tableDense = light.getStyle("tableDense") ?? false;
14
+
11
15
  const props = defineProps({
12
16
  columns: {
13
17
  type: Array<{
@@ -33,6 +37,10 @@ const props = defineProps({
33
37
  type: String,
34
38
  default: null
35
39
  },
40
+ rowsPerPageLabel: {
41
+ type: String,
42
+ default: "Records per page:"
43
+ },
36
44
  })
37
45
 
38
46
 
@@ -328,6 +336,8 @@ const onDelete = async (id: any) => {
328
336
  }
329
337
 
330
338
 
339
+
340
+
331
341
  </script>
332
342
  <template>
333
343
  <template v-if="errors.length > 0">
@@ -337,9 +347,9 @@ const onDelete = async (id: any) => {
337
347
  </ul>
338
348
  </div>
339
349
  </template>
340
-
341
- <q-table flat bordered :columns="renderColumns" v-model:pagination="pagination" ref="table" :loading="loading"
342
- @request="onRequest" :selection="selection" :rows="rows">
350
+ <q-table flat bordered :dense="tableDense" :columns="renderColumns" v-model:pagination="pagination" ref="table"
351
+ :loading="loading" @request="onRequest" :selection="selection" :rows="rows"
352
+ :rows-per-page-label="t(props.rowsPerPageLabel)">
343
353
 
344
354
  <template v-for="s in ss" v-slot:[s]="props">
345
355
  <slot :name="s" v-bind="props"></slot>
@@ -2,6 +2,8 @@ interface Light {
2
2
  addError: (error: String) => void;
3
3
  getErrors: () => String[];
4
4
  removeError: (error: String) => void;
5
+ getStyle: (name: String) => any;
6
+ setStyles: (styles: Object) => void;
5
7
  }
6
8
  export declare function useLight(): Light;
7
9
  export { notify, addObject, f, getApiUrl, getCurrentUser, getObject, id, list, listData, login, m, mutation, q, removeObject, t, updateObject, getID, deleteObject, listObject } from "./lib";
@@ -1,4 +1,5 @@
1
1
  const errors = [];
2
+ let styles = {};
2
3
  export function useLight() {
3
4
  return {
4
5
  addError: (error) => {
@@ -12,6 +13,12 @@ export function useLight() {
12
13
  if (index > -1) {
13
14
  errors.splice(index, 1);
14
15
  }
16
+ },
17
+ getStyle(name) {
18
+ return styles[name];
19
+ },
20
+ setStyles(s) {
21
+ styles = s;
15
22
  }
16
23
  };
17
24
  }
@@ -145,5 +145,7 @@
145
145
  "Menu": "選單",
146
146
  "New": "新增",
147
147
  "Server": "伺服器",
148
- "Remove": "移除"
148
+ "Remove": "移除",
149
+ "Records per page:": "每頁顯示:"
150
+
149
151
  }
@@ -9,8 +9,6 @@ const loadData = async () => {
9
9
  return await q("listRole", ["name", "canDelete", { parents: ["name"] }]);
10
10
 
11
11
  }
12
-
13
-
14
12
  const roles = ref(await loadData());
15
13
 
16
14
  const onDelete = async (role) => {
@@ -29,12 +27,45 @@ const onDelete = async (role) => {
29
27
 
30
28
  }
31
29
 
30
+ const columns = [
31
+ {
32
+ name: "_can_delete"
33
+ },
34
+ {
35
+ name: "name",
36
+ field: "name",
37
+ label: "Name",
38
+ align: "left",
39
+ sortable: true,
40
+ }, {
41
+ name: "parents",
42
+ label: "Parent",
43
+ align: "left",
44
+ }
45
+ ]
46
+
32
47
  </script>
33
48
 
34
49
  <template>
35
50
  <l-page>
51
+ <q-table :rows="roles" flat bordered :columns="columns">
52
+ <template #body-cell-_can_delete="props">
53
+ <q-td auto-width>
54
+ <q-btn v-if="props.row.canDelete" flat round dense icon="sym_o_delete"
55
+ @click="onDelete(props.row.name)" />
56
+ </q-td>
57
+ </template>
58
+
59
+ <template #body-cell-parents="props">
60
+ <q-td>
61
+ <q-table :rows="props.row.parents" flat bordered :rows-per-page-options="[0]" hide-bottom></q-table>
62
+ </q-td>
63
+ </template>
64
+
65
+
66
+ </q-table>
36
67
 
37
- <el-table :data="roles">
68
+ <!-- q-table :data="roles">
38
69
 
39
70
  <el-table-column width="60px" #default="{ row }">
40
71
  <q-btn v-if="row.canDelete" flat round dense icon="sym_o_delete" @click="onDelete(row.name)" />
@@ -49,6 +80,6 @@ const onDelete = async (role) => {
49
80
  </el-table>
50
81
  </template>
51
82
  </el-table-column>
52
- </el-table>
83
+ </q-table -->
53
84
  </l-page>
54
85
  </template>
@@ -34,6 +34,12 @@ const columns = [
34
34
  name: "phone",
35
35
  sortable: true,
36
36
  searchable: true,
37
+ }, {
38
+ label: "Join date",
39
+ name: "join_date",
40
+ sortable: true,
41
+ searchable: true,
42
+ searchType: "date"
37
43
  }
38
44
  ]
39
45
 
@@ -1,3 +1,21 @@
1
+ <script setup>
2
+ import { q, m } from '../../../'
3
+ import { reactive } from 'vue'
4
+ let my = await q("my", ["styles"]);
5
+
6
+ const styles = reactive({
7
+ tableDense: my.styles.tableDense,
8
+ })
9
+
10
+ const onSave = async () => {
11
+ await m("updateMyStyle", {
12
+ name: "tableDense",
13
+ value: styles.tableDense
14
+ });
15
+ }
16
+ </script>
1
17
  <template>
2
- <div>Style</div>
18
+ <l-form @save="onSave" :bordered="false">
19
+ <q-checkbox v-model="styles.tableDense" label="Dense table" />
20
+ </l-form>
3
21
  </template>
@@ -1,4 +1,3 @@
1
1
  import "./assets/main.css";
2
- import './assets/element.css';
3
2
  declare const _default: any;
4
3
  export default _default;
@@ -1,12 +1,8 @@
1
1
  import { Quasar, Dialog, Notify, Loading } from "quasar";
2
- import ElementPlus from "element-plus";
3
2
  import { createI18n } from "vue-i18n";
4
3
  import { defineNuxtPlugin } from "#app";
5
4
  import { useRouter } from "vue-router";
6
5
  import "./assets/main.css";
7
- import "./assets/element.css";
8
- import zhTW from "element-plus/es/locale/lang/zh-tw";
9
- import en from "element-plus/es/locale/lang/en";
10
6
  import message_en from "./locales/en.json";
11
7
  import message_zh from "./locales/zh-hk.json";
12
8
  import routes from "./routes.mjs";
@@ -22,15 +18,14 @@ export default defineNuxtPlugin((nuxtApp) => {
22
18
  legacy: false,
23
19
  locale: localStorage.getItem("locale") || "en",
24
20
  messages: {
25
- en: Object.assign(en, message_en),
26
- "zh-hk": Object.assign(zhTW, message_zh),
27
- "zh-tw": Object.assign(zhTW, message_zh)
21
+ en: message_en,
22
+ "zh-hk": message_zh,
23
+ "zh-tw": message_zh
28
24
  },
29
25
  fallbackWarn: false,
30
26
  missingWarn: false
31
27
  });
32
28
  nuxtApp.vueApp.use(i18n);
33
- nuxtApp.vueApp.use(ElementPlus);
34
29
  nuxtApp.vueApp.use(Quasar, {
35
30
  config: {
36
31
  brand: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostlink/nuxt-light",
3
- "version": "0.0.27",
3
+ "version": "0.0.29",
4
4
  "description": "HostLink Nuxt Light Framework",
5
5
  "repository": "@hostlink/nuxt-light",
6
6
  "license": "MIT",
@@ -34,7 +34,6 @@
34
34
  "@nuxt/kit": "^3.7.0",
35
35
  "@quasar/extras": "^1.16.6",
36
36
  "axios": "^1.5.0",
37
- "element-plus": "^2.3.12",
38
37
  "gql-query-builder": "^3.8.0",
39
38
  "json-to-graphql-query": "^2.2.5",
40
39
  "quasar": "^2.12.5",