@winchsa/ui 0.1.53 → 0.1.57
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/components/forms/AutocompleteInput.d.vue.ts +2 -0
- package/dist/components/forms/AutocompleteInput.vue +3 -2
- package/dist/components/forms/AutocompleteInput.vue.d.ts +2 -0
- package/dist/components/table/DataTable.d.vue.ts +1 -1
- package/dist/components/table/DataTable.vue.d.ts +1 -1
- package/dist/components/table/EditableDataTableRow.vue +1 -0
- package/dist/components/table/FilterGenerator.vue +8 -4
- package/dist/composables/useTableFilters.js +75 -2
- package/dist/composables/useTableFilters.mjs +76 -3
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
|
@@ -17,6 +17,7 @@ type __VLS_Props = {
|
|
|
17
17
|
error?: boolean;
|
|
18
18
|
modelValue?: unknown;
|
|
19
19
|
itemLabel?: string;
|
|
20
|
+
descriptionKey?: string;
|
|
20
21
|
groupValues?: string;
|
|
21
22
|
groupLabel?: string;
|
|
22
23
|
trackBy?: string;
|
|
@@ -83,6 +84,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
83
84
|
clearable: boolean;
|
|
84
85
|
hideSelected: boolean;
|
|
85
86
|
querySearchParam: string;
|
|
87
|
+
descriptionKey: string;
|
|
86
88
|
trackBy: string;
|
|
87
89
|
deselectLabel: string;
|
|
88
90
|
selectLabel: string;
|
|
@@ -26,6 +26,7 @@ const props = defineProps({
|
|
|
26
26
|
error: { type: Boolean, required: false },
|
|
27
27
|
modelValue: { type: null, required: false },
|
|
28
28
|
itemLabel: { type: String, required: false },
|
|
29
|
+
descriptionKey: { type: String, required: false, default: "description" },
|
|
29
30
|
groupValues: { type: String, required: false },
|
|
30
31
|
groupLabel: { type: String, required: false },
|
|
31
32
|
trackBy: { type: String, required: false, default: "id" },
|
|
@@ -305,7 +306,7 @@ defineExpose({
|
|
|
305
306
|
<p class="ma-0 app-font-size-13">
|
|
306
307
|
{{ option.name }}
|
|
307
308
|
</p>
|
|
308
|
-
<span v-if="option?.
|
|
309
|
+
<span v-if="option?.[descriptionKey]" class="text-gray-600 app-font-size-13">{{ option?.[descriptionKey] }}</span>
|
|
309
310
|
</div>
|
|
310
311
|
</template>
|
|
311
312
|
|
|
@@ -422,7 +423,7 @@ defineExpose({
|
|
|
422
423
|
<p class="ma-0 app-font-size-13">
|
|
423
424
|
{{ option.name }}
|
|
424
425
|
</p>
|
|
425
|
-
<span v-if="option?.
|
|
426
|
+
<span v-if="option?.[descriptionKey]" class="text-gray-600 app-font-size-13">({{ option?.[descriptionKey] }})</span>
|
|
426
427
|
</div>
|
|
427
428
|
</template>
|
|
428
429
|
|
|
@@ -17,6 +17,7 @@ type __VLS_Props = {
|
|
|
17
17
|
error?: boolean;
|
|
18
18
|
modelValue?: unknown;
|
|
19
19
|
itemLabel?: string;
|
|
20
|
+
descriptionKey?: string;
|
|
20
21
|
groupValues?: string;
|
|
21
22
|
groupLabel?: string;
|
|
22
23
|
trackBy?: string;
|
|
@@ -83,6 +84,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
83
84
|
clearable: boolean;
|
|
84
85
|
hideSelected: boolean;
|
|
85
86
|
querySearchParam: string;
|
|
87
|
+
descriptionKey: string;
|
|
86
88
|
trackBy: string;
|
|
87
89
|
deselectLabel: string;
|
|
88
90
|
selectLabel: string;
|
|
@@ -62,9 +62,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
62
62
|
}>, {
|
|
63
63
|
modelValue: string[];
|
|
64
64
|
returnObject: boolean;
|
|
65
|
+
url: string;
|
|
65
66
|
headers: Header[];
|
|
66
67
|
formFilters: FormFilter[];
|
|
67
|
-
url: string;
|
|
68
68
|
queryParams: Record<string, string>;
|
|
69
69
|
enableButtons: boolean;
|
|
70
70
|
enableButtonsFilter: boolean;
|
|
@@ -62,9 +62,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
62
62
|
}>, {
|
|
63
63
|
modelValue: string[];
|
|
64
64
|
returnObject: boolean;
|
|
65
|
+
url: string;
|
|
65
66
|
headers: Header[];
|
|
66
67
|
formFilters: FormFilter[];
|
|
67
|
-
url: string;
|
|
68
68
|
queryParams: Record<string, string>;
|
|
69
69
|
enableButtons: boolean;
|
|
70
70
|
enableButtonsFilter: boolean;
|
|
@@ -178,6 +178,7 @@ const placeholder = (header) => {
|
|
|
178
178
|
:group-label="header.groupLabel || 'name'"
|
|
179
179
|
:group-values="header.groupValues || 'children'"
|
|
180
180
|
:item-label="header.itemLabel || 'name'"
|
|
181
|
+
:description-key="header.descriptionKey || 'description'"
|
|
181
182
|
:track-by="header.trackBy || 'id'"
|
|
182
183
|
:multiple="header.multiple"
|
|
183
184
|
:disabled="isDisabled"
|
|
@@ -57,9 +57,7 @@ const value = computed({
|
|
|
57
57
|
emit("update:modelValue", value2 || "");
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
|
-
|
|
61
|
-
formsFilters.value = value2 || [];
|
|
62
|
-
});
|
|
60
|
+
const initializedDefaults = /* @__PURE__ */ new Set();
|
|
63
61
|
watch(
|
|
64
62
|
() => props.forms,
|
|
65
63
|
(filter) => {
|
|
@@ -68,7 +66,12 @@ watch(
|
|
|
68
66
|
return;
|
|
69
67
|
}
|
|
70
68
|
filter.forEach((item) => {
|
|
71
|
-
if (item?.value) {
|
|
69
|
+
if (item?.value === void 0 || item?.value === null || initializedDefaults.has(item.name)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
initializedDefaults.add(item.name);
|
|
73
|
+
const currentValue = value.value?.[item.name];
|
|
74
|
+
if (currentValue === void 0 || currentValue === null || currentValue === "") {
|
|
72
75
|
value.value[item.name] = item.value;
|
|
73
76
|
}
|
|
74
77
|
});
|
|
@@ -157,6 +160,7 @@ watch(
|
|
|
157
160
|
:url="form.urlSearch"
|
|
158
161
|
:label="form.label"
|
|
159
162
|
:item-label="form.itemLabel || 'name'"
|
|
163
|
+
:description-key="form.descriptionKey || 'description'"
|
|
160
164
|
:track-by="form.trackBy || 'id'"
|
|
161
165
|
:track-by-value="form.trackByValue"
|
|
162
166
|
:params="form.params"
|
|
@@ -9,6 +9,75 @@ var _vueRouter = require("vue-router");
|
|
|
9
9
|
var _router = require("@vueuse/router");
|
|
10
10
|
var _vue = require("vue");
|
|
11
11
|
const multipleFilterTypes = ["autocomplete", "autocompleteGroups", "select", "bankSelect", "range"];
|
|
12
|
+
function parseQueryToFilterValues(query, formFilters) {
|
|
13
|
+
const result = {};
|
|
14
|
+
formFilters.forEach(filter => {
|
|
15
|
+
const filterType = filter.type ?? "text";
|
|
16
|
+
if (filter.keys && filter.keys.length > 0) {
|
|
17
|
+
const values = [];
|
|
18
|
+
let hasAnyValue = false;
|
|
19
|
+
filter.keys.forEach(keyName => {
|
|
20
|
+
const v = query[keyName];
|
|
21
|
+
if (v !== void 0 && v !== null) {
|
|
22
|
+
hasAnyValue = true;
|
|
23
|
+
values.push(Array.isArray(v) ? v[0] : v);
|
|
24
|
+
} else {
|
|
25
|
+
values.push("");
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
if (hasAnyValue) {
|
|
29
|
+
result[filter.name] = values;
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const queryValue = query[filter.name];
|
|
34
|
+
if (queryValue === void 0 || queryValue === null) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (filterType === "datepickerRange") {
|
|
38
|
+
result[filter.name] = Array.isArray(queryValue) ? queryValue : [queryValue];
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (multipleFilterTypes.includes(filterType) && filter.multiple) {
|
|
42
|
+
result[filter.name] = Array.isArray(queryValue) ? [...queryValue] : [queryValue];
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
result[filter.name] = Array.isArray(queryValue) ? queryValue[0] : queryValue;
|
|
46
|
+
});
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
function urlParamsMatchQuery(urlParams, query, formFilters) {
|
|
50
|
+
const relevantKeys = /* @__PURE__ */new Set();
|
|
51
|
+
formFilters.forEach(filter => {
|
|
52
|
+
relevantKeys.add(filter.name);
|
|
53
|
+
if (filter.keys) {
|
|
54
|
+
filter.keys.forEach(k => relevantKeys.add(k));
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
for (const key of relevantKeys) {
|
|
58
|
+
const a = urlParams[key];
|
|
59
|
+
const b = query[key];
|
|
60
|
+
const aEmpty = a == null || Array.isArray(a) && a.length === 0 || a === "";
|
|
61
|
+
const bEmpty = b == null || Array.isArray(b) && b.length === 0 || b === "";
|
|
62
|
+
if (aEmpty && bEmpty) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (aEmpty || bEmpty) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const aArr = Array.isArray(a) ? a : [a];
|
|
69
|
+
const bArr = Array.isArray(b) ? b : [b];
|
|
70
|
+
if (aArr.length !== bArr.length) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
for (let i = 0; i < aArr.length; i++) {
|
|
74
|
+
if (String(aArr[i]) !== String(bArr[i])) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
12
81
|
function useTableFilters({
|
|
13
82
|
formFilters,
|
|
14
83
|
syncFiltersWithUrl
|
|
@@ -120,13 +189,17 @@ function useTableFilters({
|
|
|
120
189
|
return parsedFilters;
|
|
121
190
|
}
|
|
122
191
|
const urlQueryParams = (0, _vue.computed)(() => convertFiltersToUrlParams(filters.value, formFilters.value));
|
|
123
|
-
(0, _vue.watch)(() => route.query,
|
|
192
|
+
(0, _vue.watch)([() => route.query, formFilters], () => {
|
|
124
193
|
if (isUpdatingFromFilters) {
|
|
125
194
|
isUpdatingFromFilters = false;
|
|
126
195
|
return;
|
|
127
196
|
}
|
|
197
|
+
const currentAsUrlParams = convertFiltersToUrlParams(filters.value, formFilters.value);
|
|
198
|
+
if (urlParamsMatchQuery(currentAsUrlParams, route.query, formFilters.value)) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
128
201
|
isUpdatingFromUrl = true;
|
|
129
|
-
filters.value = query;
|
|
202
|
+
filters.value = parseQueryToFilterValues(route.query, formFilters.value);
|
|
130
203
|
}, {
|
|
131
204
|
immediate: true,
|
|
132
205
|
deep: true
|
|
@@ -2,6 +2,75 @@ import { useRoute, useRouter } from "vue-router";
|
|
|
2
2
|
import { useRouteQuery } from "@vueuse/router";
|
|
3
3
|
import { computed, ref, watch } from "vue";
|
|
4
4
|
const multipleFilterTypes = ["autocomplete", "autocompleteGroups", "select", "bankSelect", "range"];
|
|
5
|
+
function parseQueryToFilterValues(query, formFilters) {
|
|
6
|
+
const result = {};
|
|
7
|
+
formFilters.forEach((filter) => {
|
|
8
|
+
const filterType = filter.type ?? "text";
|
|
9
|
+
if (filter.keys && filter.keys.length > 0) {
|
|
10
|
+
const values = [];
|
|
11
|
+
let hasAnyValue = false;
|
|
12
|
+
filter.keys.forEach((keyName) => {
|
|
13
|
+
const v = query[keyName];
|
|
14
|
+
if (v !== void 0 && v !== null) {
|
|
15
|
+
hasAnyValue = true;
|
|
16
|
+
values.push(Array.isArray(v) ? v[0] : v);
|
|
17
|
+
} else {
|
|
18
|
+
values.push("");
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
if (hasAnyValue) {
|
|
22
|
+
result[filter.name] = values;
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const queryValue = query[filter.name];
|
|
27
|
+
if (queryValue === void 0 || queryValue === null) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (filterType === "datepickerRange") {
|
|
31
|
+
result[filter.name] = Array.isArray(queryValue) ? queryValue : [queryValue];
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (multipleFilterTypes.includes(filterType) && filter.multiple) {
|
|
35
|
+
result[filter.name] = Array.isArray(queryValue) ? [...queryValue] : [queryValue];
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
result[filter.name] = Array.isArray(queryValue) ? queryValue[0] : queryValue;
|
|
39
|
+
});
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
function urlParamsMatchQuery(urlParams, query, formFilters) {
|
|
43
|
+
const relevantKeys = /* @__PURE__ */ new Set();
|
|
44
|
+
formFilters.forEach((filter) => {
|
|
45
|
+
relevantKeys.add(filter.name);
|
|
46
|
+
if (filter.keys) {
|
|
47
|
+
filter.keys.forEach((k) => relevantKeys.add(k));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
for (const key of relevantKeys) {
|
|
51
|
+
const a = urlParams[key];
|
|
52
|
+
const b = query[key];
|
|
53
|
+
const aEmpty = a == null || Array.isArray(a) && a.length === 0 || a === "";
|
|
54
|
+
const bEmpty = b == null || Array.isArray(b) && b.length === 0 || b === "";
|
|
55
|
+
if (aEmpty && bEmpty) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (aEmpty || bEmpty) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
const aArr = Array.isArray(a) ? a : [a];
|
|
62
|
+
const bArr = Array.isArray(b) ? b : [b];
|
|
63
|
+
if (aArr.length !== bArr.length) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
for (let i = 0; i < aArr.length; i++) {
|
|
67
|
+
if (String(aArr[i]) !== String(bArr[i])) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
5
74
|
export function useTableFilters({ formFilters, syncFiltersWithUrl }) {
|
|
6
75
|
const route = useRoute();
|
|
7
76
|
const router = useRouter();
|
|
@@ -111,14 +180,18 @@ export function useTableFilters({ formFilters, syncFiltersWithUrl }) {
|
|
|
111
180
|
}
|
|
112
181
|
const urlQueryParams = computed(() => convertFiltersToUrlParams(filters.value, formFilters.value));
|
|
113
182
|
watch(
|
|
114
|
-
() => route.query,
|
|
115
|
-
(
|
|
183
|
+
[() => route.query, formFilters],
|
|
184
|
+
() => {
|
|
116
185
|
if (isUpdatingFromFilters) {
|
|
117
186
|
isUpdatingFromFilters = false;
|
|
118
187
|
return;
|
|
119
188
|
}
|
|
189
|
+
const currentAsUrlParams = convertFiltersToUrlParams(filters.value, formFilters.value);
|
|
190
|
+
if (urlParamsMatchQuery(currentAsUrlParams, route.query, formFilters.value)) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
120
193
|
isUpdatingFromUrl = true;
|
|
121
|
-
filters.value = query;
|
|
194
|
+
filters.value = parseQueryToFilterValues(route.query, formFilters.value);
|
|
122
195
|
},
|
|
123
196
|
{ immediate: true, deep: true }
|
|
124
197
|
);
|
package/dist/types.d.ts
CHANGED
|
@@ -71,6 +71,7 @@ export type FormFilter = {
|
|
|
71
71
|
hasLang?: boolean
|
|
72
72
|
options?: OptionItem[]
|
|
73
73
|
itemLabel?: string
|
|
74
|
+
descriptionKey?: string
|
|
74
75
|
urlSearch?: string
|
|
75
76
|
multiple?: boolean
|
|
76
77
|
trackBy?: string
|
|
@@ -142,6 +143,7 @@ export type EditableDataTableItem = {
|
|
|
142
143
|
searchInternally?: boolean
|
|
143
144
|
trackBy?: string
|
|
144
145
|
itemLabel?: string
|
|
146
|
+
descriptionKey?: string
|
|
145
147
|
multiple?: boolean
|
|
146
148
|
groupLabel?: string
|
|
147
149
|
groupValues?: string
|