@hostlink/nuxt-light 1.54.5 → 1.55.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "light",
3
3
  "configKey": "light",
4
- "version": "1.54.5",
4
+ "version": "1.55.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -93,7 +93,7 @@ const localClass = computed(() => {
93
93
  </q-card-section>
94
94
 
95
95
  <q-card-actions align="right">
96
- <l-btn :icon="submitIcon" :label="submitLabel" @click="save" :loading="loading" />
96
+ <l-btn :icon="submitIcon" :label="submitLabel" @click="save" :loading="loading" type="submit" />
97
97
  </q-card-actions>
98
98
  </l-card>
99
99
  </q-form>
@@ -162,7 +162,7 @@ const forgetPassword = async () => {
162
162
  };
163
163
  const bioLogin = async () => {
164
164
  try {
165
- await api.auth.WebAuthn.login();
165
+ await api.auth.webAuthn.login();
166
166
  window.self.location.reload();
167
167
  } catch (e) {
168
168
  $q.notify({
@@ -0,0 +1,36 @@
1
+ declare const _default: typeof __VLS_export;
2
+ export default _default;
3
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
4
+ type __VLS_WithSlots<T, S> = T & (new () => {
5
+ $slots: S;
6
+ });
7
+ declare const __VLS_base: import("vue").DefineComponent<{}, {
8
+ $emit: typeof emit;
9
+ $props: Partial<typeof props>;
10
+ dense: boolean;
11
+ sortable: boolean;
12
+ bordered: boolean;
13
+ separator: boolean;
14
+ modelValue: unknown[];
15
+ max: number;
16
+ min: number;
17
+ addLabel: string;
18
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
19
+ type __VLS_Slots = {
20
+ default?: ((props: {
21
+ value: unknown;
22
+ index: number;
23
+ item: unknown;
24
+ }) => any) | undefined;
25
+ };
26
+ declare const emit: (event: "update:modelValue", ...args: any[]) => void;
27
+ declare const props: {
28
+ readonly dense: boolean;
29
+ readonly sortable: boolean;
30
+ readonly bordered: boolean;
31
+ readonly separator: boolean;
32
+ readonly modelValue: unknown[];
33
+ readonly max: number;
34
+ readonly min: number;
35
+ readonly addLabel: string;
36
+ };
@@ -0,0 +1,153 @@
1
+ <script setup>
2
+ import { computed, ref, watch } from "vue";
3
+ import { useDragAndDrop } from "@formkit/drag-and-drop/vue";
4
+ import { animations } from "@formkit/drag-and-drop";
5
+ const props = defineProps({
6
+ modelValue: {
7
+ type: Array,
8
+ default: () => []
9
+ },
10
+ min: {
11
+ type: Number,
12
+ default: 0
13
+ },
14
+ max: {
15
+ type: Number,
16
+ default: Infinity
17
+ },
18
+ sortable: {
19
+ type: Boolean,
20
+ default: true
21
+ },
22
+ addLabel: {
23
+ type: String,
24
+ default: "Add"
25
+ },
26
+ dense: {
27
+ type: Boolean,
28
+ default: false
29
+ },
30
+ bordered: {
31
+ type: Boolean,
32
+ default: true
33
+ },
34
+ separator: {
35
+ type: Boolean,
36
+ default: true
37
+ }
38
+ });
39
+ const emit = defineEmits(["update:modelValue"]);
40
+ const initializeValue = () => {
41
+ let initialValue = props.modelValue ? [...props.modelValue] : [];
42
+ if (initialValue.length < props.min) {
43
+ for (let i = initialValue.length; i < props.min; i++) {
44
+ initialValue.push({});
45
+ }
46
+ }
47
+ if (initialValue.length > props.max) {
48
+ initialValue = initialValue.slice(0, props.max);
49
+ }
50
+ return initialValue;
51
+ };
52
+ const [parent, localValue] = useDragAndDrop(initializeValue(), {
53
+ dragHandle: ".l-repeater-handle",
54
+ plugins: [animations()]
55
+ });
56
+ watch(() => props.modelValue, (newVal) => {
57
+ if (JSON.stringify(newVal) !== JSON.stringify(localValue.value)) {
58
+ localValue.value = initializeValue();
59
+ }
60
+ }, { deep: true });
61
+ watch(localValue, (newVal) => {
62
+ emit("update:modelValue", newVal);
63
+ }, { deep: true });
64
+ watch(() => props.max, (newVal) => {
65
+ if (localValue.value.length > newVal) {
66
+ localValue.value = localValue.value.slice(0, newVal);
67
+ }
68
+ });
69
+ watch(() => props.min, (newVal) => {
70
+ if (localValue.value.length < newVal) {
71
+ for (let i = localValue.value.length; i < newVal; i++) {
72
+ localValue.value.push({});
73
+ }
74
+ }
75
+ });
76
+ const onAdd = () => {
77
+ if (localValue.value.length >= props.max) return;
78
+ localValue.value.push({});
79
+ };
80
+ const onRemove = (index) => {
81
+ if (localValue.value.length <= props.min) return;
82
+ localValue.value.splice(index, 1);
83
+ };
84
+ const onMoveUp = (index) => {
85
+ if (index > 0) {
86
+ let temp = localValue.value[index - 1];
87
+ localValue.value[index - 1] = localValue.value[index];
88
+ localValue.value[index] = temp;
89
+ }
90
+ };
91
+ const onMoveDown = (index) => {
92
+ if (index < localValue.value.length - 1) {
93
+ let temp = localValue.value[index + 1];
94
+ localValue.value[index + 1] = localValue.value[index];
95
+ localValue.value[index] = temp;
96
+ }
97
+ };
98
+ const isAllowRemove = computed(() => {
99
+ return localValue.value.length > props.min;
100
+ });
101
+ const isAllowAdd = computed(() => {
102
+ return localValue.value.length < props.max;
103
+ });
104
+ const isAllowMoveUp = (index) => {
105
+ return index > 0;
106
+ };
107
+ const isAllowMoveDown = (index) => {
108
+ return index < localValue.value.length - 1;
109
+ };
110
+ const cursor = ref("cursor-grab");
111
+ </script>
112
+
113
+ <style scoped>
114
+ .cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}
115
+ </style>
116
+
117
+ <template>
118
+ <div class="l-repeater">
119
+ <q-list :bordered="bordered" :separator="separator" ref="parent">
120
+ <q-item v-for="(item, index) in localValue" :key="index" :class="{ 'q-pa-xs': !dense, 'q-pa-none': dense }">
121
+ <q-item-section avatar v-if="sortable">
122
+ <div class="l-repeater-handle" :class="cursor" @mousedown="cursor = 'cursor-grabbing'"
123
+ @mouseup="cursor = 'cursor-grab'" @mouseleave="cursor = 'cursor-grab'">
124
+ <q-icon name="sym_o_drag_indicator" size="sm" />
125
+ </div>
126
+ </q-item-section>
127
+
128
+ <q-item-section>
129
+ <slot :value="localValue[index]" :index="index" :item="item"></slot>
130
+ </q-item-section>
131
+
132
+ <q-item-section side>
133
+ <div class="column q-gutter-xs">
134
+ <!-- Move up -->
135
+ <q-btn type="button" @click="onMoveUp(index)" icon="sym_o_arrow_upward" color="primary"
136
+ :dense="dense" flat :disable="!isAllowMoveUp(index)" size="sm" />
137
+
138
+ <!-- Remove -->
139
+ <q-btn type="button" @click="onRemove(index)" icon="sym_o_delete" color="negative"
140
+ :dense="dense" flat :disable="!isAllowRemove" size="sm" />
141
+
142
+ <!-- Move down -->
143
+ <q-btn type="button" @click="onMoveDown(index)" icon="sym_o_arrow_downward" color="primary"
144
+ :dense="dense" flat :disable="!isAllowMoveDown(index)" size="sm" />
145
+ </div>
146
+ </q-item-section>
147
+ </q-item>
148
+ </q-list>
149
+
150
+ <q-btn @click="onAdd" :label="addLabel" icon="sym_o_add" color="primary" outline class="q-mt-sm"
151
+ :disable="!isAllowAdd" :dense="dense" />
152
+ </div>
153
+ </template>
@@ -0,0 +1,36 @@
1
+ declare const _default: typeof __VLS_export;
2
+ export default _default;
3
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
4
+ type __VLS_WithSlots<T, S> = T & (new () => {
5
+ $slots: S;
6
+ });
7
+ declare const __VLS_base: import("vue").DefineComponent<{}, {
8
+ $emit: typeof emit;
9
+ $props: Partial<typeof props>;
10
+ dense: boolean;
11
+ sortable: boolean;
12
+ bordered: boolean;
13
+ separator: boolean;
14
+ modelValue: unknown[];
15
+ max: number;
16
+ min: number;
17
+ addLabel: string;
18
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
19
+ type __VLS_Slots = {
20
+ default?: ((props: {
21
+ value: unknown;
22
+ index: number;
23
+ item: unknown;
24
+ }) => any) | undefined;
25
+ };
26
+ declare const emit: (event: "update:modelValue", ...args: any[]) => void;
27
+ declare const props: {
28
+ readonly dense: boolean;
29
+ readonly sortable: boolean;
30
+ readonly bordered: boolean;
31
+ readonly separator: boolean;
32
+ readonly modelValue: unknown[];
33
+ readonly max: number;
34
+ readonly min: number;
35
+ readonly addLabel: string;
36
+ };
@@ -4,7 +4,7 @@ import { useQuasar } from "quasar";
4
4
  import { computed, model } from "#imports";
5
5
  const route = useRoute();
6
6
  const router = useRouter();
7
- const quasar = useQuasar();
7
+ const $q = useQuasar();
8
8
  let props = defineProps({
9
9
  context: {
10
10
  type: Object,
@@ -53,7 +53,7 @@ if (!props.context.onSubmit) {
53
53
  try {
54
54
  if (id) {
55
55
  if (await model(modelName).update(Number(id), v)) {
56
- quasar.notify({
56
+ $q.notify({
57
57
  message: "Updated successfully",
58
58
  color: "positive",
59
59
  icon: "sym_o_check"
@@ -64,7 +64,7 @@ if (!props.context.onSubmit) {
64
64
  }
65
65
  } else {
66
66
  if (await model(modelName).add(v)) {
67
- quasar.notify({
67
+ $q.notify({
68
68
  message: "Added successfully",
69
69
  color: "positive",
70
70
  icon: "sym_o_check"
@@ -78,7 +78,7 @@ if (!props.context.onSubmit) {
78
78
  props.context.attrs.onSubmitted(v);
79
79
  }
80
80
  } catch (e) {
81
- quasar.dialog({
81
+ $q.dialog({
82
82
  title: "Error",
83
83
  message: e.message,
84
84
  ok: "OK"
@@ -99,12 +99,14 @@ const localClass = computed(() => {
99
99
 
100
100
  <template>
101
101
  <l-card :bordered="bordered">
102
- <q-card-section :class="localClass">
103
- <slot v-bind="context"></slot>
104
- </q-card-section>
105
- <q-card-actions align="right" v-if="context.actions">
106
- <l-btn icon="sym_o_check" :label="context.submitLabel ?? 'Submit'" @click="onSubmit"
107
- :disabled="!isNoDirtyCheck && !context.state.dirty" :loading="context.state.loading"></l-btn>
108
- </q-card-actions>
102
+ <form @submit.prevent="onSubmit">
103
+ <q-card-section :class="localClass">
104
+ <slot v-bind="context"></slot>
105
+ </q-card-section>
106
+ <q-card-actions align="right" v-if="context.actions">
107
+ <l-btn type="submit" icon="sym_o_check" :label="context.submitLabel ?? 'Submit'"
108
+ :disabled="!isNoDirtyCheck && !context.state.dirty" :loading="context.state.loading"></l-btn>
109
+ </q-card-actions>
110
+ </form>
109
111
  </l-card>
110
112
  </template>
@@ -10,6 +10,9 @@ const min = ref(props.context.node.props.min ?? 0);
10
10
  const max = ref(props.context.node.props.max ?? Infinity);
11
11
  const sortable = ref(props.context.node.props.sortable ?? true);
12
12
  const addLabel = ref(props.context.node.props.addLabel ?? "Add");
13
+ const dense = ref(props.context.node.props.dense ?? false);
14
+ const bordered = ref(props.context.node.props.bordered ?? true);
15
+ const separator = ref(props.context.node.props.separator ?? true);
13
16
  node.on("prop", ({ payload }) => {
14
17
  if (payload.prop == "max") {
15
18
  max.value = payload.value;
@@ -23,6 +26,15 @@ node.on("prop", ({ payload }) => {
23
26
  if (payload.prop == "addLabel") {
24
27
  addLabel.value = payload.value;
25
28
  }
29
+ if (payload.prop == "dense") {
30
+ dense.value = payload.value;
31
+ }
32
+ if (payload.prop == "bordered") {
33
+ bordered.value = payload.value;
34
+ }
35
+ if (payload.prop == "separator") {
36
+ separator.value = payload.value;
37
+ }
26
38
  });
27
39
  if (!props.context.value) {
28
40
  await node.input([]);
@@ -92,12 +104,11 @@ const cursor = ref("cursor-grab");
92
104
  <template>
93
105
  <FormKit type="list" v-model="localValue" dynamic #default="{ items, node }" :name="node.name">
94
106
  <div class="col col-12">
95
-
96
- <q-list bordered separator ref="parent">
107
+ <q-list :bordered="bordered" :separator="separator" ref="parent">
97
108
  <FormKit type="group" v-for="(item, index) in items" :index="index" :key="item" #default="{ node }">
98
- <q-item class="q-pa-xs">
99
- <q-item-section avatar class="">
100
- <div class="l-repeater-handle" v-if="sortable" :class="cursor"
109
+ <q-item :class="{ 'q-pa-xs': !dense, 'q-pa-none': dense }">
110
+ <q-item-section avatar v-if="sortable">
111
+ <div class="l-repeater-handle" :class="cursor"
101
112
  @mousedown="cursor = 'cursor-grabbing'" @mouseup="cursor = 'cursor-grab'"
102
113
  @mouseleave="cursor = 'cursor-grab'">
103
114
  <q-icon name="sym_o_drag_indicator" size="sm" />
@@ -109,16 +120,17 @@ const cursor = ref("cursor-grab");
109
120
  </q-item-section>
110
121
 
111
122
  <q-item-section side>
112
- <!-- up -->
113
- <q-btn type="button" @click="onMoveUp(index)" icon="sym_o_arrow_upward" color="primary"
114
- dense flat :disable="!isAllowMoveUp(index)" />
115
-
116
- <q-btn type="button" @click="onRemove(index)" icon="sym_o_delete" color="primary" dense
117
- :disable="!isAllowRemove" flat />
118
- <!-- down -->
119
- <q-btn type="button" @click="onMoveDown(index)" icon="sym_o_arrow_downward" color="primary"
120
- dense flat :disable="!isAllowMoveDown(index)" />
123
+ <div class="column q-gutter-xs">
124
+ <!-- up -->
125
+ <q-btn type="button" @click="onMoveUp(index)" icon="sym_o_arrow_upward" color="primary"
126
+ :dense="dense" flat :disable="!isAllowMoveUp(index)" size="sm" />
121
127
 
128
+ <q-btn type="button" @click="onRemove(index)" icon="sym_o_delete" color="negative"
129
+ :dense="dense" :disable="!isAllowRemove" flat size="sm" />
130
+ <!-- down -->
131
+ <q-btn type="button" @click="onMoveDown(index)" icon="sym_o_arrow_downward" color="primary"
132
+ :dense="dense" flat :disable="!isAllowMoveDown(index)" size="sm" />
133
+ </div>
122
134
  </q-item-section>
123
135
  </q-item>
124
136
  </FormKit>
@@ -100,7 +100,7 @@ export const createLightPlugin = () => {
100
100
  case "l-repeater":
101
101
  return node.define({
102
102
  type: "input",
103
- props: ["min", "max", "sortable", "addLabel"],
103
+ props: ["min", "max", "sortable", "addLabel", "dense"],
104
104
  component: RepeaterVue
105
105
  });
106
106
  case "l-form":
@@ -161,12 +161,11 @@ const filteredRows = computed(() => {
161
161
  </div>
162
162
 
163
163
  <!-- 權限表格 -->
164
- <q-table :columns="columns" flat bordered :rows="filteredRows" :pagination="{ rowsPerPage: 0 }" dense
165
- class="permission-table">
164
+ <q-table :columns="columns" flat bordered :rows="filteredRows" :pagination="{ rowsPerPage: 0 }" dense>
166
165
 
167
166
  <template #body="props">
168
167
  <q-tr :props="props">
169
- <q-td :style="columns[0].style" class="text-weight-medium">
168
+ <q-td :style="columns[0].style" class="text-weight-medium" auto-width>
170
169
  <q-icon name="security" class="q-mr-sm text-grey-6" />
171
170
  {{ props.row.permission }}
172
171
  </q-td>
@@ -199,7 +198,3 @@ const filteredRows = computed(() => {
199
198
  </div>
200
199
  </l-page>
201
200
  </template>
202
-
203
- <style scoped>
204
- .permission-table{box-shadow:0 2px 8px rgba(0,0,0,.1)}.permission-table :deep(.q-table__top){background-color:rgba(0,0,0,.02);padding:16px}.permission-table :deep(thead tr th){background-color:rgba(0,0,0,.05);font-weight:700}.permission-table :deep(tbody tr:hover){background-color:rgba(0,0,0,.03)}.permission-table :deep(tbody tr td:first-child){border-right:2px solid rgba(0,0,0,.1)}
205
- </style>
@@ -3,7 +3,7 @@ import { useQuasar } from "quasar";
3
3
  import { q, m, notify, useAsyncData } from "#imports";
4
4
  import { useI18n } from "vue-i18n";
5
5
  const { t } = useI18n();
6
- const qua = useQuasar();
6
+ const $q = useQuasar();
7
7
  const { data, refresh } = await useAsyncData("role", async () => {
8
8
  const data2 = await q({
9
9
  app: {
@@ -30,7 +30,7 @@ const { data, refresh } = await useAsyncData("role", async () => {
30
30
  let role_options = data.value.roles.map((r) => ({ label: r.name, value: r.name }));
31
31
  let users = data.value.listUser.data;
32
32
  const onDelete = async (role) => {
33
- qua.dialog({
33
+ $q.dialog({
34
34
  title: "Delete",
35
35
  message: "Are you sure you want to delete this role and related role relations?",
36
36
  cancel: true,
@@ -71,10 +71,18 @@ const onRemoveChild = async (value, child) => {
71
71
  refresh();
72
72
  };
73
73
  const onAddChild = async (value, child) => {
74
- await m("addRoleChild", {
75
- name: value,
76
- child: child.value.value
77
- });
74
+ try {
75
+ await m("addRoleChild", {
76
+ name: value,
77
+ child: child.value.value
78
+ });
79
+ } catch (e) {
80
+ $q.notify({
81
+ type: "negative",
82
+ message: e.message
83
+ });
84
+ return;
85
+ }
78
86
  notify("Role added to role");
79
87
  refresh();
80
88
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostlink/nuxt-light",
3
- "version": "1.54.5",
3
+ "version": "1.55.0",
4
4
  "description": "HostLink Nuxt Light Framework",
5
5
  "repository": {
6
6
  "type": "git",