@hostlink/nuxt-light 1.2.1 → 1.3.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.
@@ -138,12 +138,17 @@ const attrs = computed(() => {
138
138
 
139
139
  if (props.label) {
140
140
  a.label = i18n.t(props.label);
141
+
142
+ if (props.required) {
143
+ a.label = "* " + a.label;
144
+ }
145
+
141
146
  }
142
147
  return a;
143
148
  })
144
149
  </script>
145
150
  <template>
146
- <q-input v-bind="attrs" v-model="localValue" :rules="new_rules" :type="localType">
151
+ <q-input v-bind="attrs" v-model="localValue" :rules="new_rules" :type="localType">
147
152
  <template v-if="translate" #prepend>
148
153
  <q-btn icon="sym_o_translate" flat dense rounded>
149
154
  <q-menu dense>
@@ -5,6 +5,10 @@ declare const app: {
5
5
  theme: string;
6
6
  isAdmin: boolean;
7
7
  permissions: string[];
8
+ myFavorites: any[];
9
+ setMyFavorites: (favorites: any[]) => void;
10
+ reloadMyFavorites: () => Promise<void>;
11
+ getMyFavorites: () => any[];
8
12
  isDarkMode: () => boolean;
9
13
  setCompany: (company: string) => void;
10
14
  getCompany: () => string;
@@ -38,6 +42,10 @@ export declare const useLight: () => {
38
42
  theme: string;
39
43
  isAdmin: boolean;
40
44
  permissions: string[];
45
+ myFavorites: any[];
46
+ setMyFavorites: (favorites: Array<any>) => void;
47
+ reloadMyFavorites: () => Promise<void>;
48
+ getMyFavorites: () => any[];
41
49
  isDarkMode: () => boolean;
42
50
  setCompany: (company: string) => void;
43
51
  getCompany: () => string;
@@ -1,6 +1,6 @@
1
1
  import packageJson from "../../package.json";
2
2
  import { watch, reactive } from "vue";
3
- import { m } from "./lib/index.mjs";
3
+ import { m, q } from "./lib/index.mjs";
4
4
  const errors = [];
5
5
  let styles = {};
6
6
  let defaultStyle = {
@@ -17,6 +17,26 @@ const app = reactive({
17
17
  theme: "light",
18
18
  isAdmin: false,
19
19
  permissions: Array(),
20
+ myFavorites: Array(),
21
+ setMyFavorites: (favorites) => {
22
+ app.myFavorites = favorites;
23
+ },
24
+ reloadMyFavorites: async () => {
25
+ const data = await q({
26
+ my: {
27
+ myFavorites: {
28
+ my_favorite_id: true,
29
+ label: true,
30
+ path: true,
31
+ icon: true
32
+ }
33
+ }
34
+ });
35
+ app.myFavorites = data.my.myFavorites;
36
+ },
37
+ getMyFavorites: () => {
38
+ return app.myFavorites;
39
+ },
20
40
  isDarkMode: () => {
21
41
  return app.theme == "dark";
22
42
  },
@@ -1,4 +1,7 @@
1
1
  {
2
+ "Developer": "開發者",
3
+ "Modules": "模組",
4
+ "Security": "安全",
2
5
  "Password policy": "密碼規則",
3
6
  "Must contain at least {0} characters": "必須包含至少{0}個字元",
4
7
  "contains_symbol": "必須包含符號",
@@ -1,10 +1,10 @@
1
1
  <script setup>
2
+ import { ref } from 'vue'
2
3
  import { Notify } from 'quasar'
3
4
  import { reset } from "@formkit/core"
4
5
  import { useRouter } from 'vue-router'
5
- import { q, m } from '../../'
6
+ import { q, m } from '#imports'
6
7
 
7
- const router = useRouter()
8
8
  const { app } = await q({ app: { config: ["name", "value"] } })
9
9
  const obj = app.config.reduce((acc, cur) => {
10
10
  acc[cur.name] = cur.value
@@ -63,65 +63,104 @@ if (obj.mode != 'prod') {
63
63
  obj.mode = 'prod'
64
64
  }
65
65
 
66
+ const tab = ref('general')
66
67
 
67
68
  </script>
68
69
  <template>
69
70
  <l-page>
70
- <FormKit type="l-form" :value="obj" #default="{ value }" @submit="onSubmit">
71
- <FormKit type="l-input" label="Company" name="company" validation="required"></FormKit>
72
- <FormKit type="l-input" label="Company logo" name="company_logo"></FormKit>
73
-
74
- <q-separator />
75
-
76
- <q-field label="Password policy" stack-label>
77
- <FormKit type="q-checkbox" label="Upper Case" name="password_contains_uppercase" true-value="1"
78
- false-value="0" />
79
- <FormKit type="q-checkbox" label="Lower Case" name="password_contains_lowercase" true-value="1"
80
- false-value="0" />
81
- <FormKit type="q-checkbox" label="Number" name="password_contains_numeric" true-value="1" false-value="0" />
82
- <FormKit type="q-checkbox" label="Special Character" name="password_contains_symbol" true-value="1"
83
- false-value="0" />
84
- </q-field>
85
-
86
- <FormKit type="l-input" label="Password min Length" name="password_min_length" validation="required|number">
87
- </FormKit>
88
-
89
- <q-field label="File manager" stack-label>
90
- <FormKit type="q-checkbox" label="Show" name="file_manager" true-value="1" false-value="0" />
91
- </q-field>
92
-
93
- <q-field label="Two factor authentication" stack-label>
94
- <FormKit type="q-checkbox" label="Enable" name="two_factor_authentication" true-value="1" false-value="0" />
95
- </q-field>
96
-
97
- <FormKit label="Mode" type="l-select" :options="[
98
- { label: 'Production', value: 'prod' },
99
- { label: 'Development', value: 'dev' },
100
-
101
- ]" name="mode" validation="required">
102
- </FormKit>
103
-
104
- <q-separator />
105
-
106
- <FormKit label="Auth lockout duration" type="l-input" name="auth_lockout_duration"
107
- hint="The number of minutes the user is locked out after the maximum number of failed login attempts. Default is 15 minutes."
108
- validation="required" />
109
-
110
- <FormKit label="Auth lockout attempts" type="l-input" name="auth_lockout_attempts"
111
- hint="The number of failed login attempts before the user is locked out. Default is 5 attempts."
112
- validation="required" />
113
-
114
- <FormKit label="Access token expiration" type="l-input" name="access_token_expire"
115
- hint="The access token expiration time in seconds. Default is 28800 seconds (8 hours)."
116
- validation="required" />
117
-
118
- <q-separator />
119
-
120
- <FormKit label="Copyright name" type="l-input" name="copyright_name" validation="required" />
121
- <FormKit label="Copyright year" type="l-input" name="copyright_year" validation="required" />
122
-
123
-
124
- </FormKit>
125
71
 
72
+ <q-card flat bordered>
73
+ <q-splitter unit="px" :model-value="120">
74
+ <template #before>
75
+ <q-tabs v-model="tab" vertical :active-color="$light.color">
76
+ <q-tab name="general" icon="sym_o_info" :label="$t('General')" />
77
+ <q-tab name="security" icon="sym_o_security" :label="$t('Security')" />
78
+ <q-tab name="Modules" icon="sym_o_apps" :label="$t('Modules')" />
79
+ <q-tab name="Developer" icon="sym_o_code" :label="$t('Developer')" />
80
+ </q-tabs>
81
+ </template>
82
+ <template #after>
83
+ <FormKit type="l-form" :value="{
84
+ company: obj.company,
85
+ company_logo: obj.company_logo,
86
+ copyright_name: obj.copyright_name,
87
+ copyright_year: obj.copyright_year
88
+ }" v-if="tab == 'general'" @submit="onSubmit">
89
+ <FormKit type="l-input" label="Company" name="company" validation="required"></FormKit>
90
+ <FormKit type="l-input" label="Company logo" name="company_logo"></FormKit>
91
+
92
+ <FormKit label="Copyright name" type="l-input" name="copyright_name" validation="required" />
93
+ <FormKit label="Copyright year" type="l-input" name="copyright_year" validation="required" />
94
+
95
+ </FormKit>
96
+
97
+ <FormKit type="l-form" :value="{
98
+ password_contains_uppercase: obj.password_contains_uppercase,
99
+ password_contains_lowercase: obj.password_contains_lowercase,
100
+ password_contains_numeric: obj.password_contains_numeric,
101
+ password_contains_symbol: obj.password_contains_symbol,
102
+ password_min_length: obj.password_min_length,
103
+ two_factor_authentication: obj.two_factor_authentication,
104
+ auth_lockout_duration: obj.auth_lockout_duration,
105
+ auth_lockout_attempts: obj.auth_lockout_attempts,
106
+ access_token_expire: obj.access_token_expire,
107
+ }" v-if="tab == 'security'" @submit="onSubmit">
108
+ <q-field label="Password policy" stack-label>
109
+ <FormKit type="q-checkbox" label="Upper Case" name="password_contains_uppercase" true-value="1"
110
+ false-value="0" />
111
+ <FormKit type="q-checkbox" label="Lower Case" name="password_contains_lowercase" true-value="1"
112
+ false-value="0" />
113
+ <FormKit type="q-checkbox" label="Number" name="password_contains_numeric" true-value="1"
114
+ false-value="0" />
115
+ <FormKit type="q-checkbox" label="Special Character" name="password_contains_symbol"
116
+ true-value="1" false-value="0" />
117
+ </q-field>
118
+
119
+ <FormKit type="l-input" label="Password min Length" name="password_min_length"
120
+ validation="required|number">
121
+ </FormKit>
122
+
123
+
124
+ <q-field label="Two factor authentication" stack-label>
125
+ <FormKit type="q-checkbox" label="Enable" name="two_factor_authentication" true-value="1"
126
+ false-value="0" />
127
+ </q-field>
128
+
129
+ <FormKit label="Auth lockout duration" type="l-input" name="auth_lockout_duration"
130
+ hint="The number of minutes the user is locked out after the maximum number of failed login attempts. Default is 15 minutes."
131
+ validation="required" />
132
+
133
+ <FormKit label="Auth lockout attempts" type="l-input" name="auth_lockout_attempts"
134
+ hint="The number of failed login attempts before the user is locked out. Default is 5 attempts."
135
+ validation="required" />
136
+
137
+ <FormKit label="Access token expiration" type="l-input" name="access_token_expire"
138
+ hint="The access token expiration time in seconds. Default is 28800 seconds (8 hours)."
139
+ validation="required" />
140
+ </FormKit>
141
+
142
+ <FormKit type="l-form" :value="{
143
+ file_manager: obj.file_manager,
144
+
145
+ }" v-if="tab == 'Modules'" @submit="onSubmit">
146
+ <q-field label="File manager" stack-label>
147
+ <FormKit type="q-checkbox" label="Show" name="file_manager" true-value="1" false-value="0" />
148
+ </q-field>
149
+ </FormKit>
150
+
151
+ <FormKit type="l-form" :value="{
152
+ mode: obj.mode,
153
+
154
+ }" v-if="tab == 'Developer'" @submit="onSubmit">
155
+ <FormKit label="Mode" type="l-select" :options="[
156
+ { label: 'Production', value: 'prod' },
157
+ { label: 'Development', value: 'dev' },
158
+
159
+ ]" name="mode" validation="required">
160
+ </FormKit>
161
+ </FormKit>
162
+ </template>
163
+ </q-splitter>
164
+ </q-card>
126
165
  </l-page>
127
166
  </template>
@@ -0,0 +1,74 @@
1
+ <script setup>
2
+ import { useLight, model, q } from "#imports"
3
+ import { ref } from "vue"
4
+ import { Notify } from "quasar";
5
+ const light = useLight()
6
+
7
+ const columns = [
8
+ { name: "_delete", align: "center" },
9
+ { name: 'label', label: 'Label', align: 'left' },
10
+ { name: 'path', label: 'Path', align: 'left' },
11
+ { name: 'icon', label: 'Icon', align: 'left' }
12
+ ]
13
+
14
+ const onSave = async (id, data) => {
15
+
16
+ await model("MyFavorite").update(id, data);
17
+
18
+ //show success message
19
+ Notify.create({
20
+ message: "Updated successfully",
21
+ color: "positive",
22
+ icon: "check"
23
+ });
24
+
25
+
26
+ await light.reloadMyFavorites()
27
+
28
+ }
29
+
30
+ const onRemove = async (id) => {
31
+ await model("MyFavorite").delete(id);
32
+ await light.reloadMyFavorites()
33
+ }
34
+
35
+ </script>
36
+ <template>
37
+ <q-table :columns="columns" :rows="$light.myFavorites" :rows-per-page-options="[0]">
38
+
39
+ <template #body-cell-_delete="props">
40
+ <q-td auto-width>
41
+ <q-btn flat icon="sym_o_delete" round @click="onRemove(props.row.my_favorite_id)"></q-btn>
42
+ </q-td>
43
+ </template>
44
+
45
+ <template #body-cell-label="props">
46
+ <q-td key="label">
47
+ {{ props.row.label }}
48
+ <q-popup-edit v-model="props.row.label" #default="scope" buttons
49
+ @save="onSave(props.row.my_favorite_id, { 'label': $event })">
50
+ <q-input v-model="scope.value" dense autofocus counter @keyup.enter="scope.set" />
51
+ </q-popup-edit>
52
+ </q-td>
53
+
54
+ </template>
55
+
56
+ <template #body-cell-path="props">
57
+ <q-td key="path">
58
+ {{ props.row.path }}
59
+ <q-popup-edit v-model="props.row.path" #default="scope" buttons
60
+ @save="onSave(props.row.my_favorite_id, { 'path': $event })">
61
+ <q-input v-model="scope.value" dense autofocus counter @keyup.enter="scope.set" />
62
+ </q-popup-edit>
63
+ </q-td>
64
+ </template>
65
+
66
+ <template #body-cell-icon="props">
67
+ <q-td key="icon">
68
+ <l-icon-picker v-model="props.row.icon" flat round @update:model-value="onSave(
69
+ props.row.my_favorite_id, { 'icon': $event })"></l-icon-picker>
70
+ </q-td>
71
+ </template>
72
+
73
+ </q-table>
74
+ </template>
@@ -23,7 +23,10 @@ const route = useRoute()
23
23
  replace />
24
24
  <q-route-tab name="bio" icon="sym_o_fingerprint" :label="$t('Bio')" to="/User/setting/bio-auth"
25
25
  exact replace />
26
- <q-route-tab name="openid" icon="sym_o_key" :label="$t('Open ID')" to="/User/setting/open_id" exact replace />
26
+ <q-route-tab name="openid" icon="sym_o_key" :label="$t('Open ID')" to="/User/setting/open_id" exact
27
+ replace />
28
+ <q-route-tab name="myfav" icon="sym_o_star" :label="$t('My favorite')"
29
+ to="/User/setting/my_favorite" exact replace />
27
30
 
28
31
  </q-tabs>
29
32
  </template>
@@ -131,6 +131,11 @@ function User_setting_information() {
131
131
  /* webpackChunkName: "User-setting-information" */ './pages/User/setting/information.vue'
132
132
  )
133
133
  }
134
+ function User_setting_my_favorite() {
135
+ return import(
136
+ /* webpackChunkName: "User-setting-my_favorite" */ './pages/User/setting/my_favorite.vue'
137
+ )
138
+ }
134
139
  function User_setting_open_id() {
135
140
  return import(
136
141
  /* webpackChunkName: "User-setting-open_id" */ './pages/User/setting/open_id.vue'
@@ -342,6 +347,11 @@ export default [
342
347
  path: 'information',
343
348
  component: User_setting_information,
344
349
  },
350
+ {
351
+ name: 'User-setting-my_favorite',
352
+ path: 'my_favorite',
353
+ component: User_setting_my_favorite,
354
+ },
345
355
  {
346
356
  name: 'User-setting-open_id',
347
357
  path: 'open_id',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostlink/nuxt-light",
3
- "version": "1.2.1",
3
+ "version": "1.3.1",
4
4
  "description": "HostLink Nuxt Light Framework",
5
5
  "repository": "@hostlink/nuxt-light",
6
6
  "license": "MIT",