@hostlink/nuxt-light 1.38.0 → 1.40.0
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/module.mjs +2 -1
- package/dist/runtime/assets/main.css +1 -1
- package/dist/runtime/components/L/System/Setting/authentication.vue +4 -1
- package/dist/runtime/components/L/System/Setting/forget-password.vue +1 -1
- package/dist/runtime/components/L/System/Setting/modules.vue +2 -1
- package/dist/runtime/components/l-app-main.vue +1 -0
- package/dist/runtime/components/l-app.vue +1 -0
- package/dist/runtime/components/l-editor.vue +4 -4
- package/dist/runtime/components/l-form.vue +2 -5
- package/dist/runtime/components/l-input.vue +10 -2
- package/dist/runtime/components/l-login.vue +1 -1
- package/dist/runtime/components/l-select.vue +9 -2
- package/dist/runtime/composables/useLight.d.ts +9 -5
- package/dist/runtime/composables/useLight.js +4 -0
- package/dist/runtime/composables/useRoles.d.ts +7 -0
- package/dist/runtime/composables/useRoles.js +39 -0
- package/dist/runtime/composables/useWebAuthn.d.ts +5 -0
- package/dist/runtime/composables/useWebAuthn.js +5 -0
- package/dist/runtime/formkit/Form.vue +2 -4
- package/dist/runtime/pages/Permission/add.vue +2 -2
- package/dist/runtime/pages/User/add.vue +1 -1
- package/package.json +9 -9
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
body{font-family:Noto Sans,Noto Sans HK,Noto Sans TC,-apple-system,Helvetica Neue,Helvetica,Arial,sans-serif}.q-card__actions .q-btn--rectangle{padding:4px 16px}.q-table--dense .q-table td,.q-table--dense .q-table td:first-child,.q-table--dense .q-table th,.q-table--dense .q-table th:first-child{padding:2px 4px}.q-tab-panel{padding:8px}::-webkit-scrollbar{background:transparent;height:12px;overflow:visible;width:14px;z-index:12}::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:#c1c1c1;border:4px solid transparent;border-radius:10px;margin:4px;min-height:32px;min-width:32px;-webkit-transition:background-color .32s ease-in-out;transition:background-color .32s ease-in-out;width:10px;z-index:12}::-webkit-scrollbar-thumb:hover{background:#c1c1c1}
|
|
1
|
+
body{font-family:Noto Sans,Noto Sans HK,Noto Sans TC,-apple-system,Helvetica Neue,Helvetica,Arial,sans-serif}.q-field--dense .q-field__before,.q-field--dense .q-field__prepend{padding-right:5px}.q-field--dense .q-field__after,.q-field--dense .q-field__append{padding-left:5px}.q-field--outlined .q-field__control{padding:0 10px}.q-field__before,.q-field__prepend{padding-right:10px}.q-field--filled .q-field__control{padding:0 10px}.q-card__actions .q-btn--rectangle{padding:4px 16px}.q-table--dense .q-table td,.q-table--dense .q-table td:first-child,.q-table--dense .q-table th,.q-table--dense .q-table th:first-child{padding:2px 4px}.q-tab-panel{padding:8px}::-webkit-scrollbar{background:transparent;height:12px;overflow:visible;width:14px;z-index:12}::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:#c1c1c1;border:4px solid transparent;border-radius:10px;margin:4px;min-height:32px;min-width:32px;-webkit-transition:background-color .32s ease-in-out;transition:background-color .32s ease-in-out;width:10px;z-index:12}::-webkit-scrollbar-thumb:hover{background:#c1c1c1}
|
|
@@ -23,7 +23,10 @@ const onSubmit = async (d) => {
|
|
|
23
23
|
|
|
24
24
|
<form-kit label="Password based" type="l-checkbox" name="authentication_password_based" true-value="1"
|
|
25
25
|
false-value="0" />
|
|
26
|
-
|
|
26
|
+
|
|
27
|
+
<div class="col-12">
|
|
28
|
+
<q-separator />
|
|
29
|
+
</div>
|
|
27
30
|
|
|
28
31
|
<form-kit label="Google Client ID" type="l-input" name="authentication_google_client_id" />
|
|
29
32
|
|
|
@@ -14,7 +14,7 @@ const onSubmit = async (d) => {
|
|
|
14
14
|
</script>
|
|
15
15
|
|
|
16
16
|
<template>
|
|
17
|
-
<form-kit type="l-form" :value="{
|
|
17
|
+
<form-kit :bordered="false" type="l-form" :value="{
|
|
18
18
|
forget_password_enabled: processedEnabled,
|
|
19
19
|
forget_password_subject: processedSubject,
|
|
20
20
|
forget_password_template: processedTemplate
|
|
@@ -7,8 +7,9 @@ defineProps({
|
|
|
7
7
|
|
|
8
8
|
<template>
|
|
9
9
|
<form-kit type="l-form" :bordered="false" :value="$props" @submit="$emit('submit', $event)">
|
|
10
|
-
<l-field :label="$t('File Manager')" stack-label :color="$light.color" hide-bottom-space>
|
|
10
|
+
<l-field :label="$t('File Manager')" stack-label :color="$light.color" hide-bottom-space class="col-6">
|
|
11
11
|
<form-kit type="l-checkbox" label="Show" name="file_manager" true-value="1" false-value="0" />
|
|
12
12
|
</l-field>
|
|
13
|
+
|
|
13
14
|
</form-kit>
|
|
14
15
|
</template>
|
|
@@ -55,6 +55,7 @@ let my = reactive(tt.my);
|
|
|
55
55
|
const light = useLight();
|
|
56
56
|
light.devMode = tt.system.devMode;
|
|
57
57
|
light.init(my.styles);
|
|
58
|
+
light.setMyRoles(my.roles);
|
|
58
59
|
light.setPermissions(my.permissions);
|
|
59
60
|
light.setMyFavorites(toRaw(my.myFavorites));
|
|
60
61
|
const myFavorites = computed(() => {
|
|
@@ -4,6 +4,7 @@ import { useLight, watch } from "#imports";
|
|
|
4
4
|
import { useQuasar } from "quasar";
|
|
5
5
|
import { q } from "#imports";
|
|
6
6
|
import { useRoute } from "vue-router";
|
|
7
|
+
import "../assets/main.css";
|
|
7
8
|
const route = useRoute();
|
|
8
9
|
const light = useLight();
|
|
9
10
|
const quasar = useQuasar();
|
|
@@ -7,20 +7,20 @@ const textColorRef = ref(null);
|
|
|
7
7
|
const textHightlightRef = ref(null);
|
|
8
8
|
const highlight = ref("#ffff00aa");
|
|
9
9
|
const foreColor = ref("#000000");
|
|
10
|
-
const TextColorCMD = (cmd, name) => {
|
|
10
|
+
const TextColorCMD = ((cmd, name) => {
|
|
11
11
|
const edit = editorRef.value;
|
|
12
12
|
textColorRef.value.hide();
|
|
13
13
|
edit.caret.restore();
|
|
14
14
|
edit.runCmd(cmd, name);
|
|
15
15
|
edit.focus();
|
|
16
|
-
};
|
|
17
|
-
const TextHightlightCMD = (cmd, name) => {
|
|
16
|
+
});
|
|
17
|
+
const TextHightlightCMD = ((cmd, name) => {
|
|
18
18
|
const edit = editorRef.value;
|
|
19
19
|
textHightlightRef.value.hide();
|
|
20
20
|
edit.caret.restore();
|
|
21
21
|
edit.runCmd(cmd, name);
|
|
22
22
|
edit.focus();
|
|
23
|
-
};
|
|
23
|
+
});
|
|
24
24
|
const emit = defineEmits(["update:modelValue"]);
|
|
25
25
|
const props = defineProps({
|
|
26
26
|
fullscreen: { type: Boolean, required: false, skipCheck: true },
|
|
@@ -81,11 +81,8 @@ const onSubmit = (e) => {
|
|
|
81
81
|
<template>
|
|
82
82
|
<q-form ref="form" @submit="onSubmit">
|
|
83
83
|
<l-card :bordered="bordered">
|
|
84
|
-
<q-card-section>
|
|
85
|
-
<
|
|
86
|
-
<slot></slot>
|
|
87
|
-
</div>
|
|
88
|
-
|
|
84
|
+
<q-card-section class="row q-col-gutter-md">
|
|
85
|
+
<slot></slot>
|
|
89
86
|
</q-card-section>
|
|
90
87
|
|
|
91
88
|
<q-card-actions align="right">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, ref } from "vue";
|
|
2
|
+
import { computed, ref, useAttrs } from "vue";
|
|
3
3
|
import { useI18n } from "vue-i18n";
|
|
4
4
|
import tc2sc from "../composables/tc2sc";
|
|
5
5
|
const { t } = useI18n();
|
|
@@ -12,6 +12,7 @@ const props = defineProps({
|
|
|
12
12
|
fillMask: { type: [Boolean, String], required: false, skipCheck: true },
|
|
13
13
|
reverseFillMask: { type: Boolean, required: false, skipCheck: true },
|
|
14
14
|
unmaskedValue: { type: Boolean, required: false, skipCheck: true },
|
|
15
|
+
maskTokens: { type: null, required: false },
|
|
15
16
|
modelValue: { type: null, required: true },
|
|
16
17
|
error: { type: [Boolean, null], required: false, skipCheck: true },
|
|
17
18
|
errorMessage: { type: null, required: false },
|
|
@@ -135,10 +136,17 @@ const localShowPassword = computed(() => {
|
|
|
135
136
|
const onClickTc2Sc = () => {
|
|
136
137
|
modelValue.value = tc2sc(modelValue.value ?? "");
|
|
137
138
|
};
|
|
139
|
+
const attrs = useAttrs();
|
|
140
|
+
const localClass = computed(() => {
|
|
141
|
+
if (attrs.class) {
|
|
142
|
+
return attrs.class;
|
|
143
|
+
}
|
|
144
|
+
return "col-12";
|
|
145
|
+
});
|
|
138
146
|
</script>
|
|
139
147
|
|
|
140
148
|
<template>
|
|
141
|
-
<q-input v-bind="$light.getInputProps($props)" :rules="new_rules" :type="localType">
|
|
149
|
+
<q-input v-bind="$light.getInputProps($props)" :rules="new_rules" :type="localType" :class="localClass">
|
|
142
150
|
<template v-if="translate" #prepend>
|
|
143
151
|
<q-btn icon="sym_o_translate" flat dense rounded>
|
|
144
152
|
<q-menu dense>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, reactive, onMounted, resolveComponent } from "vue";
|
|
3
3
|
import { useQuasar } from "quasar";
|
|
4
|
-
import { api, useHead
|
|
4
|
+
import { api, useHead } from "#imports";
|
|
5
5
|
import { useI18n } from "vue-i18n";
|
|
6
6
|
const { t } = useI18n();
|
|
7
7
|
const emits = defineEmits(["login"]);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { ref } from "vue";
|
|
2
|
+
import { ref, useAttrs, computed } from "vue";
|
|
3
3
|
const props = defineProps({
|
|
4
4
|
name: { type: null, required: false },
|
|
5
5
|
virtualScrollHorizontal: { type: Boolean, required: false, skipCheck: true },
|
|
@@ -150,8 +150,15 @@ const filterFn = (val, update, abort) => {
|
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
152
|
};
|
|
153
|
+
const attrs = useAttrs();
|
|
154
|
+
const localClass = computed(() => {
|
|
155
|
+
if (attrs.class) {
|
|
156
|
+
return attrs.class;
|
|
157
|
+
}
|
|
158
|
+
return "col-12";
|
|
159
|
+
});
|
|
153
160
|
</script>
|
|
154
161
|
|
|
155
162
|
<template>
|
|
156
|
-
<q-select v-bind="$light.getInputProps($props)" :options="select_options" @filter="filterFn" />
|
|
163
|
+
<q-select v-bind="$light.getInputProps($props)" :options="select_options" @filter="filterFn" :class="localClass" />
|
|
157
164
|
</template>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { QDialogOptions, QNotifyCreateOptions
|
|
1
|
+
import type { QDialogOptions, QNotifyCreateOptions } from 'quasar';
|
|
2
2
|
declare module 'vue' {
|
|
3
3
|
interface ComponentCustomProperties {
|
|
4
4
|
$light: typeof light;
|
|
@@ -99,7 +99,7 @@ declare const light: {
|
|
|
99
99
|
increment: (amount?: number) => void;
|
|
100
100
|
setDefaults: (props: import("quasar").QLoadingBarOptions) => void;
|
|
101
101
|
};
|
|
102
|
-
notify: (opts: QNotifyCreateOptions | string) => (props?: QNotifyUpdateOptions) => void;
|
|
102
|
+
notify: (opts: QNotifyCreateOptions | string) => (props?: import("quasar").QNotifyUpdateOptions) => void;
|
|
103
103
|
platform: {
|
|
104
104
|
userAgent: string;
|
|
105
105
|
is: {
|
|
@@ -589,8 +589,9 @@ declare const light: {
|
|
|
589
589
|
isAdmin: boolean;
|
|
590
590
|
permissions: string[];
|
|
591
591
|
myFavorites: any[];
|
|
592
|
+
myRoles: string[];
|
|
592
593
|
$t: any;
|
|
593
|
-
notify: (opts: QNotifyCreateOptions | string) => (props?: QNotifyUpdateOptions) => void;
|
|
594
|
+
notify: (opts: QNotifyCreateOptions | string) => (props?: import("quasar").QNotifyUpdateOptions) => void;
|
|
594
595
|
dialog: (opts: QDialogOptions) => import("quasar").DialogChainObject;
|
|
595
596
|
users: {
|
|
596
597
|
create: (user: User) => Promise<User>;
|
|
@@ -603,6 +604,7 @@ declare const light: {
|
|
|
603
604
|
};
|
|
604
605
|
getColorValue: () => string;
|
|
605
606
|
setMyFavorites: (favorites: Array<any>) => void;
|
|
607
|
+
setMyRoles: (roles: Array<string>) => void;
|
|
606
608
|
reloadMyFavorites: () => Promise<void>;
|
|
607
609
|
getMyFavorites: () => any[];
|
|
608
610
|
isDarkMode: () => boolean;
|
|
@@ -703,7 +705,7 @@ declare const _default: () => {
|
|
|
703
705
|
increment: (amount?: number) => void;
|
|
704
706
|
setDefaults: (props: import("quasar").QLoadingBarOptions) => void;
|
|
705
707
|
};
|
|
706
|
-
notify: (opts: QNotifyCreateOptions | string) => (props?: QNotifyUpdateOptions) => void;
|
|
708
|
+
notify: (opts: QNotifyCreateOptions | string) => (props?: import("quasar").QNotifyUpdateOptions) => void;
|
|
707
709
|
platform: {
|
|
708
710
|
userAgent: string;
|
|
709
711
|
is: {
|
|
@@ -1193,8 +1195,9 @@ declare const _default: () => {
|
|
|
1193
1195
|
isAdmin: boolean;
|
|
1194
1196
|
permissions: string[];
|
|
1195
1197
|
myFavorites: any[];
|
|
1198
|
+
myRoles: string[];
|
|
1196
1199
|
$t: any;
|
|
1197
|
-
notify: (opts: QNotifyCreateOptions | string) => (props?: QNotifyUpdateOptions) => void;
|
|
1200
|
+
notify: (opts: QNotifyCreateOptions | string) => (props?: import("quasar").QNotifyUpdateOptions) => void;
|
|
1198
1201
|
dialog: (opts: QDialogOptions) => import("quasar").DialogChainObject;
|
|
1199
1202
|
users: {
|
|
1200
1203
|
create: (user: User) => Promise<User>;
|
|
@@ -1207,6 +1210,7 @@ declare const _default: () => {
|
|
|
1207
1210
|
};
|
|
1208
1211
|
getColorValue: () => string;
|
|
1209
1212
|
setMyFavorites: (favorites: Array<any>) => void;
|
|
1213
|
+
setMyRoles: (roles: Array<string>) => void;
|
|
1210
1214
|
reloadMyFavorites: () => Promise<void>;
|
|
1211
1215
|
getMyFavorites: () => any[];
|
|
1212
1216
|
isDarkMode: () => boolean;
|
|
@@ -74,6 +74,7 @@ const light = reactive({
|
|
|
74
74
|
isAdmin: false,
|
|
75
75
|
permissions: Array(),
|
|
76
76
|
myFavorites: Array(),
|
|
77
|
+
myRoles: Array(),
|
|
77
78
|
$t: null,
|
|
78
79
|
notify: (opts) => {
|
|
79
80
|
if (light.$q == null) {
|
|
@@ -158,6 +159,9 @@ const light = reactive({
|
|
|
158
159
|
setMyFavorites: (favorites) => {
|
|
159
160
|
light.myFavorites = favorites;
|
|
160
161
|
},
|
|
162
|
+
setMyRoles: (roles) => {
|
|
163
|
+
light.myRoles = roles;
|
|
164
|
+
},
|
|
161
165
|
reloadMyFavorites: async () => {
|
|
162
166
|
const data = await q({
|
|
163
167
|
my: {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import useLight from "./useLight.js";
|
|
3
|
+
import q from "./q.js";
|
|
4
|
+
export default function useRoles() {
|
|
5
|
+
const light = useLight();
|
|
6
|
+
const roles = computed(() => light.myRoles || []);
|
|
7
|
+
function hasRole(role) {
|
|
8
|
+
if (!role) return false;
|
|
9
|
+
if (light.isAdmin) return true;
|
|
10
|
+
return light.myRoles.includes(role);
|
|
11
|
+
}
|
|
12
|
+
function hasAny(...args) {
|
|
13
|
+
const list = Array.isArray(args[0]) ? args[0] : args;
|
|
14
|
+
if (light.isAdmin) return true;
|
|
15
|
+
return list.some((r) => light.myRoles.includes(r));
|
|
16
|
+
}
|
|
17
|
+
function hasAll(wanted = []) {
|
|
18
|
+
if (light.isAdmin) return true;
|
|
19
|
+
return wanted.every((r) => light.myRoles.includes(r));
|
|
20
|
+
}
|
|
21
|
+
async function reload() {
|
|
22
|
+
const data = await q({
|
|
23
|
+
my: {
|
|
24
|
+
roles
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const newRoles = (data?.my?.roles || []).map((r) => r.role || r);
|
|
28
|
+
light.myRoles = newRoles;
|
|
29
|
+
light.isAdmin = newRoles.includes("Administrators");
|
|
30
|
+
return newRoles;
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
roles,
|
|
34
|
+
hasRole,
|
|
35
|
+
hasAny,
|
|
36
|
+
hasAll,
|
|
37
|
+
reload
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -77,10 +77,8 @@ const isNoDirtyCheck = computed(() => {
|
|
|
77
77
|
<template>
|
|
78
78
|
<form v-bind="context.attrs">
|
|
79
79
|
<l-card :bordered="bordered">
|
|
80
|
-
<q-card-section>
|
|
81
|
-
<
|
|
82
|
-
<slot v-bind="context"></slot>
|
|
83
|
-
</div>
|
|
80
|
+
<q-card-section class="row q-col-gutter-md">
|
|
81
|
+
<slot v-bind="context"></slot>
|
|
84
82
|
</q-card-section>
|
|
85
83
|
|
|
86
84
|
<q-card-actions align="right" v-if="context.actions">
|
|
@@ -24,9 +24,9 @@ const onSave = async () => {
|
|
|
24
24
|
|
|
25
25
|
<template>
|
|
26
26
|
<l-page>
|
|
27
|
-
<l-form @
|
|
27
|
+
<l-form @submit="onSave">
|
|
28
28
|
|
|
29
|
-
<l-input label="Permission name" v-model="obj.value" required></l-input>
|
|
29
|
+
<l-input label="Permission name" v-model="obj.value" required class="col-12"></l-input>
|
|
30
30
|
|
|
31
31
|
<l-field label="Roles" stack-label>
|
|
32
32
|
<q-option-group type="checkbox" :options="roles" v-model="obj.roles" inline :color="$light.color">
|
|
@@ -52,7 +52,7 @@ const languages = tt.app.languages.map((lang) => {
|
|
|
52
52
|
<l-page>
|
|
53
53
|
|
|
54
54
|
<FormKit type="l-form" :value="obj">
|
|
55
|
-
<l-row>
|
|
55
|
+
<l-row class="col">
|
|
56
56
|
<l-col md="6">
|
|
57
57
|
<FormKit type="l-input" label="Username" name="username" validation="required" />
|
|
58
58
|
<FormKit type="l-input" label="Password" name="password" :validation="system.passwordPolicy"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hostlink/nuxt-light",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.40.0",
|
|
4
4
|
"description": "HostLink Nuxt Light Framework",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -32,31 +32,31 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@azure/msal-browser": "^3.26.1",
|
|
34
34
|
"@formkit/drag-and-drop": "^0.5.3",
|
|
35
|
-
"@hostlink/light": "^2.
|
|
35
|
+
"@hostlink/light": "^2.9.0",
|
|
36
36
|
"@nuxt/module-builder": "^1.0.1",
|
|
37
|
-
"@quasar/extras": "^1.
|
|
37
|
+
"@quasar/extras": "^1.17.0",
|
|
38
38
|
"@quasar/quasar-ui-qmarkdown": "^2.0.5",
|
|
39
|
-
"axios": "^1.
|
|
39
|
+
"axios": "^1.12.2",
|
|
40
40
|
"defu": "^6.1.4",
|
|
41
41
|
"diff2html": "^3.4.47",
|
|
42
42
|
"formkit-quasar": "^0.0.15",
|
|
43
43
|
"json-to-graphql-query": "^2.2.5",
|
|
44
44
|
"nuxt-quasar-ui": "^2.1.12",
|
|
45
|
-
"quasar": "^2.
|
|
45
|
+
"quasar": "^2.18.5",
|
|
46
46
|
"vue-i18n": "^9.2.2",
|
|
47
47
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@nuxt/devtools": "latest",
|
|
51
51
|
"@nuxt/eslint-config": "^0.2.0",
|
|
52
|
-
"@nuxt/kit": "^4.
|
|
53
|
-
"@nuxt/schema": "^4.
|
|
52
|
+
"@nuxt/kit": "^4.1.2",
|
|
53
|
+
"@nuxt/schema": "^4.1.2",
|
|
54
54
|
"@nuxt/test-utils": "^3.17.2",
|
|
55
55
|
"@types/node": "^22.5.0",
|
|
56
56
|
"changelogen": "^0.5.4",
|
|
57
57
|
"eslint": "^8.46.0",
|
|
58
|
-
"nuxt": "^4.
|
|
59
|
-
"typescript": "^5.
|
|
58
|
+
"nuxt": "^4.1.2",
|
|
59
|
+
"typescript": "^5.9.2",
|
|
60
60
|
"vue-tsc": "^2.2.8"
|
|
61
61
|
}
|
|
62
62
|
}
|