@winchsa/ui 0.1.52 → 0.1.54
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/ImageCardInput.vue +22 -5
- package/dist/components/table/DataTable.d.vue.ts +1 -1
- package/dist/components/table/DataTable.vue.d.ts +1 -1
- package/dist/components/table/FilterGenerator.vue +7 -4
- package/dist/composables/useTableFilters.js +75 -2
- package/dist/composables/useTableFilters.mjs +76 -3
- package/package.json +1 -1
|
@@ -73,6 +73,21 @@ const initCropper = () => {
|
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
|
+
const closeCropper = () => {
|
|
77
|
+
if (cropperInstance.value) {
|
|
78
|
+
cropperInstance.value.destroy();
|
|
79
|
+
cropperInstance.value = null;
|
|
80
|
+
}
|
|
81
|
+
if (cropImageSrc.value) {
|
|
82
|
+
URL.revokeObjectURL(cropImageSrc.value);
|
|
83
|
+
cropImageSrc.value = null;
|
|
84
|
+
}
|
|
85
|
+
selectedFile.value = null;
|
|
86
|
+
if (fileInputRef.value) {
|
|
87
|
+
fileInputRef.value.value = "";
|
|
88
|
+
}
|
|
89
|
+
cropperDialog.value = false;
|
|
90
|
+
};
|
|
76
91
|
const cropImage = () => {
|
|
77
92
|
if (!cropperInstance.value) {
|
|
78
93
|
return;
|
|
@@ -81,15 +96,17 @@ const cropImage = () => {
|
|
|
81
96
|
width: 200,
|
|
82
97
|
height: 200
|
|
83
98
|
});
|
|
99
|
+
const fileType = selectedFile.value?.type;
|
|
100
|
+
const fileName = selectedFile.value?.name ?? "image.jpg";
|
|
84
101
|
canvas.toBlob((blob) => {
|
|
85
|
-
if (blob
|
|
86
|
-
const croppedFile = new File([blob],
|
|
102
|
+
if (blob) {
|
|
103
|
+
const croppedFile = new File([blob], fileName, { type: fileType });
|
|
87
104
|
generateImageUrl(croppedFile);
|
|
88
105
|
model.value = croppedFile;
|
|
89
106
|
emit("update");
|
|
90
|
-
|
|
107
|
+
closeCropper();
|
|
91
108
|
}
|
|
92
|
-
},
|
|
109
|
+
}, fileType);
|
|
93
110
|
};
|
|
94
111
|
const deleteUserImage = () => {
|
|
95
112
|
imageSrc.value = avatar;
|
|
@@ -179,7 +196,7 @@ const hasImage = computed(() => {
|
|
|
179
196
|
width="500"
|
|
180
197
|
:has-icon="false"
|
|
181
198
|
@save="cropImage"
|
|
182
|
-
@cancel="
|
|
199
|
+
@cancel="closeCropper"
|
|
183
200
|
>
|
|
184
201
|
<img
|
|
185
202
|
v-if="cropImageSrc"
|
|
@@ -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;
|
|
66
65
|
headers: Header[];
|
|
67
66
|
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;
|
|
66
65
|
headers: Header[];
|
|
67
66
|
formFilters: FormFilter[];
|
|
67
|
+
url: string;
|
|
68
68
|
queryParams: Record<string, string>;
|
|
69
69
|
enableButtons: boolean;
|
|
70
70
|
enableButtonsFilter: boolean;
|
|
@@ -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
|
});
|
|
@@ -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
|
);
|