@hostlink/nuxt-light 0.0.114 → 0.0.115
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 +1 -1
- package/dist/runtime/components/l-file.vue +19 -2
- package/dist/runtime/components/l-input.vue +10 -2
- package/dist/runtime/components/l-table.vue +9 -9
- package/dist/runtime/components/l-time-picker.vue +17 -2
- package/dist/runtime/formkit/Checkbox.vue +27 -0
- package/dist/runtime/formkit/DatePicker.vue +25 -0
- package/dist/runtime/formkit/FilePicker.vue +33 -0
- package/dist/runtime/formkit/Form.vue +72 -0
- package/dist/runtime/formkit/Input.vue +35 -0
- package/dist/runtime/formkit/OptionGroup.vue +22 -0
- package/dist/runtime/formkit/Radio.vue +22 -0
- package/dist/runtime/formkit/Repeater.vue +107 -0
- package/dist/runtime/formkit/Select.vue +25 -0
- package/dist/runtime/formkit/TimePicker.vue +25 -0
- package/dist/runtime/formkit/index.d.ts +2 -0
- package/dist/runtime/formkit/index.mjs +79 -0
- package/dist/runtime/pages/Role/add.vue +8 -12
- package/dist/runtime/pages/User/_user_id/change-password.vue +9 -17
- package/dist/runtime/pages/User/_user_id/update-role.vue +7 -8
- package/dist/runtime/pages/User/add.vue +66 -43
- package/dist/runtime/pages/User/setting/index.vue +19 -9
- package/dist/runtime/pages/User/setting/information.vue +19 -18
- package/dist/runtime/pages/User/setting/open_id.vue +4 -1
- package/dist/runtime/pages/User/setting/password.vue +26 -23
- package/dist/runtime/pages/User/setting/style.vue +2 -2
- package/dist/runtime/plugin.mjs +15 -0
- package/package.json +2 -1
package/dist/module.json
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { ref, computed } from "vue";
|
|
2
|
+
import { ref, computed, useAttrs } from "vue";
|
|
3
|
+
import { useLight } from '../';
|
|
4
|
+
|
|
5
|
+
const light = useLight();
|
|
6
|
+
|
|
3
7
|
const props = defineProps({
|
|
4
8
|
modelValue: {
|
|
5
9
|
type: String
|
|
@@ -21,9 +25,22 @@ const localValue = computed({
|
|
|
21
25
|
set: (value) => emit("update:modelValue", value),
|
|
22
26
|
})
|
|
23
27
|
|
|
28
|
+
const attrs = {
|
|
29
|
+
|
|
30
|
+
...{
|
|
31
|
+
filled: light.getStyle("inputFilled"),
|
|
32
|
+
outlined: light.getStyle("inputOutlined"),
|
|
33
|
+
standout: light.getStyle("inputStandout"),
|
|
34
|
+
rounded: light.getStyle("inputRounded"),
|
|
35
|
+
dense: light.getStyle("inputDense"),
|
|
36
|
+
square: light.getStyle("inputSquare"),
|
|
37
|
+
stackLabel: light.getStyle("inputStackLabel")
|
|
38
|
+
},
|
|
39
|
+
...useAttrs(),
|
|
40
|
+
}
|
|
24
41
|
</script>
|
|
25
42
|
<template>
|
|
26
|
-
<q-input v-model="localValue">
|
|
43
|
+
<q-input v-bind="attrs" v-model="localValue">
|
|
27
44
|
<q-dialog v-model="show" full-height full-width>
|
|
28
45
|
<l-file-manager closable @close="show = false" @input="onInput"></l-file-manager>
|
|
29
46
|
</q-dialog>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, ref, useAttrs } from "vue";
|
|
2
|
+
import { computed, ref, useAttrs, useSlots } from "vue";
|
|
3
3
|
import { useI18n } from 'vue-i18n';
|
|
4
4
|
import tc2sc from "../lib/tc2sc";
|
|
5
5
|
import { useLight } from '../';
|
|
@@ -164,12 +164,17 @@ const attrs = {
|
|
|
164
164
|
},
|
|
165
165
|
...useAttrs(),
|
|
166
166
|
}
|
|
167
|
+
|
|
168
|
+
const ss = Object.entries(useSlots()).map(([key, value]) => {
|
|
169
|
+
return key;
|
|
170
|
+
});
|
|
171
|
+
|
|
167
172
|
</script>
|
|
168
173
|
<template>
|
|
169
174
|
<q-input v-bind="attrs" :label="localLabel" v-model="localValue" :rules="new_rules" hide-bottom-space :type="localType">
|
|
170
175
|
<template v-if="translate" #prepend>
|
|
171
176
|
<q-btn icon="sym_o_translate" flat dense rounded>
|
|
172
|
-
<q-menu
|
|
177
|
+
<q-menu dense>
|
|
173
178
|
<q-list>
|
|
174
179
|
<q-item clickable v-close-popup @click="onClickTc2Sc">
|
|
175
180
|
<q-item-section>繁轉簡</q-item-section>
|
|
@@ -177,7 +182,10 @@ const attrs = {
|
|
|
177
182
|
</q-list>
|
|
178
183
|
</q-menu>
|
|
179
184
|
</q-btn>
|
|
185
|
+
</template>
|
|
180
186
|
|
|
187
|
+
<template v-for="s in ss" v-slot:[s]="props" :key="s">
|
|
188
|
+
<slot :name="s" v-bind="props ?? {}"></slot>
|
|
181
189
|
</template>
|
|
182
190
|
|
|
183
191
|
<template v-if="localShowPassword" v-slot:append>
|
|
@@ -618,25 +618,25 @@ const getCellClass = (col: any, row: any) => {
|
|
|
618
618
|
<template v-if="col.searchable">
|
|
619
619
|
|
|
620
620
|
<template v-if="col.searchType == 'number'">
|
|
621
|
-
<q-input dense clearable v-model.number="filters[col.name]"
|
|
622
|
-
@clear="onFilters" mask="##########"></q-input>
|
|
621
|
+
<q-input dense clearable filled square v-model.number="filters[col.name]"
|
|
622
|
+
@keydown.enter.prevent="onFilters" @clear="onFilters" mask="##########"></q-input>
|
|
623
623
|
</template>
|
|
624
624
|
|
|
625
625
|
<template v-if="col.searchType == 'select'">
|
|
626
|
-
<q-select dense v-model="filters[col.name]"
|
|
627
|
-
options-dense :options="col.searchOptions" emit-value
|
|
628
|
-
:multiple="col.searchMultiple" />
|
|
626
|
+
<q-select dense clearable filled square v-model="filters[col.name]"
|
|
627
|
+
@update:model-value="onFilters" options-dense :options="col.searchOptions" emit-value
|
|
628
|
+
map-options :multiple="col.searchMultiple" />
|
|
629
629
|
|
|
630
630
|
</template>
|
|
631
631
|
|
|
632
632
|
<template v-if="col.searchType == 'date'">
|
|
633
|
-
<l-date-picker :outlined="false" hide-bottom-space
|
|
634
|
-
@update:model-value="onFilters"
|
|
633
|
+
<l-date-picker dense clearable filled square :outlined="false" hide-bottom-space
|
|
634
|
+
v-model="filters[col.name]" @update:model-value="onFilters" range @clear="onFilters" />
|
|
635
635
|
</template>
|
|
636
636
|
|
|
637
637
|
<template v-if="!col.searchType">
|
|
638
|
-
<q-input dense clearable v-model="filters[col.name]"
|
|
639
|
-
@clear="onFilters" enterkeyhint="search"></q-input>
|
|
638
|
+
<q-input dense clearable filled square v-model="filters[col.name]"
|
|
639
|
+
@keydown.enter.prevent="onFilters" @clear="onFilters" enterkeyhint="search"></q-input>
|
|
640
640
|
|
|
641
641
|
</template>
|
|
642
642
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, ref } from "vue";
|
|
2
|
+
import { computed, ref, useAttrs } from "vue";
|
|
3
|
+
import { useLight } from '../';
|
|
4
|
+
const light = useLight();
|
|
5
|
+
|
|
3
6
|
const props = defineProps({
|
|
4
7
|
modelValue: {
|
|
5
8
|
type: [String, Object],
|
|
@@ -35,11 +38,23 @@ if (props.required) {
|
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
|
|
41
|
+
const attrs = {
|
|
42
|
+
...{
|
|
43
|
+
filled: light.getStyle("inputFilled"),
|
|
44
|
+
outlined: light.getStyle("inputOutlined"),
|
|
45
|
+
standout: light.getStyle("inputStandout"),
|
|
46
|
+
rounded: light.getStyle("inputRounded"),
|
|
47
|
+
dense: light.getStyle("inputDense"),
|
|
48
|
+
square: light.getStyle("inputSquare"),
|
|
49
|
+
stackLabel: light.getStyle("inputStackLabel")
|
|
50
|
+
},
|
|
51
|
+
...useAttrs(),
|
|
52
|
+
}
|
|
38
53
|
|
|
39
54
|
|
|
40
55
|
</script>
|
|
41
56
|
<template>
|
|
42
|
-
<q-input v-model="localValue" mask="time" :rules="rules" :label="$t(label)" :hint="$t(hint)">
|
|
57
|
+
<q-input v-bind="attrs" v-model="localValue" mask="time" :rules="rules" :label="$t(label)" :hint="$t(hint)">
|
|
43
58
|
<template v-slot:prepend>
|
|
44
59
|
<q-btn icon="sym_o_access_time" round dense flat>
|
|
45
60
|
<q-popup-proxy cover transition-show="scale" transition-hide="scale" ref="popup">
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { getErrorMessage } from 'formkit-quasar';
|
|
3
|
+
import { computed, useSlots } from 'vue'
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
context: Object
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
const value = computed({
|
|
9
|
+
get: () => props.context.value,
|
|
10
|
+
set: (val) => props.context.node.input(val)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const ss = Object.entries(useSlots()).map(([key, value]) => {
|
|
14
|
+
return key;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const { error, errorMessage } = getErrorMessage(props.context.node);
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
</script>
|
|
21
|
+
<template>
|
|
22
|
+
<l-checkbox v-model="value" :label="context.label" v-bind="context.attrs" :error="error" :error-message="errorMessage">
|
|
23
|
+
<template v-for="s in ss" v-slot:[s]="props" :key="s">
|
|
24
|
+
<slot :name="s" v-bind="props ?? {}"></slot>
|
|
25
|
+
</template>
|
|
26
|
+
</l-checkbox>
|
|
27
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, useSlots } from 'vue'
|
|
3
|
+
import { getErrorMessage } from 'formkit-quasar';
|
|
4
|
+
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
context: Object
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const { error, errorMessage } = getErrorMessage(props.context.node);
|
|
10
|
+
|
|
11
|
+
const value = computed({
|
|
12
|
+
get: () => props.context.value,
|
|
13
|
+
set: (val) => props.context.node.input(val)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const ss = Object.entries(useSlots()).map(([key]) => key);
|
|
17
|
+
</script>
|
|
18
|
+
<template>
|
|
19
|
+
<l-date-picker v-model="value" :label="context.label" v-bind="context.attrs" :error="error" :type="context.inputType"
|
|
20
|
+
:error-message="errorMessage">
|
|
21
|
+
<template v-for="s in ss" v-slot:[s]="props" :key="s">
|
|
22
|
+
<slot :name="s" v-bind="props ?? {}"></slot>
|
|
23
|
+
</template>
|
|
24
|
+
</l-date-picker>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, useSlots } from 'vue'
|
|
3
|
+
import { getErrorMessage } from 'formkit-quasar';
|
|
4
|
+
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
context: Object
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const { error, errorMessage } = getErrorMessage(props.context.node);
|
|
10
|
+
|
|
11
|
+
const value = computed({
|
|
12
|
+
get: () => props.context.value,
|
|
13
|
+
set: (val) => props.context.node.input(val)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const ss = Object.entries(useSlots()).map(([key]) => key);
|
|
17
|
+
|
|
18
|
+
const onBlur = () => {
|
|
19
|
+
if (errorMessage.value) {
|
|
20
|
+
error.value = true
|
|
21
|
+
} else {
|
|
22
|
+
error.value = false
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
</script>
|
|
26
|
+
<template>
|
|
27
|
+
<l-file v-model="value" :label="context.label" v-bind="context.attrs" :error="error" :type="context.inputType"
|
|
28
|
+
:error-message="errorMessage" @blur="onBlur">
|
|
29
|
+
<template v-for="s in ss" v-slot:[s]="props" :key="s">
|
|
30
|
+
<slot :name="s" v-bind="props ?? {}"></slot>
|
|
31
|
+
</template>
|
|
32
|
+
</l-file>
|
|
33
|
+
</template>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { useRouter, useRoute } from "vue-router";
|
|
4
|
+
import { Dialog } from "quasar";
|
|
5
|
+
import { model } from "@hostlink/light"
|
|
6
|
+
|
|
7
|
+
const route = useRoute();
|
|
8
|
+
const router = useRouter();
|
|
9
|
+
|
|
10
|
+
let props = defineProps({
|
|
11
|
+
context: Object
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
let onSubmit = async () => {
|
|
15
|
+
props.context.handlers.submit(new Event("submit"));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const gutter = props.gutter ?? "md";
|
|
19
|
+
|
|
20
|
+
//check bordered is undefined
|
|
21
|
+
let bordered = true;
|
|
22
|
+
if (props.context.bordered !== undefined) {
|
|
23
|
+
bordered = props.context.bordered;
|
|
24
|
+
}
|
|
25
|
+
const loading = ref(false);
|
|
26
|
+
if (!props.context.onSubmit) {
|
|
27
|
+
props.context.node.props.onSubmit = async function () {
|
|
28
|
+
loading.value = true;
|
|
29
|
+
const [module, id_name] = route.name.split("-");
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
if (route.params[id_name]) {//edit
|
|
33
|
+
if (await model(module).update(parseInt(route.params[id_name]), props.context.value)) {
|
|
34
|
+
router.go(-1);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
if (await model(module).add(props.context.value)) {
|
|
39
|
+
router.go(-1);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
Dialog.create({
|
|
45
|
+
title: "Error",
|
|
46
|
+
message: e.message,
|
|
47
|
+
ok: "OK"
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
loading.value = false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
</script>
|
|
57
|
+
<template>
|
|
58
|
+
<form v-bind="context.attrs">
|
|
59
|
+
<l-card :bordered="bordered">
|
|
60
|
+
<q-card-section>
|
|
61
|
+
<div :class="`q-gutter-${gutter}`">
|
|
62
|
+
<slot v-bind="context"></slot>
|
|
63
|
+
</div>
|
|
64
|
+
</q-card-section>
|
|
65
|
+
|
|
66
|
+
<q-card-actions align="right">
|
|
67
|
+
<l-btn color="primary" icon="sym_o_check" label="Submit" @click="onSubmit" :disabled="!context.state.dirty"
|
|
68
|
+
:loading="loading"></l-btn>
|
|
69
|
+
</q-card-actions>
|
|
70
|
+
</l-card>
|
|
71
|
+
</form>
|
|
72
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, useSlots } from 'vue'
|
|
3
|
+
import { getErrorMessage } from 'formkit-quasar';
|
|
4
|
+
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
context: Object
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const { error, errorMessage } = getErrorMessage(props.context.node);
|
|
10
|
+
|
|
11
|
+
const value = computed({
|
|
12
|
+
get: () => props.context.value,
|
|
13
|
+
set: (val) => props.context.node.input(val)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const ss = Object.entries(useSlots()).map(([key]) => key);
|
|
17
|
+
|
|
18
|
+
const onBlur = () => {
|
|
19
|
+
if (errorMessage.value) {
|
|
20
|
+
error.value = true
|
|
21
|
+
} else {
|
|
22
|
+
error.value = false
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
</script>
|
|
28
|
+
<template>
|
|
29
|
+
<l-input v-model="value" :label="context.label" v-bind="context.attrs" :error="error" :type="context.inputType"
|
|
30
|
+
:error-message="errorMessage" @blur="onBlur">
|
|
31
|
+
<template v-for="s in ss" v-slot:[s]="props" :key="s">
|
|
32
|
+
<slot :name="s" v-bind="props ?? {}"></slot>
|
|
33
|
+
</template>
|
|
34
|
+
</l-input>
|
|
35
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { getErrorMessage } from 'formkit-quasar';
|
|
4
|
+
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
context: Object
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const { error, errorMessage } = getErrorMessage(props.context.node);
|
|
10
|
+
|
|
11
|
+
const value = computed({
|
|
12
|
+
get: () => props.context.value,
|
|
13
|
+
set: (val) => props.context.node.input(val)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
</script>
|
|
17
|
+
<template>
|
|
18
|
+
<l-field label="Roles" stack-label :label="context.label" :error="error" :error-message="errorMessage">
|
|
19
|
+
<q-option-group type="checkbox" :options="context.options" v-model="value" inline v-bind="context.attrs">
|
|
20
|
+
</q-option-group>
|
|
21
|
+
</l-field>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { getErrorMessage } from 'formkit-quasar';
|
|
4
|
+
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
context: Object
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const { error, errorMessage } = getErrorMessage(props.context.node);
|
|
10
|
+
|
|
11
|
+
const value = computed({
|
|
12
|
+
get: () => props.context.value,
|
|
13
|
+
set: (val) => props.context.node.input(val)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
</script>
|
|
17
|
+
<template>
|
|
18
|
+
<q-radio v-model="value" :label="context.label" v-bind="context.attrs" :error="error" :type="context.inputType"
|
|
19
|
+
:error-message="errorMessage">
|
|
20
|
+
<slot></slot>
|
|
21
|
+
</q-radio>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, computed } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
context: Object
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
const node = props.context.node;
|
|
9
|
+
const min = props.context.node.props.min ?? 1;
|
|
10
|
+
const max = props.context.node.props.max ?? Infinity;
|
|
11
|
+
|
|
12
|
+
const localValue = ref(props.context.value)
|
|
13
|
+
|
|
14
|
+
if (localValue.value.length < min) {
|
|
15
|
+
for (let i = localValue.value.length; i < min; i++) {
|
|
16
|
+
localValue.value.push({})
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (localValue.value.length > max) {
|
|
21
|
+
localValue.value = localValue.value.slice(0, max)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const onAdd = () => {
|
|
25
|
+
if (localValue.value.length >= max) return;
|
|
26
|
+
localValue.value.push({})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const onRemove = (index) => {
|
|
30
|
+
if (localValue.value.length <= min) return;
|
|
31
|
+
localValue.value.splice(index, 1)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const onMoveUp = (index) => {
|
|
35
|
+
if (index > 0) {
|
|
36
|
+
let temp = localValue.value[index - 1]
|
|
37
|
+
localValue.value[index - 1] = localValue.value[index]
|
|
38
|
+
localValue.value[index] = temp
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const onMoveDown = (index) => {
|
|
43
|
+
if (index < localValue.value.length - 1) {
|
|
44
|
+
let temp = localValue.value[index + 1]
|
|
45
|
+
localValue.value[index + 1] = localValue.value[index]
|
|
46
|
+
localValue.value[index] = temp
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const isAllowRemove = computed(() => {
|
|
51
|
+
return localValue.value.length > min
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const isAllowMoveUp = (index) => {
|
|
55
|
+
return index > 0
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const isAllowMoveDown = (index) => {
|
|
59
|
+
return index < localValue.value.length - 1
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<template>
|
|
67
|
+
<FormKit type="list" v-model="localValue" dynamic #default="{ items, node, value }">
|
|
68
|
+
|
|
69
|
+
<FormKit type="group" v-for="(item, index) in items " :index="index" :key="item">
|
|
70
|
+
|
|
71
|
+
<q-card class="q-mb-sm" flat>
|
|
72
|
+
<q-card-section>
|
|
73
|
+
<div class="row q-col-gutter-md">
|
|
74
|
+
|
|
75
|
+
<div class="col-shrink">
|
|
76
|
+
<div class="q-mb-sm">
|
|
77
|
+
<!-- up -->
|
|
78
|
+
<q-btn type="button" @click="onMoveUp(index)" icon="sym_o_arrow_upward" color="primary"
|
|
79
|
+
dense unelevated :disable="!isAllowMoveUp(index)"/>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div class="q-mb-sm">
|
|
83
|
+
<q-btn type="button" @click="onRemove" icon="sym_o_remove" color="primary" dense unelevated
|
|
84
|
+
:disable="!isAllowRemove" />
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
<div class="q-mb-sm">
|
|
89
|
+
<!-- down -->
|
|
90
|
+
<q-btn type="button" @click="onMoveDown(index)" icon="sym_o_arrow_downward" color="primary"
|
|
91
|
+
dense unelevated :disable="!isAllowMoveDown(index)"/>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div class="col">
|
|
97
|
+
<slot></slot>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</q-card-section>
|
|
101
|
+
</q-card>
|
|
102
|
+
</FormKit>
|
|
103
|
+
|
|
104
|
+
<q-btn color="primary" @click="onAdd" icon="sym_o_add" label="Add" :disable="localValue.length >= max"
|
|
105
|
+
unelevated></q-btn>
|
|
106
|
+
</FormKit>
|
|
107
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { getErrorMessage } from 'formkit-quasar';
|
|
3
|
+
import { computed, useSlots } from 'vue'
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
context: Object
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
const { error, errorMessage } = getErrorMessage(props.context.node);
|
|
9
|
+
|
|
10
|
+
const value = computed({
|
|
11
|
+
get: () => props.context.value,
|
|
12
|
+
set: (val) => props.context.node.input(val)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const ss = Object.entries(useSlots()).map(([key, value]) => {
|
|
16
|
+
return key;
|
|
17
|
+
});
|
|
18
|
+
</script>
|
|
19
|
+
<template>
|
|
20
|
+
<l-select v-model="value" :label="context.label" v-bind="context.attrs" :error="error" :error-message="errorMessage">
|
|
21
|
+
<template v-for="s in ss" v-slot:[s]="props" :key="s">
|
|
22
|
+
<slot :name="s" v-bind="props ?? {}"></slot>
|
|
23
|
+
</template>
|
|
24
|
+
</l-select>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, useSlots } from 'vue'
|
|
3
|
+
import { getErrorMessage } from 'formkit-quasar';
|
|
4
|
+
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
context: Object
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const { error, errorMessage } = getErrorMessage(props.context.node);
|
|
10
|
+
|
|
11
|
+
const value = computed({
|
|
12
|
+
get: () => props.context.value,
|
|
13
|
+
set: (val) => props.context.node.input(val)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const ss = Object.entries(useSlots()).map(([key]) => key);
|
|
17
|
+
</script>
|
|
18
|
+
<template>
|
|
19
|
+
<l-time-picker v-model="value" :label="context.label" v-bind="context.attrs" :error="error" :type="context.inputType"
|
|
20
|
+
:error-message="errorMessage">
|
|
21
|
+
<template v-for="s in ss" v-slot:[s]="props" :key="s">
|
|
22
|
+
<slot :name="s" v-bind="props ?? {}"></slot>
|
|
23
|
+
</template>
|
|
24
|
+
</l-time-picker>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { forms, disablesChildren } from "@formkit/inputs";
|
|
2
|
+
import Input from "./Input.vue";
|
|
3
|
+
import SelectVue from "./Select.vue";
|
|
4
|
+
import RepeaterVue from "./Repeater.vue";
|
|
5
|
+
import FormVue from "./Form.vue";
|
|
6
|
+
import CheckboxVue from "./Checkbox.vue";
|
|
7
|
+
import RadioVue from "./Radio.vue";
|
|
8
|
+
import DatePickerVue from "./DatePicker.vue";
|
|
9
|
+
import TimePickerVue from "./TimePicker.vue";
|
|
10
|
+
import OptionGroupVue from "./OptionGroup.vue";
|
|
11
|
+
import FilePickerVue from "./FilePicker.vue";
|
|
12
|
+
export const createLightPlugin = () => {
|
|
13
|
+
return (node) => {
|
|
14
|
+
let type = node.props.type + "";
|
|
15
|
+
switch (type) {
|
|
16
|
+
case "l-file-picker":
|
|
17
|
+
return node.define({
|
|
18
|
+
type: "input",
|
|
19
|
+
component: FilePickerVue
|
|
20
|
+
});
|
|
21
|
+
case "l-option-group":
|
|
22
|
+
return node.define({
|
|
23
|
+
type: "input",
|
|
24
|
+
component: OptionGroupVue
|
|
25
|
+
});
|
|
26
|
+
case "l-time-picker":
|
|
27
|
+
return node.define({
|
|
28
|
+
type: "input",
|
|
29
|
+
component: TimePickerVue
|
|
30
|
+
});
|
|
31
|
+
case "l-date-picker":
|
|
32
|
+
return node.define({
|
|
33
|
+
type: "input",
|
|
34
|
+
component: DatePickerVue
|
|
35
|
+
});
|
|
36
|
+
case "l-radio":
|
|
37
|
+
return node.define({
|
|
38
|
+
type: "input",
|
|
39
|
+
component: RadioVue
|
|
40
|
+
});
|
|
41
|
+
case "l-checkbox":
|
|
42
|
+
return node.define({
|
|
43
|
+
type: "input",
|
|
44
|
+
component: CheckboxVue
|
|
45
|
+
});
|
|
46
|
+
case "l-input":
|
|
47
|
+
return node.define({
|
|
48
|
+
type: "input",
|
|
49
|
+
props: ["inputType"],
|
|
50
|
+
component: Input
|
|
51
|
+
});
|
|
52
|
+
case "l-select":
|
|
53
|
+
return node.define({
|
|
54
|
+
type: "input",
|
|
55
|
+
component: SelectVue
|
|
56
|
+
});
|
|
57
|
+
case "l-repeater":
|
|
58
|
+
return node.define({
|
|
59
|
+
type: "list",
|
|
60
|
+
props: ["min", "max"],
|
|
61
|
+
component: RepeaterVue
|
|
62
|
+
});
|
|
63
|
+
case "l-form":
|
|
64
|
+
return node.define({
|
|
65
|
+
type: "group",
|
|
66
|
+
component: FormVue,
|
|
67
|
+
props: [
|
|
68
|
+
"submitLabel",
|
|
69
|
+
"submit",
|
|
70
|
+
"actions",
|
|
71
|
+
"onSubmit",
|
|
72
|
+
"gutter",
|
|
73
|
+
"bordered"
|
|
74
|
+
],
|
|
75
|
+
features: [forms, disablesChildren]
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
};
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { reactive } from 'vue'
|
|
3
2
|
import { q } from '../../'
|
|
4
|
-
const obj = reactive({
|
|
5
|
-
childs: ["Users"],
|
|
6
|
-
})
|
|
7
3
|
|
|
8
4
|
let roles = await q("listRole", ["name"]);
|
|
9
5
|
roles = roles.map((role) => {
|
|
@@ -13,18 +9,18 @@ roles = roles.map((role) => {
|
|
|
13
9
|
};
|
|
14
10
|
});
|
|
15
11
|
|
|
12
|
+
const onSubmit = (e) => {
|
|
13
|
+
e.preventDefault();
|
|
14
|
+
console.log("submit");
|
|
15
|
+
}
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
18
|
<template>
|
|
19
19
|
<l-page>
|
|
20
|
-
<l-form
|
|
21
|
-
<l-input
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
</q-option-group>
|
|
25
|
-
</q-field>
|
|
26
|
-
|
|
27
|
-
</l-form>
|
|
20
|
+
<FormKit type="l-form" :value="{ childs: ['Users'] }" >
|
|
21
|
+
<FormKit type="l-input" name="name" label="Name" validation="required" />
|
|
22
|
+
<FormKit type="l-option-group" :options="roles" name="childs" label="Child" />
|
|
23
|
+
</FormKit>
|
|
28
24
|
|
|
29
25
|
</l-page>
|
|
30
26
|
</template>
|
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { q, m } from '../../../'
|
|
3
|
-
import { useRouter
|
|
4
|
-
import { reactive } from "vue"
|
|
3
|
+
import { useRouter } from "vue-router"
|
|
5
4
|
const system = await q("system", ["passwordPolicy"]);
|
|
6
5
|
const router = useRouter();
|
|
7
|
-
const route = useRoute();
|
|
8
6
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
const onUpdatePassword = async () => {
|
|
14
|
-
if (await m("updateUserPassword", {
|
|
7
|
+
const onSubmit = async (data, form) => {
|
|
8
|
+
return await m("updateUserPassword", {
|
|
15
9
|
id: route.params.user_id,
|
|
16
|
-
password:
|
|
17
|
-
})) {
|
|
10
|
+
password: data.password
|
|
11
|
+
}).then(() => {
|
|
18
12
|
router.push("/User");
|
|
19
|
-
}
|
|
13
|
+
});
|
|
20
14
|
}
|
|
21
15
|
|
|
22
16
|
</script>
|
|
23
17
|
<template>
|
|
24
18
|
<l-page>
|
|
25
|
-
<l-form @
|
|
26
|
-
<l-input
|
|
27
|
-
|
|
28
|
-
</l-form>
|
|
29
|
-
|
|
19
|
+
<FormKit type="l-form" @submit="onSubmit">
|
|
20
|
+
<FormKit type="l-input" name="password" :validation="system.passwordPolicy" label="Password" input-type="password"></FormKit>
|
|
21
|
+
</FormKit>
|
|
30
22
|
</l-page>
|
|
31
23
|
</template>
|
|
@@ -18,11 +18,11 @@ roles = roles.map((role) => {
|
|
|
18
18
|
};
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
const submit = async () => {
|
|
21
|
+
const submit = async (data, form) => {
|
|
22
22
|
|
|
23
23
|
if (await m("updateUserRole", {
|
|
24
24
|
user_id: obj.user_id,
|
|
25
|
-
roles:
|
|
25
|
+
roles: data.roles
|
|
26
26
|
})) {
|
|
27
27
|
//show success message
|
|
28
28
|
|
|
@@ -41,12 +41,11 @@ const submit = async () => {
|
|
|
41
41
|
</script>
|
|
42
42
|
<template>
|
|
43
43
|
<l-page>
|
|
44
|
-
<l-form @submit="submit">
|
|
45
|
-
<l-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
</l-form>
|
|
44
|
+
<FormKit type="l-form" @submit="submit" :value="{ roles: obj.roles }">
|
|
45
|
+
<FormKit type="l-option-group" :options="roles" name="roles">
|
|
46
|
+
</FormKit>
|
|
47
|
+
</FormKit>
|
|
48
|
+
|
|
50
49
|
|
|
51
50
|
</l-page>
|
|
52
51
|
</template>
|
|
@@ -1,71 +1,94 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { reactive } from "vue"
|
|
3
|
+
import { useRouter } from "vue-router";
|
|
4
|
+
import { model } from "@hostlink/light";
|
|
3
5
|
import { q } from '../../'
|
|
6
|
+
const router = useRouter()
|
|
4
7
|
const obj = reactive({
|
|
5
|
-
|
|
8
|
+
username: null,
|
|
9
|
+
password: null,
|
|
10
|
+
first_name: null,
|
|
11
|
+
last_name: null,
|
|
12
|
+
email: null,
|
|
13
|
+
phone: null,
|
|
14
|
+
addr1: null,
|
|
15
|
+
addr2: null,
|
|
16
|
+
addr3: null,
|
|
17
|
+
join_date: new Date().toISOString().substring(0, 10), //YYYY-MM-DD (today)
|
|
18
|
+
expiry_date: null,
|
|
6
19
|
status: 0,
|
|
7
20
|
language: "en",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
21
|
+
default_page: null,
|
|
22
|
+
roles: ['Users'],
|
|
11
23
|
})
|
|
12
24
|
|
|
13
|
-
let
|
|
14
|
-
|
|
25
|
+
let { system, listRole } = await q({
|
|
26
|
+
system: {
|
|
27
|
+
passwordPolicy: true,
|
|
28
|
+
},
|
|
29
|
+
listRole: {
|
|
30
|
+
name: true,
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
const roles = listRole.map((role) => {
|
|
15
34
|
return {
|
|
16
35
|
label: role.name,
|
|
17
36
|
value: role.name,
|
|
18
37
|
};
|
|
19
38
|
});
|
|
20
39
|
|
|
21
|
-
|
|
40
|
+
|
|
41
|
+
const options = [
|
|
42
|
+
{ label: 'Active', value: 0 },
|
|
43
|
+
{ label: 'Inactive', value: 1 }
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
const languages = [
|
|
47
|
+
{ label: 'English', value: 'en' },
|
|
48
|
+
{ label: '中文', value: 'zh-hk' }
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
const onSubmit = async (data) => {
|
|
52
|
+
return model("User").add(data).then((res) => {
|
|
53
|
+
router.push("/User");
|
|
54
|
+
}).catch((err) => {
|
|
55
|
+
console.log(err)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
22
59
|
</script>
|
|
23
60
|
<template>
|
|
24
61
|
<l-page>
|
|
25
|
-
<l-form
|
|
62
|
+
<FormKit type="l-form" :value="obj" @submit="onSubmit">
|
|
26
63
|
<l-row>
|
|
27
64
|
<l-col md="6" gutter="md">
|
|
28
|
-
<l-input label="Username"
|
|
29
|
-
<l-input label="Password"
|
|
30
|
-
|
|
31
|
-
<l-input label="First name"
|
|
32
|
-
<l-input label="Last name"
|
|
33
|
-
<l-input label="Email"
|
|
65
|
+
<FormKit type="l-input" label="Username" name="username" validation="required" />
|
|
66
|
+
<FormKit type="l-input" label="Password" name="password" :validation="system.passwordPolicy"
|
|
67
|
+
input-type="password" />
|
|
68
|
+
<FormKit type="l-input" label="First name" name="first_name" validation="required" />
|
|
69
|
+
<FormKit type="l-input" label="Last name" name="last_name" />
|
|
70
|
+
<FormKit type="l-input" label="Email" name="email" validation="required|email" />
|
|
34
71
|
</l-col>
|
|
72
|
+
|
|
35
73
|
<l-col md="6" gutter="md">
|
|
36
|
-
<l-input label="Phone"
|
|
37
|
-
<l-input label="Address1"
|
|
38
|
-
<l-input label="Address2"
|
|
39
|
-
<l-input label="Address3"
|
|
74
|
+
<FormKit type="l-input" label="Phone" name="phone" />
|
|
75
|
+
<FormKit type="l-input" label="Address1" name="addr1" />
|
|
76
|
+
<FormKit type="l-input" label="Address2" name="addr2" />
|
|
77
|
+
<FormKit type="l-input" label="Address3" name="addr3" />
|
|
40
78
|
</l-col>
|
|
41
|
-
<l-col gutter="md">
|
|
42
|
-
<l-date-picker label="Join date" v-model="obj.join_date" required />
|
|
43
|
-
<l-date-picker label="Expiry date" v-model="obj.expiry_date" />
|
|
44
|
-
|
|
45
|
-
<l-select label="Status" :options="[{
|
|
46
|
-
label: 'Active',
|
|
47
|
-
value: 0
|
|
48
|
-
}, {
|
|
49
|
-
label: 'Inactive',
|
|
50
|
-
value: 1
|
|
51
|
-
}]" v-model="obj.status" required></l-select>
|
|
52
|
-
|
|
53
|
-
<l-select label="Language" :options="[{
|
|
54
|
-
label: 'English',
|
|
55
|
-
value: 'en'
|
|
56
|
-
}, {
|
|
57
|
-
label: '中文',
|
|
58
|
-
value: 'zh-hk'
|
|
59
|
-
}]" v-model="obj.language" emit-value map-options required></l-select>
|
|
60
79
|
|
|
61
|
-
|
|
80
|
+
<l-col gutter="md">
|
|
81
|
+
<FormKit type="l-date-picker" label="Join date" name="join_date" validation="required" />
|
|
82
|
+
<FormKit type="l-date-picker" label="Expiry date" name="expiry_date" />
|
|
83
|
+
<FormKit type="l-select" label="Status" name="status" :options="options" validation="required" />
|
|
84
|
+
<FormKit type="l-select" label="Language" name="language" :options="languages" validation="required" />
|
|
85
|
+
<FormKit type="l-input" label="Default page" name="default_page" />
|
|
62
86
|
|
|
63
|
-
<l-
|
|
64
|
-
<q-option-group type="checkbox" :options="roles" v-model="obj.roles" inline>
|
|
65
|
-
</q-option-group>
|
|
66
|
-
</l-field>
|
|
87
|
+
<FormKit type="l-option-group" label="Roles" name="roles" :options="roles ?? []" />
|
|
67
88
|
</l-col>
|
|
68
89
|
</l-row>
|
|
69
|
-
|
|
90
|
+
|
|
91
|
+
</FormKit>
|
|
92
|
+
|
|
70
93
|
</l-page>
|
|
71
94
|
</template>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { reactive } from "vue"
|
|
3
|
+
import { reset } from "@formkit/core"
|
|
3
4
|
import { q, m, notify } from '../../../'
|
|
4
5
|
|
|
5
6
|
const obj = reactive(await q("my", ["username", "email", "first_name", "last_name"]))
|
|
@@ -18,16 +19,25 @@ const save = async () => {
|
|
|
18
19
|
} catch (e) {
|
|
19
20
|
notify(e.message, "red")
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
}
|
|
23
|
+
const onSubmit = async (data, form) => {
|
|
24
|
+
return await m("updateMy", {
|
|
25
|
+
data: {
|
|
26
|
+
email: data.email,
|
|
27
|
+
first_name: data.first_name,
|
|
28
|
+
last_name: data.last_name
|
|
29
|
+
}
|
|
30
|
+
}).then(() => {
|
|
31
|
+
notify("Your profile has been updated")
|
|
32
|
+
reset(form, data)
|
|
33
|
+
});
|
|
24
34
|
}
|
|
25
35
|
</script>
|
|
26
36
|
<template>
|
|
27
|
-
<l-form
|
|
28
|
-
<l-input label="Username"
|
|
29
|
-
<l-input label="Email"
|
|
30
|
-
<l-input label="First name"
|
|
31
|
-
<l-input label="Last name"
|
|
32
|
-
</
|
|
37
|
+
<FormKit type="l-form" :value="obj" :bordered="false" @submit="onSubmit">
|
|
38
|
+
<FormKit type="l-input" label="Username" name="username" readonly></FormKit>
|
|
39
|
+
<FormKit type="l-input" label="Email" name="email" validation="required|email"></FormKit>
|
|
40
|
+
<FormKit type="l-input" label="First name" name="first_name" validation="required"></FormKit>
|
|
41
|
+
<FormKit type="l-input" label="Last name" name="last_name"></FormKit>
|
|
42
|
+
</FormKit>
|
|
33
43
|
</template>
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import {
|
|
2
|
+
import { reset } from "@formkit/core"
|
|
3
3
|
import { q, m, notify } from '../../../'
|
|
4
|
-
const obj =
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
const obj = await q("my", ["phone", "addr1", "addr2", "addr3"])
|
|
5
|
+
const onSubmit = (data, form) => {
|
|
6
|
+
return m("updateMy", {
|
|
7
|
+
data: {
|
|
8
|
+
phone: data.phone,
|
|
9
|
+
addr1: data.addr1,
|
|
10
|
+
addr2: data.addr2,
|
|
11
|
+
addr3: data.addr3
|
|
12
|
+
}
|
|
13
|
+
}).then(() => {
|
|
10
14
|
notify("Your information has been updated")
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
notify(e.message, "red")
|
|
14
|
-
}
|
|
15
|
+
reset(form, data)
|
|
16
|
+
});
|
|
15
17
|
}
|
|
16
18
|
</script>
|
|
17
19
|
<template>
|
|
18
|
-
<l-form
|
|
19
|
-
<l-input label="Phone"
|
|
20
|
-
<l-input label="Address1"
|
|
21
|
-
<l-input label="Address2"
|
|
22
|
-
<l-input label="Address3"
|
|
23
|
-
|
|
24
|
-
</l-form>
|
|
20
|
+
<FormKit type="l-form" :value="obj" :bordered="false" @submit="onSubmit">
|
|
21
|
+
<FormKit type="l-input" label="Phone" name="phone"></FormKit>
|
|
22
|
+
<FormKit type="l-input" label="Address1" name="addr1"></FormKit>
|
|
23
|
+
<FormKit type="l-input" label="Address2" name="addr2"></FormKit>
|
|
24
|
+
<FormKit type="l-input" label="Address3" name="addr3"></FormKit>
|
|
25
|
+
</FormKit>
|
|
25
26
|
</template>
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
|
|
3
|
-
import {
|
|
2
|
+
|
|
3
|
+
import { Dialog } from 'quasar';
|
|
4
|
+
import { reset } from "@formkit/core"
|
|
4
5
|
import { updatePassword } from "@hostlink/light"
|
|
5
6
|
|
|
6
7
|
import { q } from "#imports"
|
|
7
8
|
|
|
8
|
-
const
|
|
9
|
-
old_password
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const onSubmit = async (data, form) => {
|
|
10
|
+
if (await updatePassword(data.old_password, data.new_password)) {
|
|
11
|
+
reset(form);
|
|
12
|
+
await Dialog.create({
|
|
13
|
+
title: "Password updated",
|
|
14
|
+
message: "Your password has been updated",
|
|
15
|
+
ok: "OK"
|
|
16
|
+
})
|
|
13
17
|
|
|
14
|
-
const onSave = async () => {
|
|
15
|
-
if (await updatePassword(obj.old_password, obj.new_password)) {
|
|
16
|
-
notify("Your password has been updated")
|
|
17
18
|
} else {
|
|
18
|
-
|
|
19
|
+
await Dialog.create({
|
|
20
|
+
title: "Error",
|
|
21
|
+
message: "Old password is incorrect",
|
|
22
|
+
ok: "OK"
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
|
|
19
26
|
}
|
|
20
27
|
}
|
|
21
28
|
|
|
@@ -23,20 +30,16 @@ const system = await q("system", ["passwordPolicy"])
|
|
|
23
30
|
|
|
24
31
|
</script>
|
|
25
32
|
<template>
|
|
26
|
-
<l-form
|
|
27
|
-
<l-input label="Old password"
|
|
28
|
-
<l-input label="New password"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
</
|
|
33
|
+
<FormKit type="l-form" :bordered="false" @submit="onSubmit">
|
|
34
|
+
<FormKit type="l-input" label="Old password" name="old_password" inputType="password" validation="required" />
|
|
35
|
+
<FormKit type="l-input" label="New password" name="new_password" inputType="password"
|
|
36
|
+
:validation="system.passwordPolicy" />
|
|
37
|
+
<FormKit type="l-input" label="Confirm password" name="new_password_confirm" inputType="password"
|
|
38
|
+
validation="required|confirm" />
|
|
39
|
+
</FormKit>
|
|
33
40
|
|
|
34
41
|
<div>
|
|
35
42
|
<div>Password policy</div>
|
|
36
|
-
<
|
|
37
|
-
<li v-for="rule in system.passwordPolicy" :key="rule">
|
|
38
|
-
{{ rule }}
|
|
39
|
-
</li>
|
|
40
|
-
</ul>
|
|
43
|
+
<div>{{ system.passwordPolicy }}</div>
|
|
41
44
|
</div>
|
|
42
45
|
</template>
|
|
@@ -47,8 +47,8 @@ const setDefault = async () => {
|
|
|
47
47
|
styles.cardBordered = true;
|
|
48
48
|
styles.cardSquare = false;
|
|
49
49
|
|
|
50
|
-
styles.buttonOutline =
|
|
51
|
-
styles.buttonRounded =
|
|
50
|
+
styles.buttonOutline = false;
|
|
51
|
+
styles.buttonRounded = false;
|
|
52
52
|
styles.buttonUnelevated = false;
|
|
53
53
|
styles.buttonDense = false;
|
|
54
54
|
|
package/dist/runtime/plugin.mjs
CHANGED
|
@@ -8,12 +8,16 @@ import message_zh from "./locales/zh-hk.json";
|
|
|
8
8
|
import routes from "./routes.mjs";
|
|
9
9
|
import { defineModel } from "@hostlink/light";
|
|
10
10
|
localStorage.getItem("locale") || localStorage.setItem("locale", "en");
|
|
11
|
+
import { createQuasarPlugin } from "formkit-quasar";
|
|
12
|
+
import { createLightPlugin } from "./formkit/index.mjs";
|
|
13
|
+
import { plugin, defaultConfig } from "@formkit/vue";
|
|
11
14
|
import { useLight } from "./index.mjs";
|
|
12
15
|
import TypeUser from "./types/User.mjs";
|
|
13
16
|
import TypeUserLog from "./types/UserLog.mjs";
|
|
14
17
|
import TypeSystemValue from "./types/SystemValue.mjs";
|
|
15
18
|
import TypeMailLog from "./types/MailLog.mjs";
|
|
16
19
|
import TypeEventLog from "./types/EventLog.mjs";
|
|
20
|
+
import { zhTW } from "@formkit/i18n";
|
|
17
21
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
18
22
|
defineModel("User", TypeUser);
|
|
19
23
|
defineModel("UserLog", TypeUserLog);
|
|
@@ -57,6 +61,17 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|
|
57
61
|
Loading
|
|
58
62
|
}
|
|
59
63
|
});
|
|
64
|
+
let locale = localStorage.getItem("locale") || "en";
|
|
65
|
+
if (locale == "zh-hk") {
|
|
66
|
+
locale = "zhTW";
|
|
67
|
+
}
|
|
68
|
+
nuxtApp.vueApp.use(plugin, defaultConfig({
|
|
69
|
+
plugins: [createQuasarPlugin(), createLightPlugin()],
|
|
70
|
+
locales: {
|
|
71
|
+
zhTW
|
|
72
|
+
},
|
|
73
|
+
locale
|
|
74
|
+
}));
|
|
60
75
|
const router = useRouter();
|
|
61
76
|
routes.forEach((route) => {
|
|
62
77
|
router.addRoute(route);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hostlink/nuxt-light",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.115",
|
|
4
4
|
"description": "HostLink Nuxt Light Framework",
|
|
5
5
|
"repository": "@hostlink/nuxt-light",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"@nuxt/module-builder": "^0.5.2",
|
|
40
40
|
"@quasar/extras": "^1.16.6",
|
|
41
41
|
"axios": "^1.5.0",
|
|
42
|
+
"formkit-quasar": "^0.0.12",
|
|
42
43
|
"json-to-graphql-query": "^2.2.5",
|
|
43
44
|
"quasar": "^2.12.5",
|
|
44
45
|
"unplugin-auto-import": "^0.16.6",
|