@hostlink/nuxt-light 1.0.10 → 1.1.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,5 +1,5 @@
1
1
  {
2
2
  "name": "light",
3
3
  "configKey": "light",
4
- "version": "1.0.10"
4
+ "version": "1.1.0"
5
5
  }
@@ -3,7 +3,7 @@ import { useLight, watch } from "#imports";
3
3
  import { useRuntimeConfig } from 'nuxt/app'
4
4
  import { setApiUrl } from '@hostlink/light'
5
5
  import { Dialog } from 'quasar'
6
- import { q } from '../'
6
+ import { q } from '#imports'
7
7
  import { useRoute } from "#vue-router";
8
8
  const config = useRuntimeConfig();
9
9
  setApiUrl(config?.public?.apiBase ?? '/api/');
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { type QBannerProps, type QBannerSlots } from 'quasar'
2
+ import { type QBannerProps } from 'quasar'
3
3
  import { computed, useSlots } from 'vue'
4
4
 
5
5
  export interface LBannerProps extends QBannerProps {
@@ -1,15 +1,37 @@
1
1
  <script setup lang="ts">
2
- import { ref, computed, useAttrs } from "vue";
2
+ import { ref, computed } from "vue";
3
3
  import { useLight } from '#imports';
4
4
 
5
5
  import { type QDateProps } from "quasar";
6
+ import { useI18n } from 'vue-i18n';
7
+
8
+ const { t } = useI18n();
6
9
 
7
10
  export interface LDatePickerProps extends QDateProps {
8
11
  label?: string
9
12
  required?: boolean
13
+ hideBottomSpace?: boolean
14
+ filled?: boolean
15
+ outlined?: boolean
16
+ standout?: boolean
17
+ rounded?: boolean
18
+ dense?: boolean
19
+ square?: boolean
20
+ stackLabel?: boolean
21
+ rules?: any[]
10
22
  }
11
23
 
12
- const props = defineProps<LDatePickerProps>()
24
+ const props = withDefaults(defineProps<LDatePickerProps>(), {
25
+ hideBottomSpace: true,
26
+ filled: undefined,
27
+ outlined: undefined,
28
+ standout: undefined,
29
+ rounded: undefined,
30
+ dense: undefined,
31
+ square: undefined,
32
+ stackLabel: undefined,
33
+ mask: "YYYY-MM-DD",
34
+ })
13
35
 
14
36
  const light = useLight();
15
37
 
@@ -55,26 +77,41 @@ if (!props.range) {
55
77
  });
56
78
  }
57
79
 
58
- const attrs = {
59
- filled: light.getStyle("inputFilled"),
60
- outlined: light.getStyle("inputOutlined"),
61
- standout: light.getStyle("inputStandout"),
62
- rounded: light.getStyle("inputRounded"),
63
- dense: light.getStyle("inputDense"),
64
- square: light.getStyle("inputSquare"),
65
- stackLabel: light.getStyle("inputStackLabel")
66
- }
80
+ const input_attrs = computed(() => {
81
+ const attrs: any = {
82
+ label: props.label,
83
+ rules: rules,
84
+ hideBottomSpace: props.hideBottomSpace,
85
+ mask: props.range ? "####-##-## - ####-##-##" : "####-##-##"
86
+ }
87
+
88
+ if (props.filled == undefined) attrs.filled = light.getStyle("inputFilled");
89
+ if (props.outlined == undefined) attrs.outlined = light.getStyle("inputOutlined");
90
+ if (props.standout == undefined) attrs.standout = light.getStyle("inputStandout");
91
+ if (props.rounded == undefined) attrs.rounded = light.getStyle("inputRounded");
92
+ if (props.dense == undefined) attrs.dense = light.getStyle("inputDense");
93
+ if (props.square == undefined) attrs.square = light.getStyle("inputSquare");
94
+ if (props.stackLabel == undefined) attrs.stackLabel = light.getStyle("inputStackLabel");
95
+
96
+ if (props.label) {
97
+ attrs.label = t(props.label);
98
+ }
99
+ return attrs;
100
+ })
101
+
102
+ const date_attrs = computed(() => {
103
+ const { label, rules, hideBottomSpace, filled, outlined, standout, rounded, dense, square, stackLabel, ...rest } = props;
104
+ return rest;
105
+ });
67
106
 
68
- const mask = props.range ? "####-##-## - ####-##-##" : "####-##-##";
69
107
 
70
108
  </script>
71
109
  <template>
72
- <q-input v-bind="attrs" :label="$t(props.label ?? '')" v-model="localValue" :rules="rules" hide-bottom-space
73
- :mask="mask">
110
+ <q-input v-bind="input_attrs" v-model="localValue" :rules="rules">
74
111
  <template v-slot:prepend>
75
112
  <q-btn icon="sym_o_event" round dense flat>
76
113
  <q-popup-proxy cover transition-show="scale" transition-hide="scale" ref="popup">
77
- <q-date v-model="localValue" mask="YYYY-MM-DD" :range="range">
114
+ <q-date v-bind="date_attrs" v-model="localValue">
78
115
  <div class="row items-center justify-end">
79
116
  <q-btn v-close-popup label="Close" color="primary" flat />
80
117
  </div>
@@ -0,0 +1,127 @@
1
+ <script setup lang="ts">
2
+ import { computed, ref, useAttrs } from "vue";
3
+ import { type QEditorProps, useQuasar } from "quasar"
4
+
5
+ const $q = useQuasar();
6
+
7
+ export interface LEditorProps extends QEditorProps {
8
+
9
+ }
10
+
11
+ const emit = defineEmits(["update:modelValue"]);
12
+
13
+ const props = withDefaults(defineProps<LEditorProps>(), {
14
+ modelValue: "",
15
+ placeholder: "type something",
16
+ dense: false,
17
+ toolbar: undefined,
18
+ fonts: undefined,
19
+ })
20
+
21
+ const localValue = computed({
22
+ get: () => props.modelValue,
23
+ set: (value) => emit('update:modelValue', value)
24
+ });
25
+
26
+ const attrs = computed(() => {
27
+ const a = { ...props };
28
+ if (props.toolbar === undefined) a.toolbar = newToolBar;
29
+ if (props.fonts === undefined) a.fonts = newFonts;
30
+ return a;
31
+ });
32
+
33
+
34
+ const newToolBar = [
35
+ [
36
+ {
37
+ label: $q.lang.editor.align,
38
+ icon: $q.iconSet.editor.align,
39
+ fixedLabel: true,
40
+ list: 'only-icons',
41
+ options: ['left', 'center', 'right', 'justify']
42
+ },
43
+ {
44
+ label: $q.lang.editor.align,
45
+ icon: $q.iconSet.editor.align,
46
+ fixedLabel: true,
47
+ options: ['left', 'center', 'right', 'justify']
48
+ }
49
+ ],
50
+ ['bold', 'italic', 'strike', 'underline', 'subscript', 'superscript'],
51
+ ['token', 'hr', 'link', 'custom_btn'],
52
+ ['print', 'fullscreen'],
53
+ [
54
+ {
55
+ label: $q.lang.editor.formatting,
56
+ icon: $q.iconSet.editor.formatting,
57
+ list: 'no-icons',
58
+ options: [
59
+ 'p',
60
+ 'h1',
61
+ 'h2',
62
+ 'h3',
63
+ 'h4',
64
+ 'h5',
65
+ 'h6',
66
+ 'code'
67
+ ]
68
+ },
69
+ {
70
+ label: $q.lang.editor.fontSize,
71
+ icon: $q.iconSet.editor.fontSize,
72
+ fixedLabel: true,
73
+ fixedIcon: true,
74
+ list: 'no-icons',
75
+ options: [
76
+ 'size-1',
77
+ 'size-2',
78
+ 'size-3',
79
+ 'size-4',
80
+ 'size-5',
81
+ 'size-6',
82
+ 'size-7'
83
+ ]
84
+ },
85
+ {
86
+ label: $q.lang.editor.defaultFont,
87
+ icon: $q.iconSet.editor.font,
88
+ fixedIcon: true,
89
+ list: 'no-icons',
90
+ options: [
91
+ 'default_font',
92
+ 'arial',
93
+ 'arial_black',
94
+ 'comic_sans',
95
+ 'courier_new',
96
+ 'impact',
97
+ 'lucida_grande',
98
+ 'times_new_roman',
99
+ 'verdana'
100
+ ]
101
+ },
102
+ 'removeFormat'
103
+ ],
104
+ ['quote', 'unordered', 'ordered', 'outdent', 'indent'],
105
+
106
+ ['undo', 'redo'],
107
+ ['viewsource']
108
+ ];
109
+
110
+ const newFonts = {
111
+ arial: 'Arial',
112
+ arial_black: 'Arial Black',
113
+ comic_sans: 'Comic Sans MS',
114
+ courier_new: 'Courier New',
115
+ impact: 'Impact',
116
+ lucida_grande: 'Lucida Grande',
117
+ times_new_roman: 'Times New Roman',
118
+ verdana: 'Verdana'
119
+ };
120
+
121
+ </script>
122
+
123
+ <template>
124
+ <div class="q-pa-md q-gutter-sm">
125
+ <q-editor v-bind="attrs" v-model="localValue" />
126
+ </div>
127
+ </template>
@@ -1,17 +1,32 @@
1
- <script setup>
2
- import { useLight, useAttrs } from '#imports';
3
- const props = defineProps(['label']);
1
+ <script setup lang="ts">
2
+ import { useLight } from '#imports';
3
+ import { computed } from 'vue';
4
+ import { useI18n } from 'vue-i18n';
5
+
6
+ import type { QFieldProps } from 'quasar';
7
+
8
+ const props = defineProps<QFieldProps>()
4
9
  const light = useLight();
10
+ const { t } = useI18n();
5
11
 
6
- const attrs = {
7
- ...{
12
+ const attrs = computed(() => {
13
+
14
+ const a = {
15
+ ...props,
8
16
  outlined: light.getStyle("inputOutlined"),
9
- },
10
- ...useAttrs()
11
- }
17
+ };
18
+
19
+ if (props.label) {
20
+ a.label = t(props.label);
21
+ }
22
+
23
+
24
+ return a;
25
+ });
26
+
12
27
  </script>
13
28
  <template>
14
- <q-field v-bind="attrs" :label="$t(props.label ?? '')">
29
+ <q-field v-bind="attrs">
15
30
  <slot></slot>
16
31
  </q-field>
17
32
  </template>
@@ -64,6 +64,33 @@ const attrs = computed(() => {
64
64
  return a;
65
65
  });
66
66
 
67
+
68
+ //@param bytes Number of bytes.
69
+ //@param si True to use metric (SI) units, aka powers of 1000. False to use binary (IEC), aka powers of 1024.
70
+ //@param dp Number of decimal places to display.
71
+ const humanFileSize = (bytesSize, si = false, dp = 1) => {
72
+ const thresh = si ? 1000 : 1024;
73
+
74
+ if (Math.abs(bytesSize) < thresh) {
75
+ return bytesSize + ' B';
76
+ }
77
+
78
+ const units = si
79
+ ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
80
+ : ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; //: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
81
+ let u = -1;
82
+ const r = 10 ** dp;
83
+
84
+ do {
85
+ bytesSize /= thresh;
86
+ ++u;
87
+ } while (Math.round(Math.abs(bytesSize) * r) / r >= thresh && u < units.length - 1);
88
+
89
+ return bytesSize.toFixed(dp) + ' ' + units[u];
90
+ }
91
+
92
+
93
+
67
94
  const uploadFile = ref<File | null>(null);
68
95
  const rename = ref(true);
69
96
 
@@ -82,7 +109,7 @@ const onUploadFile = async () => {
82
109
  if (uploadFile.value.size > system.maxUploadSize) {
83
110
  Dialog.create({
84
111
  title: "Error",
85
- message: "File size is too big. Max size is " + system.maxUploadSize + " bytes",
112
+ message: "File size is too big. Max size is " + humanFileSize(system.maxUploadSize, false, 0),
86
113
  color: "negative"
87
114
  });
88
115
  return;
@@ -134,11 +161,11 @@ const onUploadFile = async () => {
134
161
  <q-dialog v-model="show" persistent transition-show="scale" transition-hide="scale">
135
162
  <l-card style="width:300px">
136
163
  <q-card-section>
137
- <q-file ref="file" v-model="uploadFile" name="file" :label="$t('File')" :accept="accept" :hint="`Max upload size: ${system.maxUploadSize} bytes`"></q-file>
164
+ <q-file ref="file" v-model="uploadFile" name="file" :label="$t('File')" :accept="accept"
165
+ :hint="`Max upload size: ${humanFileSize(system.maxUploadSize, false, 0)}`"></q-file>
138
166
  <!-- q-checkbox v-model="rename" :label="$t('Rename file if exists')"></q-checkbox-->
139
-
140
-
141
167
  </q-card-section>
168
+
142
169
  <q-card-actions align="right">
143
170
  <q-btn flat :label="$t('Cancel')" color="primary" v-close-popup></q-btn>
144
171
  <q-btn flat :label="$t('Upload')" color="primary" @click="onUploadFile"></q-btn>
@@ -1,49 +1,41 @@
1
- <script setup>
2
- import { computed, ref, useAttrs } from "vue";
1
+ <script setup lang="ts">
2
+ import { computed, ref } from "vue";
3
3
  import { useI18n } from 'vue-i18n';
4
4
  import tc2sc from "../lib/tc2sc";
5
5
  import { useLight } from '#imports';
6
6
 
7
+ import type { QInputProps } from "quasar";
8
+ export interface LInputProps extends QInputProps {
9
+ showPassword?: boolean;
10
+ translate?: boolean;
11
+ required?: boolean;
12
+ }
13
+
7
14
  const i18n = useI18n();
8
15
  const light = useLight();
9
16
 
10
- const props = defineProps({
11
- modelValue: {
12
- },
13
- rules: {
14
- type: Array,
15
- default: () => []
16
- },
17
- required: {
18
- type: Boolean,
19
- default: false
20
- },
21
- label: {
22
- type: String,
23
- default: ""
24
- },
25
- type: {
26
- type: String,
27
- default: "text"
28
- },
29
- showPassword: {
30
- type: Boolean,
31
- default: false
32
- },
33
- translate: {
34
- type: Boolean,
35
- default: false
36
- }
17
+ const props = withDefaults(defineProps<LInputProps>(), {
18
+ showPassword: false,
19
+ translate: false,
20
+ outlined: undefined,
21
+ filled: undefined,
22
+ standout: undefined,
23
+ rounded: undefined,
24
+ dense: undefined,
25
+ square: undefined,
26
+ stackLabel: undefined,
27
+ required: false,
28
+ hideBottomSpace: true,
37
29
  });
30
+
38
31
  const emit = defineEmits(["update:modelValue"]);
39
32
 
40
33
  //clone rules to new_rules
41
34
  const new_rules = props.rules || [];
42
35
 
43
-
44
36
  //has required prop (in properties)
45
- if (props.required || (new_rules.indexOf("required") >= 0)) {
46
- new_rules.push(val => !!val || i18n.t('input_required', [i18n.t(props.label)]));
37
+ if (props.required) {
38
+ new_rules.push(val => !!val || i18n.t('input_required', [i18n.t(props.label ?? "")]));
47
39
  }
48
40
 
49
41
  if (props.type == "email") {
@@ -101,24 +93,11 @@ if (minLength) {
101
93
  });
102
94
  }
103
95
 
104
-
105
-
106
-
107
-
108
-
109
96
  const localValue = computed({
110
97
  get: () => props.modelValue,
111
98
  set: (value) => emit('update:modelValue', value)
112
99
  });
113
100
 
114
- const localLabel = computed(() => {
115
- if (props.required && !localValue.value) {
116
- return i18n.t(props.label);
117
- }
118
- return i18n.t(props.label);
119
-
120
- });
121
-
122
101
  const isShowPassword = ref(false);
123
102
 
124
103
  const localType = computed(() => {
@@ -128,8 +107,6 @@ const localType = computed(() => {
128
107
  return props.type;
129
108
  });
130
109
 
131
-
132
-
133
110
  const localShowPassword = computed(() => {
134
111
  if (props.type != "password") {
135
112
  return false;
@@ -142,32 +119,31 @@ const localShowPassword = computed(() => {
142
119
  if (!localValue.value) {
143
120
  return false;
144
121
  }
145
-
146
122
  return true;
147
-
148
123
  });
149
124
 
150
-
151
125
  const onClickTc2Sc = () => {
152
126
  localValue.value = tc2sc(localValue.value);
153
127
  }
154
128
 
155
- const attrs = {
156
- ...{
157
- filled: light.getStyle("inputFilled"),
158
- outlined: light.getStyle("inputOutlined"),
159
- standout: light.getStyle("inputStandout"),
160
- rounded: light.getStyle("inputRounded"),
161
- dense: light.getStyle("inputDense"),
162
- square: light.getStyle("inputSquare"),
163
- stackLabel: light.getStyle("inputStackLabel")
164
- },
165
- ...useAttrs(),
166
- }
167
-
129
+ const attrs = computed(() => {
130
+ const a = { ...props };
131
+ if (props.outlined === undefined) a.outlined = light.getStyle("inputOutlined");
132
+ if (props.filled === undefined) a.filled = light.getStyle("inputFilled");
133
+ if (props.standout === undefined) a.standout = light.getStyle("inputStandout");
134
+ if (props.rounded === undefined) a.rounded = light.getStyle("inputRounded");
135
+ if (props.dense === undefined) a.dense = light.getStyle("inputDense");
136
+ if (props.square === undefined) a.square = light.getStyle("inputSquare");
137
+ if (props.stackLabel === undefined) a.stackLabel = light.getStyle("inputStackLabel");
138
+
139
+ if (props.label) {
140
+ a.label = i18n.t(props.label);
141
+ }
142
+ return a;
143
+ })
168
144
  </script>
169
145
  <template>
170
- <q-input v-bind="attrs" :label="localLabel" v-model="localValue" :rules="new_rules" hide-bottom-space :type="localType">
146
+ <q-input v-bind="attrs" v-model="localValue" :rules="new_rules" :type="localType">
171
147
  <template v-if="translate" #prepend>
172
148
  <q-btn icon="sym_o_translate" flat dense rounded>
173
149
  <q-menu dense>
@@ -1,22 +1,21 @@
1
- <script setup>
2
- const props = defineProps({
3
- label: {
4
- type: String,
5
- },
6
- type: {
7
- type: String,
8
- default: "text"
9
- }, name: {
10
- type: String,
11
- default: null
12
- }
1
+ <script setup lang="ts">
2
+ import type { QItemProps } from 'quasar';
13
3
 
4
+ export interface LItemProps extends QItemProps {
5
+ label?: string;
6
+ type?: 'text' | 'caption';
7
+ name?: string;
8
+ }
9
+
10
+ withDefaults(defineProps<LItemProps>(), {
11
+ label: '',
12
+ type: 'text'
14
13
  });
15
14
 
16
15
 
17
16
  </script>
18
17
  <template>
19
- <q-item>
18
+ <q-item v-bind="$props">
20
19
  <q-item-section>
21
20
  <q-item-label>{{ $t(label) }}</q-item-label>
22
21
  <q-item-label caption v-if="type == 'caption'">
@@ -1,18 +1,22 @@
1
- <script setup>
2
-
3
- const props = defineProps({
4
- modelValue: {
5
- type: Object
6
- },
7
- fields: {
8
- type: Array
9
- }
10
- })
1
+ <script setup lang="ts">
2
+
3
+ import type { QListProps } from 'quasar';
4
+
5
+ export interface LListProps extends QListProps {
6
+ fields?: any[];
7
+ modelValue?: any;
8
+ }
9
+
10
+ const props = withDefaults(defineProps<LListProps>(), {
11
+ bordered: true,
12
+ separator: true,
13
+ dense: true,
14
+ });
11
15
 
12
16
  function getTo(field) {
13
17
 
14
- const raw=field.getRaw();
15
-
18
+ const raw = field.getRaw();
19
+
16
20
  if (raw.to) {
17
21
  if (raw.to instanceof Function) {
18
22
  return raw.to(props.modelValue);
@@ -26,10 +30,9 @@ function getTo(field) {
26
30
  return null;
27
31
  }
28
32
 
29
-
30
33
  </script>
31
34
  <template>
32
- <q-list bordered separator dense >
35
+ <q-list v-bind="$props">
33
36
  <template v-if="fields">
34
37
  <l-item v-for="field in fields" :label="field.getRaw().label" :to="getTo(field)">
35
38
  {{ field.getFormattedValue(props.modelValue) }}
@@ -194,8 +194,8 @@ onMounted(() => {
194
194
  <q-form ref="form1">
195
195
  <div class="q-gutter-sm">
196
196
  <l-input v-model.trim="data.username" label="Username" :rules="[v => !!v || $t('Username is required')]"
197
- clearable :outlined="false" />
198
- <l-input v-model="data.password" label="Password" type="password" clearable show-password
197
+ clearable :outlined="false" stackLabel/>
198
+ <l-input v-model="data.password" label="Password" type="password" clearable show-password stackLabel
199
199
  :rules="[v => !!v || $t('Password is required')]" @keydown.enter.prevent="submit" :outlined="false" />
200
200
  <l-input v-if="twoFactorAuthentication" v-model="data.code" label="2FA code" required type="text" clearable>
201
201
  </l-input>
@@ -1,75 +1,32 @@
1
- <script setup>
1
+ <script setup lang="ts">
2
2
  import { useHead, useLight } from "#imports";
3
3
  import { useRouter, useRoute } from "vue-router"
4
4
  import { model, getID } from '../'
5
+ import type { QPageProps } from "quasar";
6
+ import { computed } from 'vue'
5
7
 
6
8
  const router = useRouter();
7
9
  const route = useRoute();
8
10
  const light = useLight();
9
11
 
10
- const props = defineProps({
11
- type: {
12
- type: String,
13
- default: "view"
14
- },
15
- title: {
16
- type: String,
17
- default: ""
18
- },
19
- backBtn: {
20
- type: Boolean,
21
- default: false
22
- },
23
- editBtn: {
24
- type: Boolean,
25
- default: false
26
- },
27
- deleteBtn: {
28
- type: Boolean,
29
- default: false
30
- },
31
- addBtn: {
32
- type: Boolean,
33
- default: false
34
- },
35
- });
36
-
37
- let showToolbar = false;
38
- let showBackBtn = false;
39
- let showEditBtn = false;
40
- let showAddBtn = false;
41
- let showDeleteBtn = false;
42
-
43
-
44
- if (props.type == "edit") {
45
- showToolbar = true
46
- showBackBtn = true
47
- }
48
-
49
- if (props.type == "add") {
50
- showToolbar = true
51
- showBackBtn = true
52
- }
53
-
54
- if (props.type == "view") {
55
- showToolbar = true
56
- showBackBtn = true
12
+ export interface LPageProps extends QPageProps {
13
+ title?: string;
14
+ backBtn?: boolean;
15
+ editBtn?: boolean;
16
+ deleteBtn?: boolean;
17
+ addBtn?: boolean;
57
18
  }
58
19
 
59
- if (props.editBtn) {
60
- showToolbar = true
61
- showEditBtn = true
62
- }
63
-
64
- if (props.deleteBtn) {
65
- showToolbar = true
66
- showDeleteBtn = true
67
- }
20
+ const props = withDefaults(defineProps<LPageProps>(), {
21
+ title: "",
22
+ backBtn: true,
23
+ });
68
24
 
69
- if (props.addBtn) {
70
- showToolbar = true
71
- showAddBtn = true
72
- }
25
+ const showToolbar = computed(() => {
26
+ if (props.backBtn || props.editBtn || props.deleteBtn || props.addBtn) {
27
+ return true
28
+ }
29
+ });
73
30
 
74
31
  let title = props.title || route.path.split("/")[1].replace(/([a-z])(?=[A-Z])/g, '$1 ').replace(/([A-Z]*)(?=[A-Z][a-z])/g, '$1 ')
75
32
 
@@ -80,9 +37,13 @@ title = title.trim()
80
37
  const module = route.path.split("/")[1];
81
38
  const onDelete = async () => {
82
39
 
83
- if (await model(module).delete(getID())) {
84
- router.push(`/${module}`);
40
+ const id = getID();
41
+ if (id) {
42
+ if (await model(module).delete(id)) {
43
+ router.push(`/${module}`);
44
+ }
85
45
  }
46
+
86
47
  }
87
48
 
88
49
  useHead({
@@ -99,10 +60,10 @@ useHead({
99
60
  </q-breadcrumbs -->
100
61
 
101
62
  <q-toolbar v-if="showToolbar">
102
- <l-back-btn v-if="showBackBtn" />
103
- <l-add-btn v-if="showAddBtn" />
104
- <l-edit-btn v-if="showEditBtn" />
105
- <l-delete-btn v-if="showDeleteBtn" @submit="onDelete" />
63
+ <l-back-btn v-if="backBtn" />
64
+ <l-add-btn v-if="addBtn" />
65
+ <l-edit-btn v-if="editBtn" />
66
+ <l-delete-btn v-if="deleteBtn" @submit="onDelete" />
106
67
  <q-toolbar-title>{{ $t(title) }}</q-toolbar-title>
107
68
  </q-toolbar>
108
69
 
@@ -1,5 +1,6 @@
1
- <script setup>
2
-
1
+ <script setup lang="ts">
2
+ import type { QTabProps } from 'quasar';
3
+ defineProps<QTabProps>()
3
4
  </script>
4
5
  <template>
5
6
  <q-tab></q-tab>
@@ -300,7 +300,7 @@ const onRequest = async (p: any) => {
300
300
  name: true
301
301
  }
302
302
  },
303
- setData(data: { data: Array<{ data: any }>, meta: { total: Number, key: string, name: string } }) {
303
+ setData(data: { data: Array<{ data: any }>, meta: { total: number, key: string, name: string } }) {
304
304
  rows.value = data.data;
305
305
  primaryKey.value = data.meta.key;
306
306
  modelName.value = data.meta.name;
@@ -411,22 +411,23 @@ const onDelete = async (id: any) => {
411
411
  }
412
412
  }
413
413
 
414
- const attrs = {
415
- ...{
416
- dense: light.getStyle("tableDense"),
417
- flat: light.getStyle("tableFlat"),
418
- bordered: light.getStyle("tableBorder"),
419
- separator: light.getStyle("tableSeparator"),
420
- },
421
- ...useAttrs(),
422
- title: props.title,
423
- loadingLabel: t(props.loadingLabel),
424
- noDataLabel: t(props.noDataLabel),
425
- rowsPerPageOptions: props.rowsPerPageOptions,
426
- rowsPerPageLabel: t(props.rowsPerPageLabel),
427
- selection: props.selection,
428
- rowKey: props.rowKey,
429
- }
414
+ const attrs = computed(() => {
415
+ return {
416
+ ...{
417
+ dense: light.getStyle("tableDense"),
418
+ flat: light.getStyle("tableFlat"),
419
+ bordered: light.getStyle("tableBorder"),
420
+ separator: light.getStyle("tableSeparator"),
421
+ },
422
+ title: props.title,
423
+ loadingLabel: t(props.loadingLabel),
424
+ noDataLabel: t(props.noDataLabel),
425
+ rowsPerPageOptions: props.rowsPerPageOptions,
426
+ rowsPerPageLabel: t(props.rowsPerPageLabel),
427
+ selection: props.selection,
428
+ rowKey: props.rowKey,
429
+ }
430
+ });
430
431
 
431
432
  const filter = ref('');
432
433
 
@@ -1,9 +1,14 @@
1
- <script setup>
2
- import { useLight } from '../'
1
+ <script setup lang="ts">
2
+ import { useLight } from '#imports'
3
3
  import { useSlots, computed, ref } from 'vue';
4
+ import type { QTabsProps } from 'quasar';
5
+
6
+ interface LTabsProps extends QTabsProps {
7
+
8
+ }
4
9
 
5
10
  const light = useLight();
6
- const props = defineProps(["modelValue"])
11
+ const props = defineProps<LTabsProps>()
7
12
  const emit = defineEmits(["update:modelValue"])
8
13
  const slots = useSlots();
9
14
  const defaultSlots = slots.default();
@@ -32,7 +37,7 @@ const localValue = computed({
32
37
  }
33
38
  })
34
39
 
35
- const color = light.getStyle("color", 'primary');
40
+ const color = light.getStyle("color");
36
41
 
37
42
  </script>
38
43
 
@@ -0,0 +1,25 @@
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-editor v-model="value" :label="context.label" v-bind="context.attrs" :error="error" :type="context.inputType"
19
+ :error-message="errorMessage">
20
+ <slot></slot>
21
+ <!-- <template v-for="(s, name) in $slots" v-slot:[name]="props" :key="name">
22
+ <slot :name="name" v-bind="props ?? {}"></slot>
23
+ </template> -->
24
+ </l-editor>
25
+ </template>
@@ -12,10 +12,16 @@ import FilePickerVue from "./FilePicker.vue";
12
12
  import FileVue from "./File.vue";
13
13
  import InputXlsxVue from "./InputXlsx.vue";
14
14
  import FileUploadVue from "./FileUpload.vue";
15
+ import EditorVue from "./Editor.vue";
15
16
  export const createLightPlugin = () => {
16
17
  return (node) => {
17
18
  let type = node.props.type + "";
18
19
  switch (type) {
20
+ case "l-editor":
21
+ return node.define({
22
+ type: "input",
23
+ component: EditorVue
24
+ });
19
25
  case "l-file-upload":
20
26
  return node.define({
21
27
  type: "input",
@@ -1,2 +1,2 @@
1
- declare const _default: () => Number | null;
1
+ declare const _default: () => number | null;
2
2
  export default _default;
@@ -10,7 +10,7 @@ const id = route.params.user_id;
10
10
 
11
11
  const onSubmit = async (data) => {
12
12
  return await m("updateUserPassword", {
13
- id: id,
13
+ id: parseInt(id),
14
14
  password: data.password
15
15
  }).then(() => {
16
16
  Notify.create({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostlink/nuxt-light",
3
- "version": "1.0.10",
3
+ "version": "1.1.0",
4
4
  "description": "HostLink Nuxt Light Framework",
5
5
  "repository": "@hostlink/nuxt-light",
6
6
  "license": "MIT",