@hostlink/nuxt-light 0.0.108 → 0.0.110

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.108"
4
+ "version": "0.0.110"
5
5
  }
@@ -1,12 +1,11 @@
1
1
  <script setup>
2
- import { computed, ref, useSlots, useAttrs } from "vue";
2
+ import { computed, ref, useAttrs } from "vue";
3
3
  import { useI18n } from 'vue-i18n';
4
4
  import tc2sc from "../lib/tc2sc";
5
5
  import { useLight } from '../';
6
6
 
7
7
  const i18n = useI18n();
8
8
  const light = useLight();
9
- const slots = useSlots();
10
9
 
11
10
  const props = defineProps({
12
11
  modelValue: {
@@ -38,11 +37,13 @@ const props = defineProps({
38
37
  });
39
38
  const emit = defineEmits(["update:modelValue"]);
40
39
 
40
+ //clone rules to new_rules
41
41
  const new_rules = props.rules || [];
42
42
 
43
+
43
44
  //has required prop (in properties)
44
- if (props.required) {
45
- new_rules.push(val => !!val || i18n.t('input_required',[i18n.t(props.label)]));
45
+ if (props.required || (new_rules.indexOf("required") >= 0)) {
46
+ new_rules.push(val => !!val || i18n.t('input_required', [i18n.t(props.label)]));
46
47
  }
47
48
 
48
49
  if (props.type == "email") {
@@ -53,6 +54,57 @@ if (props.type == "email") {
53
54
  });
54
55
  }
55
56
 
57
+ if (new_rules.indexOf("containUpper") >= 0) {
58
+ new_rules.push(val => {
59
+ if (val && !val.match(/[A-Z]/)) {
60
+ return i18n.t("Must contain at least one uppercase letter");
61
+ }
62
+ });
63
+ }
64
+
65
+ if (new_rules.indexOf("containLower") >= 0) {
66
+ new_rules.push(val => {
67
+ if (val && !val.match(/[a-z]/)) {
68
+ return i18n.t("Must contain at least one lowercase letter");
69
+ }
70
+ });
71
+ }
72
+
73
+ if (new_rules.indexOf("containNumber") >= 0) {
74
+ new_rules.push(val => {
75
+ if (val && !val.match(/[0-9]/)) {
76
+ return i18n.t("Must contain at least one number");
77
+ }
78
+ });
79
+ }
80
+
81
+ if (new_rules.indexOf("containSpecial") >= 0) {
82
+ new_rules.push(val => {
83
+ if (val && !val.match(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/)) {
84
+ return i18n.t("Must contain at least one symbol");
85
+ }
86
+ });
87
+ }
88
+
89
+ //find mniLength:x in rules
90
+ const minLength = new_rules.find(rule => {
91
+ if (typeof rule != "string") return false;
92
+ return rule.startsWith("minLength:")
93
+ });
94
+
95
+ if (minLength) {
96
+ const min = parseInt(minLength.replace("minLength:", ""));
97
+ new_rules.push(val => {
98
+ if (val && val.length < min) {
99
+ return i18n.t("input_min", [min]);
100
+ }
101
+ });
102
+ }
103
+
104
+
105
+
106
+
107
+
56
108
 
57
109
  const localValue = computed({
58
110
  get: () => props.modelValue,
@@ -100,8 +152,6 @@ const onClickTc2Sc = () => {
100
152
  localValue.value = tc2sc(localValue.value);
101
153
  }
102
154
 
103
-
104
-
105
155
  const attrs = {
106
156
  ...{
107
157
  filled: light.getStyle("inputFilled", false),
@@ -636,7 +636,7 @@ const getCellClass = (col: any, row: any) => {
636
636
 
637
637
  <template v-if="!col.searchType">
638
638
  <q-input dense clearable v-model="filters[col.name]" @keydown.enter.prevent="onFilters"
639
- @clear="onFilters"></q-input>
639
+ @clear="onFilters" enterkeyhint="search"></q-input>
640
640
 
641
641
  </template>
642
642
 
@@ -11,6 +11,7 @@
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}",
15
- "input_required": "Please input {0}"
14
+ "storage_usage": "{0} free of {1}",
15
+ "input_required": "Please input {0}",
16
+ "input_min": "Please input at least {0} characters"
16
17
  }
@@ -160,6 +160,6 @@
160
160
  "input_required": "{0}為必填",
161
161
  "Invalid email format": "電郵格式錯誤",
162
162
  "No data available": "沒有資料",
163
- "Loading...": "載入中..."
164
-
163
+ "Loading...": "載入中...",
164
+ "input_min": "最少{0}個字"
165
165
  }
@@ -40,7 +40,7 @@ const onCickView = async (id) => {
40
40
  </script>
41
41
  <template>
42
42
  <l-page>
43
- <q-table flat :columns="columns" :rows="users">
43
+ <q-table flat :columns="columns" :rows="users" :rows-per-page-options="[0]">
44
44
  <template #body-cell-view="props">
45
45
  <q-td :props="props">
46
46
  <q-btn rounded outline color="primary" @click="onCickView(props.row.user_id)" label="view"
@@ -1,35 +1,20 @@
1
1
  <script setup>
2
- import { q } from '../../../'
2
+ import { q, m } from '../../../'
3
3
  import { useRouter, useRoute } from "vue-router"
4
4
  import { reactive } from "vue"
5
5
  const system = await q("system", ["passwordPolicy"]);
6
- const rules = system.passwordPolicy.map((rule) => {
7
- let s = rule.split(":");
8
-
9
- switch (s[0]) {
10
- case "required":
11
- return (v) => !!v || "Required";
12
- case "containUpper":
13
- return (v) => /[A-Z]/.test(v) || "Must contain at least one uppercase letter";
14
- case "containLower":
15
- return (v) => /[a-z]/.test(v) || "Must contain at least one lowercase letter";
16
- case "containNumber":
17
- return (v) => /[0-9]/.test(v) || "Must contain at least one number";
18
- case "containSpecial":
19
- return (v) => /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(v) || "Must contain at least one special character";
20
- case "minLength":
21
- return (v) => v.length >= parseInt(s[1]) || `Must be at least ${s[1]} characters`;
22
- }
23
- })
24
6
  const router = useRouter();
25
7
  const route = useRoute();
26
- const obj = reactive({
27
- id: parseInt(route.params.user_id)
28
- })
29
8
 
9
+ const obj = reactive({
10
+ password: "",
11
+ });
30
12
 
31
13
  const onUpdatePassword = async () => {
32
- if (await m("changeUserPassword", obj)) {
14
+ if (await m("updateUserPassword", {
15
+ id: route.params.user_id,
16
+ password: obj.password
17
+ })) {
33
18
  router.push("/User");
34
19
  }
35
20
  }
@@ -38,7 +23,7 @@ const onUpdatePassword = async () => {
38
23
  <template>
39
24
  <l-page>
40
25
  <l-form @save="onUpdatePassword">
41
- <l-input type="password" label="New password" :rules="rules" v-model="obj.password">
26
+ <l-input type="password" label="New password" v-model="obj.password" :rules="system.passwordPolicy">
42
27
  </l-input>
43
28
  </l-form>
44
29
 
@@ -18,6 +18,7 @@ roles = roles.map((role) => {
18
18
  };
19
19
  });
20
20
 
21
+ const system = await q("system", ["passwordPolicy"]);
21
22
  </script>
22
23
  <template>
23
24
  <l-page>
@@ -25,7 +26,8 @@ roles = roles.map((role) => {
25
26
  <l-row>
26
27
  <l-col md="6" gutter="md">
27
28
  <l-input label="Username" v-model="obj.username" required />
28
- <l-input label="Password" v-model="obj.password" required type="password" />
29
+ <l-input label="Password" v-model="obj.password" required type="password"
30
+ :rules="system.passwordPolicy" />
29
31
  <l-input label="First name" v-model="obj.first_name" required />
30
32
  <l-input label="Last name" v-model="obj.last_name" />
31
33
  <l-input label="Email" v-model="obj.email" required type="email" />
@@ -3,6 +3,8 @@ import { reactive } from "vue"
3
3
  import { notify } from '../../../'
4
4
  import { updatePassword } from "@hostlink/light"
5
5
 
6
+ import { q } from "#imports"
7
+
6
8
  const obj = reactive({
7
9
  old_password: "",
8
10
  new_password: "",
@@ -17,16 +19,24 @@ const onSave = async () => {
17
19
  }
18
20
  }
19
21
 
22
+ const system = await q("system", ["passwordPolicy"])
23
+
20
24
  </script>
21
25
  <template>
22
26
  <l-form @save="onSave" :bordered="false">
23
- <l-input label="Old password" v-model="obj.old_password" type="password"
24
- :rules="[v => !!v || 'Old password is required']" />
25
- <l-input label="New password" v-model="obj.new_password" type="password"
26
- :rules="[v => !!v || 'New password is required']" />
27
+ <l-input label="Old password" v-model="obj.old_password" type="password" required />
28
+ <l-input label="New password" v-model="obj.new_password" type="password" :rules="system.passwordPolicy" />
27
29
  <l-input label="Confirm password" v-model="obj.confirm_password" type="password" :rules="[
28
- v => !!v || 'Confirm password is required',
29
30
  v => v == obj.new_password || 'Confirm password does not match'
30
31
  ]" />
31
32
  </l-form>
33
+
34
+ <div>
35
+ <div>Password policy</div>
36
+ <ul>
37
+ <li v-for="rule in system.passwordPolicy" :key="rule">
38
+ {{ rule }}
39
+ </li>
40
+ </ul>
41
+ </div>
32
42
  </template>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostlink/nuxt-light",
3
- "version": "0.0.108",
3
+ "version": "0.0.110",
4
4
  "description": "HostLink Nuxt Light Framework",
5
5
  "repository": "@hostlink/nuxt-light",
6
6
  "license": "MIT",