@opentiny/vue-search-box 0.0.1
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/README.md +111 -0
- package/es/composables/use-checkbox.es.js +87 -0
- package/es/composables/use-custom.es.js +48 -0
- package/es/composables/use-datepicker.es.js +86 -0
- package/es/composables/use-dropdown.es.js +207 -0
- package/es/composables/use-edit.es.js +106 -0
- package/es/composables/use-init.es.js +64 -0
- package/es/composables/use-match.es.js +170 -0
- package/es/composables/use-num-range.es.js +77 -0
- package/es/composables/use-placeholder.es.js +41 -0
- package/es/composables/use-tag.es.js +51 -0
- package/es/index-DCPOFFNd.css +337 -0
- package/es/index.es.js +10 -0
- package/es/index.type.es.js +1 -0
- package/es/index.vue.es.js +4 -0
- package/es/index.vue.es2.js +1287 -0
- package/es/smb-theme.es.js +18 -0
- package/es/utils/clone.es.js +29 -0
- package/es/utils/date.es.js +431 -0
- package/es/utils/dropdown.es.js +20 -0
- package/es/utils/en_US.es.js +44 -0
- package/es/utils/index.es.js +13 -0
- package/es/utils/tag.es.js +46 -0
- package/es/utils/type.es.js +4 -0
- package/es/utils/validate.es.js +179 -0
- package/es/utils/zh_CN.es.js +44 -0
- package/index.css +337 -0
- package/lib/composables/use-checkbox.cjs.js +87 -0
- package/lib/composables/use-custom.cjs.js +48 -0
- package/lib/composables/use-datepicker.cjs.js +86 -0
- package/lib/composables/use-dropdown.cjs.js +207 -0
- package/lib/composables/use-edit.cjs.js +106 -0
- package/lib/composables/use-init.cjs.js +64 -0
- package/lib/composables/use-match.cjs.js +170 -0
- package/lib/composables/use-num-range.cjs.js +77 -0
- package/lib/composables/use-placeholder.cjs.js +41 -0
- package/lib/composables/use-tag.cjs.js +51 -0
- package/lib/index-DCPOFFNd.css +337 -0
- package/lib/index.cjs.js +10 -0
- package/lib/index.type.cjs.js +1 -0
- package/lib/index.vue.cjs.js +4 -0
- package/lib/index.vue.cjs2.js +1287 -0
- package/lib/smb-theme.cjs.js +18 -0
- package/lib/utils/clone.cjs.js +29 -0
- package/lib/utils/date.cjs.js +431 -0
- package/lib/utils/dropdown.cjs.js +20 -0
- package/lib/utils/en_US.cjs.js +44 -0
- package/lib/utils/index.cjs.js +13 -0
- package/lib/utils/tag.cjs.js +46 -0
- package/lib/utils/type.cjs.js +4 -0
- package/lib/utils/validate.cjs.js +179 -0
- package/lib/utils/zh_CN.cjs.js +44 -0
- package/package.json +65 -0
- package/types/composables/use-checkbox.d.ts +10 -0
- package/types/composables/use-custom.d.ts +7 -0
- package/types/composables/use-datepicker.d.ts +11 -0
- package/types/composables/use-dropdown.d.ts +13 -0
- package/types/composables/use-edit.d.ts +13 -0
- package/types/composables/use-init.d.ts +10 -0
- package/types/composables/use-match.d.ts +8 -0
- package/types/composables/use-num-range.d.ts +9 -0
- package/types/composables/use-placeholder.d.ts +8 -0
- package/types/composables/use-tag.d.ts +9 -0
- package/types/index.type.d.ts +189 -0
- package/types/smb-theme.d.ts +15 -0
- package/types/utils/clone.d.ts +12 -0
- package/types/utils/date.d.ts +234 -0
- package/types/utils/dropdown.d.ts +12 -0
- package/types/utils/en_US.d.ts +41 -0
- package/types/utils/index.d.ts +1 -0
- package/types/utils/tag.d.ts +46 -0
- package/types/utils/type.d.ts +6 -0
- package/types/utils/validate.d.ts +31 -0
- package/types/utils/zh_CN.d.ts +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# TinySearchBox comprehensive search
|
|
2
|
+
|
|
3
|
+
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
4
|
+
|
|
5
|
+
[](#contributors-)
|
|
6
|
+
|
|
7
|
+
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
8
|
+
|
|
9
|
+
TinySearchBox is a powerful and easy-to-use comprehensive search component developed based on tiny Vue. Support multiple criteria filtering such as single choice, multiple choice, time, and time interval.
|
|
10
|
+
|
|
11
|
+
[English](README.md) | 简体中文
|
|
12
|
+
|
|
13
|
+
## Project advantages
|
|
14
|
+
|
|
15
|
+
TinySearchBox has the following characteristics and advantages:
|
|
16
|
+
|
|
17
|
+
-Contains multiple types of conditional filtering, ready to use out of the box.
|
|
18
|
+
-Powerful search function, supporting fuzzy search, single choice, multiple choice, time, time interval, number size, number interval, as well as custom search, etc.
|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
## quick start
|
|
23
|
+
|
|
24
|
+
install TinySearchBox
|
|
25
|
+
|
|
26
|
+
```shell
|
|
27
|
+
npm i @opentiny/tiny-search-box
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
html:
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<script setup>
|
|
34
|
+
const tags = ref([]);
|
|
35
|
+
const items = ref([
|
|
36
|
+
{
|
|
37
|
+
label: '名称',
|
|
38
|
+
field: 'testName',
|
|
39
|
+
replace: true,
|
|
40
|
+
placeholder: '我是自定义名称的占位符',
|
|
41
|
+
options: [
|
|
42
|
+
{
|
|
43
|
+
label: 'test-1'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
label: 'test-2'
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
label: '可用地区',
|
|
52
|
+
field: 'testRegion',
|
|
53
|
+
type: 'checkbox',
|
|
54
|
+
mergeTag: true,
|
|
55
|
+
placeholder: '我是自定义可选地区的占位符',
|
|
56
|
+
editAttrDisabled: true, // 编辑状态此属性禁用,不可变更
|
|
57
|
+
options: [
|
|
58
|
+
{
|
|
59
|
+
label: '华南区',
|
|
60
|
+
id: '2-1'
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
label: '华北区',
|
|
64
|
+
id: '2-2'
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
label: '大小',
|
|
70
|
+
field: 'size',
|
|
71
|
+
type: 'numRange',
|
|
72
|
+
placeholder: '我是自定义大小的占位符',
|
|
73
|
+
unit: 'GB',
|
|
74
|
+
start: -1,
|
|
75
|
+
min: -1,
|
|
76
|
+
max: 20
|
|
77
|
+
}
|
|
78
|
+
]);
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<template>
|
|
82
|
+
<VueSearchBox v-model="tags" :items="items"></VueSearchBox>
|
|
83
|
+
</template>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
import styles:
|
|
87
|
+
|
|
88
|
+
```css
|
|
89
|
+
@import '@opentiny/vue-search-box/index.css';
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Initialize VueSearchBox:
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
import VueSearchBox from '@opentiny/vue-search-box';
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Local development
|
|
99
|
+
|
|
100
|
+
```shell
|
|
101
|
+
git clone git@github.com:opentiny/tiny-search-box.git
|
|
102
|
+
cd tiny-search-box
|
|
103
|
+
pnpm i
|
|
104
|
+
pnpm dev
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Open a browser to access:[http://localhost:5173/](http://localhost:5173/)
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import { getTagId, hasTagItem, createNewTag, emitChangeModelEvent } from "../utils/tag.es.js";
|
|
3
|
+
import { omitObj, deepClone } from "../utils/clone.es.js";
|
|
4
|
+
function useCheckbox({ props, state, emits }) {
|
|
5
|
+
const selectCheckbox = (confirm) => {
|
|
6
|
+
const { checkboxGroup, prevItem, propItem } = state;
|
|
7
|
+
const rest = omitObj(prevItem);
|
|
8
|
+
state.hiden = true;
|
|
9
|
+
if (confirm) {
|
|
10
|
+
const tagList = [];
|
|
11
|
+
const oldValue = deepClone(state.innerModelValue);
|
|
12
|
+
const { mergeTag, operators, label: prevLabel } = prevItem;
|
|
13
|
+
if (mergeTag) {
|
|
14
|
+
let value = "";
|
|
15
|
+
const options = [];
|
|
16
|
+
const { indexMap } = state;
|
|
17
|
+
const hasTagIndex = indexMap.get(prevLabel);
|
|
18
|
+
hasTagIndex !== void 0 && state.innerModelValue.splice(hasTagIndex, 1);
|
|
19
|
+
state.backupList.forEach((item) => {
|
|
20
|
+
const { label } = item;
|
|
21
|
+
const checkboxLabel = `${prevLabel}${label}`;
|
|
22
|
+
const hasItem = checkboxGroup.includes(checkboxLabel);
|
|
23
|
+
if (hasItem) {
|
|
24
|
+
delete item.isFilter;
|
|
25
|
+
const id = getTagId(props, prevItem, item);
|
|
26
|
+
const newOptions = { label: item.label, ...id };
|
|
27
|
+
value += !value ? label : ` | ${label}`;
|
|
28
|
+
options.push(newOptions);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
if (options.length > 0) {
|
|
32
|
+
const newTag = { ...rest, value, options };
|
|
33
|
+
tagList.push(newTag);
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
const { valueMap } = state;
|
|
37
|
+
const indexList = [];
|
|
38
|
+
state.backupList.forEach((item) => {
|
|
39
|
+
const { label } = item;
|
|
40
|
+
const value = `${prevLabel}${label}`;
|
|
41
|
+
const hasItem = checkboxGroup.includes(value);
|
|
42
|
+
if (hasItem && !hasTagItem(state, label)) {
|
|
43
|
+
const id = getTagId(props, prevItem, item);
|
|
44
|
+
const operator = state.operatorValue && operators ? { operator: state.operatorValue } : null;
|
|
45
|
+
const newTag = createNewTag({ ...rest, label: propItem.label, value: label, ...id, ...operator });
|
|
46
|
+
tagList.push(newTag);
|
|
47
|
+
item.isChecked = true;
|
|
48
|
+
} else if (!hasItem && hasTagItem(state, label)) {
|
|
49
|
+
item.isChecked = false;
|
|
50
|
+
const index = valueMap.get(value);
|
|
51
|
+
indexList.push(index);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
if (indexList.length) {
|
|
55
|
+
state.innerModelValue = state.innerModelValue.filter((item, index) => item && !indexList.includes(index));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
emitChangeModelEvent({ emits, state, tagList, oldValue });
|
|
59
|
+
} else {
|
|
60
|
+
propItem.label = "";
|
|
61
|
+
state.inputValue = "";
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const isIndeterminate = computed(
|
|
65
|
+
() => state.checkboxGroup.length > 0 && state.checkboxGroup.length !== state.filterList.length
|
|
66
|
+
);
|
|
67
|
+
const checkAll = computed({
|
|
68
|
+
get: () => state.checkboxGroup.length && state.checkboxGroup.length === state.filterList.length,
|
|
69
|
+
set: (val) => {
|
|
70
|
+
if (val) {
|
|
71
|
+
state.checkboxGroup = state.filterList.flatMap((item) => `${state.prevItem.label}${item.label}`);
|
|
72
|
+
} else {
|
|
73
|
+
state.checkboxGroup = [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
const isShowClose = computed(() => props.modelValue.length || state.propItem.label || state.inputValue);
|
|
78
|
+
return {
|
|
79
|
+
selectCheckbox,
|
|
80
|
+
isIndeterminate,
|
|
81
|
+
checkAll,
|
|
82
|
+
isShowClose
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
useCheckbox
|
|
87
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { emitChangeModelEvent, hasTagItem, resetInput } from "../utils/tag.es.js";
|
|
2
|
+
import { showDropdown, showPopover } from "../utils/dropdown.es.js";
|
|
3
|
+
function useCustom({ state, emits }) {
|
|
4
|
+
const updateCustomValue = (customTag) => {
|
|
5
|
+
const { prevItem, indexMap } = state;
|
|
6
|
+
const { replace, label } = prevItem;
|
|
7
|
+
const tagList = [];
|
|
8
|
+
if (replace && indexMap.has(label)) {
|
|
9
|
+
const index = indexMap.get(label);
|
|
10
|
+
const newTag = { ...prevItem, ...customTag };
|
|
11
|
+
emitChangeModelEvent({ emits, state, newTag, index });
|
|
12
|
+
return;
|
|
13
|
+
} else if (!replace && Array.isArray(customTag)) {
|
|
14
|
+
customTag.forEach((tag) => {
|
|
15
|
+
if (!hasTagItem(state, tag.value)) {
|
|
16
|
+
tagList.push({ ...prevItem, ...tag });
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
} else {
|
|
20
|
+
if (!hasTagItem(state, customTag.value)) {
|
|
21
|
+
tagList.push({ ...prevItem, ...customTag });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
emitChangeModelEvent({ emits, state, tagList });
|
|
25
|
+
};
|
|
26
|
+
const handleConfirm = (customTag) => {
|
|
27
|
+
if (!customTag) {
|
|
28
|
+
resetInput(state);
|
|
29
|
+
showDropdown(state, false);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
updateCustomValue(customTag);
|
|
33
|
+
};
|
|
34
|
+
const handleEditConfirm = (customTag) => {
|
|
35
|
+
if (!customTag) {
|
|
36
|
+
showPopover(state, false);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
updateCustomValue(customTag);
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
handleConfirm,
|
|
43
|
+
handleEditConfirm
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
useCustom
|
|
48
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { showDropdown } from "../utils/dropdown.es.js";
|
|
2
|
+
import { getVerifyDateTag } from "../utils/validate.es.js";
|
|
3
|
+
import { emitChangeModelEvent } from "../utils/tag.es.js";
|
|
4
|
+
function useDatePicker({ props, state, emits }) {
|
|
5
|
+
const { instance } = state;
|
|
6
|
+
const onConfirmDate = async (confirm, isDateTimeType = false) => {
|
|
7
|
+
if (!confirm) {
|
|
8
|
+
state.propItem.label = "";
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const newTag = await getVerifyDateTag(instance, state, props, isDateTimeType);
|
|
12
|
+
if (newTag) {
|
|
13
|
+
const newValue = props.modelValue.filter((prev) => prev.type !== newTag.type || prev.field !== newTag.field);
|
|
14
|
+
newValue.push(newTag);
|
|
15
|
+
emitChangeModelEvent({ emits, state, newValue });
|
|
16
|
+
showDropdown(state, false);
|
|
17
|
+
} else {
|
|
18
|
+
showDropdown(state);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const handleDateShow = () => showDropdown(state);
|
|
22
|
+
const pickerOptions = (startDate, endName = "") => ({
|
|
23
|
+
disabledDate(time) {
|
|
24
|
+
const { maxTimeLength = 0, min, max } = state.prevItem;
|
|
25
|
+
const endDate = state[endName];
|
|
26
|
+
const curTime = time.getTime();
|
|
27
|
+
if (maxTimeLength > 0) {
|
|
28
|
+
if (min || max) {
|
|
29
|
+
if (endName && endDate) {
|
|
30
|
+
const end = new Date(endDate).getTime();
|
|
31
|
+
const start = !min && max ? end - maxTimeLength : Math.max(min.getTime(), end - maxTimeLength);
|
|
32
|
+
return curTime < start || curTime > end;
|
|
33
|
+
} else if (!endName && startDate) {
|
|
34
|
+
const start = new Date(startDate).getTime();
|
|
35
|
+
const end = min && !max ? start + maxTimeLength : Math.min(max.getTime(), start + maxTimeLength);
|
|
36
|
+
return curTime < start || curTime > end;
|
|
37
|
+
} else {
|
|
38
|
+
return min && curTime < min.getTime() || max && curTime > max.getTime();
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
if (endName && endDate) {
|
|
42
|
+
const end = new Date(endDate).getTime();
|
|
43
|
+
const start = end - maxTimeLength;
|
|
44
|
+
return curTime < start || curTime > end;
|
|
45
|
+
} else if (!endName && startDate) {
|
|
46
|
+
const start = new Date(startDate).getTime();
|
|
47
|
+
const end = start + maxTimeLength;
|
|
48
|
+
return curTime < start || curTime > end;
|
|
49
|
+
} else {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
if (min || max) {
|
|
55
|
+
if (endName && endDate) {
|
|
56
|
+
const end = new Date(endDate).getTime();
|
|
57
|
+
return min && curTime < min.getTime() || curTime > end;
|
|
58
|
+
} else if (!endName && startDate) {
|
|
59
|
+
const start = new Date(startDate).getTime();
|
|
60
|
+
return curTime < start || max && curTime > max.getTime();
|
|
61
|
+
} else {
|
|
62
|
+
return curTime < min || curTime > max;
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
if (endName && endDate) {
|
|
66
|
+
const end = new Date(endDate).getTime();
|
|
67
|
+
return curTime > end;
|
|
68
|
+
} else if (!endName && startDate) {
|
|
69
|
+
const start = new Date(startDate).getTime();
|
|
70
|
+
return curTime < start;
|
|
71
|
+
} else {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
onConfirmDate,
|
|
80
|
+
handleDateShow,
|
|
81
|
+
pickerOptions
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export {
|
|
85
|
+
useDatePicker
|
|
86
|
+
};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { hasTagItem, getTagId, createNewTag, resetInput, emitChangeModelEvent } from "../utils/tag.es.js";
|
|
2
|
+
import { showDropdown } from "../utils/dropdown.es.js";
|
|
3
|
+
import { setStateNumRange } from "../utils/validate.es.js";
|
|
4
|
+
import { omitObj, deepClone } from "../utils/clone.es.js";
|
|
5
|
+
function useDropdown({ props, emits, state, t, format }) {
|
|
6
|
+
const { instance } = state;
|
|
7
|
+
const showValueItem = (item) => {
|
|
8
|
+
var _a;
|
|
9
|
+
const { start, end, type } = item;
|
|
10
|
+
state.backupList = ((_a = item.options) == null ? void 0 : _a.length) ? item.options : [];
|
|
11
|
+
if (type === "numRange") {
|
|
12
|
+
setStateNumRange(state, item, t);
|
|
13
|
+
state.hiden = false;
|
|
14
|
+
} else if (type === "dateRange") {
|
|
15
|
+
const { dateRangeFormat } = state;
|
|
16
|
+
if (!state.startDate && start) {
|
|
17
|
+
const newStart = format(start, dateRangeFormat);
|
|
18
|
+
state.startDate = state.endDate < newStart ? null : newStart;
|
|
19
|
+
}
|
|
20
|
+
if (!state.endDate && end) {
|
|
21
|
+
const newEnd = format(end, dateRangeFormat);
|
|
22
|
+
state.endDate = newEnd < state.startDate ? null : newEnd;
|
|
23
|
+
}
|
|
24
|
+
state.hiden = false;
|
|
25
|
+
} else if (type === "datetimeRange") {
|
|
26
|
+
const { datetimeRangeFormat } = state;
|
|
27
|
+
if (!state.startDateTime && start) {
|
|
28
|
+
const newStart = format(start, datetimeRangeFormat);
|
|
29
|
+
state.startDateTime = state.endDateTime < newStart ? null : newStart;
|
|
30
|
+
}
|
|
31
|
+
if (!state.endDateTime && end) {
|
|
32
|
+
const newEnd = format(end, datetimeRangeFormat);
|
|
33
|
+
state.endDateTime = newEnd < state.startDateTime ? null : newEnd;
|
|
34
|
+
}
|
|
35
|
+
state.hiden = false;
|
|
36
|
+
} else if (state.backupList && type === "checkbox") {
|
|
37
|
+
state.filterList = state.backupList;
|
|
38
|
+
state.checkboxGroup = [];
|
|
39
|
+
state.backupList.forEach((subItem) => {
|
|
40
|
+
if (hasTagItem(state, subItem.label)) {
|
|
41
|
+
state.checkboxGroup.push(`${item.label}${subItem.label}`);
|
|
42
|
+
}
|
|
43
|
+
subItem.isFilter = false;
|
|
44
|
+
});
|
|
45
|
+
state.hiden = false;
|
|
46
|
+
} else if (type === "custom") {
|
|
47
|
+
state.hiden = false;
|
|
48
|
+
}
|
|
49
|
+
if (state.backupList.length && type !== "checkbox") {
|
|
50
|
+
state.backupList.forEach((option) => {
|
|
51
|
+
option.isFilter = false;
|
|
52
|
+
option.isChecked = hasTagItem(state, option.label);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
state.currentOperators = null;
|
|
56
|
+
if (!((type === "radio" || !type) && !state.backupList.length)) {
|
|
57
|
+
showDropdown(state);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const selectPropItem = (item) => {
|
|
61
|
+
const { field, label } = item;
|
|
62
|
+
state.propItem.label = label;
|
|
63
|
+
emits("first-level-select", field);
|
|
64
|
+
const inputRef = instance.refs.inputRef;
|
|
65
|
+
state.prevItem = item;
|
|
66
|
+
state.backupPrevItem = item;
|
|
67
|
+
const { operators } = item;
|
|
68
|
+
if (operators == null ? void 0 : operators.length) {
|
|
69
|
+
state.operatorValue = "";
|
|
70
|
+
state.currentOperators = operators;
|
|
71
|
+
state.isResetFlag = true;
|
|
72
|
+
showDropdown(state);
|
|
73
|
+
} else {
|
|
74
|
+
state.operatorValue = ":";
|
|
75
|
+
showValueItem(item);
|
|
76
|
+
}
|
|
77
|
+
state.inputValue = "";
|
|
78
|
+
inputRef.focus();
|
|
79
|
+
};
|
|
80
|
+
const setOperator = (operator) => {
|
|
81
|
+
state.operatorValue = operator;
|
|
82
|
+
showValueItem(state.prevItem);
|
|
83
|
+
};
|
|
84
|
+
const updateModelValue = (prevItem, item, label, value) => {
|
|
85
|
+
const { replace, operators, mergeTag } = prevItem;
|
|
86
|
+
const rest = omitObj(prevItem);
|
|
87
|
+
const { indexMap } = state;
|
|
88
|
+
const index = indexMap.get(label);
|
|
89
|
+
const id = getTagId(props, prevItem, item);
|
|
90
|
+
const operator = state.operatorValue && operators ? { operator: state.operatorValue } : null;
|
|
91
|
+
let newTag = null;
|
|
92
|
+
if (mergeTag) {
|
|
93
|
+
const options = { label: value, ...id };
|
|
94
|
+
if (index >= 0) {
|
|
95
|
+
const newValue2 = `${state.innerModelValue[index].value} | ${value}`;
|
|
96
|
+
const newOptions = [...state.innerModelValue[index].options, options];
|
|
97
|
+
newTag = createNewTag({ ...state.innerModelValue[index], value: newValue2, options: newOptions });
|
|
98
|
+
} else {
|
|
99
|
+
newTag = createNewTag({ ...rest, label, value, options: [options] });
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
newTag = createNewTag({ ...rest, label, value, ...id, ...operator });
|
|
103
|
+
}
|
|
104
|
+
if (hasTagItem(state, value, label)) {
|
|
105
|
+
resetInput(state);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const oldValue = deepClone(state.innerModelValue);
|
|
109
|
+
if ((replace || mergeTag) && index >= 0) {
|
|
110
|
+
state.innerModelValue.splice(index, 1);
|
|
111
|
+
}
|
|
112
|
+
state.innerModelValue.push(newTag);
|
|
113
|
+
const newValue = state.innerModelValue;
|
|
114
|
+
emitChangeModelEvent({ emits, state, newValue, oldValue });
|
|
115
|
+
};
|
|
116
|
+
const selectRadioItem = (item, isPotential = false) => {
|
|
117
|
+
if (isPotential) {
|
|
118
|
+
state.prevItem = item;
|
|
119
|
+
state.backupPrevItem = item;
|
|
120
|
+
}
|
|
121
|
+
const { prevItem } = state;
|
|
122
|
+
const value = item.value || item.label;
|
|
123
|
+
const inputRef = instance.refs.inputRef;
|
|
124
|
+
if (!hasTagItem(state, value)) {
|
|
125
|
+
const tagLabel = state.propItem.label || item.label;
|
|
126
|
+
updateModelValue(prevItem, item, tagLabel, value);
|
|
127
|
+
}
|
|
128
|
+
inputRef.focus();
|
|
129
|
+
};
|
|
130
|
+
const hasNotInputValueCreateTag = (propItem, prevItem) => {
|
|
131
|
+
if (propItem.label) {
|
|
132
|
+
if (!prevItem.options) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const hasTag = props.modelValue.find((item) => item.value === prevItem.options[0].label);
|
|
136
|
+
if (!hasTag) {
|
|
137
|
+
const label = prevItem.label;
|
|
138
|
+
const value = prevItem.options && prevItem.options[0].label;
|
|
139
|
+
updateModelValue(prevItem, prevItem.options[0], label, value);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
emits("search", state.innerModelValue);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const newTagUpdateModelValue = (prevItem, propItem, tag) => {
|
|
147
|
+
const item = state.backupList.find((subItem) => subItem.label === tag);
|
|
148
|
+
updateModelValue(prevItem, item, propItem.label, tag);
|
|
149
|
+
};
|
|
150
|
+
const hasInputValueCreateTag = (inputValue, propItem, prevItem) => {
|
|
151
|
+
var _a;
|
|
152
|
+
if (propItem.label) {
|
|
153
|
+
const { regexp, replace, type, mergeTag } = prevItem;
|
|
154
|
+
const tagList = type !== "checkbox" && replace || type === "checkbox" && mergeTag ? [inputValue] : inputValue.split(props.splitInputValue);
|
|
155
|
+
if (regexp) {
|
|
156
|
+
for (const tag of tagList) {
|
|
157
|
+
if (regexp.test(tag)) {
|
|
158
|
+
newTagUpdateModelValue(prevItem, propItem, tag);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
for (const tag of tagList) {
|
|
163
|
+
newTagUpdateModelValue(prevItem, propItem, tag);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
} else {
|
|
167
|
+
const { items, defaultField } = props;
|
|
168
|
+
const currentItem = defaultField ? items.find((item) => item.field === defaultField) : state.allTypeAttri;
|
|
169
|
+
const { replace, type, mergeTag } = currentItem;
|
|
170
|
+
const tagList = type !== "checkbox" && replace || type === "checkbox" && mergeTag ? [inputValue] : inputValue.split(props.splitInputValue);
|
|
171
|
+
if ((_a = currentItem == null ? void 0 : currentItem.options) == null ? void 0 : _a.length) {
|
|
172
|
+
state.backupList = [...currentItem.options];
|
|
173
|
+
state.backupList.forEach((item) => {
|
|
174
|
+
const label2 = item.value || item.label;
|
|
175
|
+
if (tagList.includes(label2)) {
|
|
176
|
+
item.isChecked = true;
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
const label = currentItem.label;
|
|
181
|
+
for (const tag of tagList) {
|
|
182
|
+
updateModelValue(currentItem, {}, label, tag);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
const createTag = () => {
|
|
187
|
+
const { inputValue, propItem, prevItem } = state;
|
|
188
|
+
showDropdown(state, false);
|
|
189
|
+
if (!inputValue) {
|
|
190
|
+
hasNotInputValueCreateTag(propItem, prevItem);
|
|
191
|
+
} else {
|
|
192
|
+
const { maxlength } = props;
|
|
193
|
+
if (maxlength && maxlength < inputValue.length) {
|
|
194
|
+
emits("exceed", maxlength);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
hasInputValueCreateTag(inputValue, propItem, prevItem);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
const helpClick = () => {
|
|
201
|
+
emits("help");
|
|
202
|
+
};
|
|
203
|
+
return { selectPropItem, selectRadioItem, createTag, helpClick, setOperator };
|
|
204
|
+
}
|
|
205
|
+
export {
|
|
206
|
+
useDropdown
|
|
207
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { emitChangeModelEvent } from "../utils/tag.es.js";
|
|
2
|
+
import { setStateNumRange, getVerifyNumTag, getVerifyDateTag, getVerifyTag } from "../utils/validate.es.js";
|
|
3
|
+
import { showDropdown } from "../utils/dropdown.es.js";
|
|
4
|
+
function useEdit({ props, state, t, nextTick, format, emits }) {
|
|
5
|
+
const { instance } = state;
|
|
6
|
+
const setDropdownProps = (curTag) => {
|
|
7
|
+
var _a;
|
|
8
|
+
const { operator, value, start, end } = curTag;
|
|
9
|
+
const { options, operators, type, mergeTag } = state.prevItem;
|
|
10
|
+
if (type === "custom") {
|
|
11
|
+
return;
|
|
12
|
+
} else if (type === "numRange") {
|
|
13
|
+
setStateNumRange(state, curTag, t);
|
|
14
|
+
} else if (type === "dateRange") {
|
|
15
|
+
const { dateRangeFormat } = state;
|
|
16
|
+
state.startDate = format(start, dateRangeFormat);
|
|
17
|
+
state.endDate = format(end, dateRangeFormat);
|
|
18
|
+
} else if (type === "datetimeRange") {
|
|
19
|
+
const { datetimeRangeFormat } = state;
|
|
20
|
+
state.startDateTime = format(start, datetimeRangeFormat);
|
|
21
|
+
state.endDateTime = format(end, datetimeRangeFormat);
|
|
22
|
+
} else {
|
|
23
|
+
if (mergeTag) {
|
|
24
|
+
state.inputEditValue = (_a = curTag.options) == null ? void 0 : _a.flatMap((item) => item.label);
|
|
25
|
+
state.currentEditSelectTags = state.inputEditValue;
|
|
26
|
+
} else {
|
|
27
|
+
state.inputEditValue = value;
|
|
28
|
+
}
|
|
29
|
+
state.currentEditValue = options;
|
|
30
|
+
}
|
|
31
|
+
state.operatorValue = operator;
|
|
32
|
+
state.currentOperators = operators;
|
|
33
|
+
};
|
|
34
|
+
const editTag = (tag, index, e) => {
|
|
35
|
+
if (!props.editable || tag.type && tag.type === "map") {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
showDropdown(state, false);
|
|
39
|
+
state.popoverVisible = false;
|
|
40
|
+
const dom = e.target.classList.contains("tiny-tag") ? e.target : e.srcElement.parentElement;
|
|
41
|
+
nextTick(() => {
|
|
42
|
+
const { popoverRef } = instance.refs;
|
|
43
|
+
popoverRef.state.referenceElm = dom;
|
|
44
|
+
popoverRef.state.popperElm && (popoverRef.state.popperElm.style.display = "none");
|
|
45
|
+
popoverRef.doDestroy();
|
|
46
|
+
state.popoverVisible = true;
|
|
47
|
+
});
|
|
48
|
+
state.prevItem = state.recordItems.find((item) => item.field === tag.field);
|
|
49
|
+
!state.prevItem && (state.prevItem = tag);
|
|
50
|
+
state.selectValue = tag.label;
|
|
51
|
+
state.currentModelValueIndex = index;
|
|
52
|
+
setDropdownProps(tag);
|
|
53
|
+
};
|
|
54
|
+
const selectPropChange = (item, disabled) => {
|
|
55
|
+
if (disabled) return;
|
|
56
|
+
state.prevItem = item;
|
|
57
|
+
setDropdownProps(item);
|
|
58
|
+
};
|
|
59
|
+
const confirmEditTag = async (isConfirm) => {
|
|
60
|
+
if (!isConfirm) {
|
|
61
|
+
state.popoverVisible = false;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const { prevItem, currentModelValueIndex: index } = state;
|
|
65
|
+
let newTag = null;
|
|
66
|
+
if (prevItem.type === "numRange") {
|
|
67
|
+
newTag = await getVerifyNumTag(instance, state, props);
|
|
68
|
+
} else if (prevItem.type === "dateRange") {
|
|
69
|
+
newTag = await getVerifyDateTag(instance, state, props, false);
|
|
70
|
+
} else if (prevItem.type === "datetimeRange") {
|
|
71
|
+
newTag = await getVerifyDateTag(instance, state, props, true);
|
|
72
|
+
} else {
|
|
73
|
+
newTag = await getVerifyTag(instance, state, props);
|
|
74
|
+
}
|
|
75
|
+
if (newTag) {
|
|
76
|
+
emitChangeModelEvent({ emits, state, index, newTag, isEdit: true });
|
|
77
|
+
state.popoverVisible = false;
|
|
78
|
+
} else {
|
|
79
|
+
state.popoverVisible = true;
|
|
80
|
+
}
|
|
81
|
+
state.currentEditValue = [];
|
|
82
|
+
};
|
|
83
|
+
const selectItemIsDisable = (item) => {
|
|
84
|
+
var _a, _b, _c, _d;
|
|
85
|
+
if (item.type && item.type === "map") {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
if (((_a = state.prevItem) == null ? void 0 : _a.operators) || item.operators) {
|
|
89
|
+
return ((_b = state.prevItem.operators) == null ? void 0 : _b.length) !== ((_c = item.operators) == null ? void 0 : _c.length);
|
|
90
|
+
}
|
|
91
|
+
const typeArr = ["radio", "checkbox"];
|
|
92
|
+
if (state.prevItem.type && typeArr.includes(state.prevItem.type)) {
|
|
93
|
+
return !item.type ? false : !typeArr.includes(item.type);
|
|
94
|
+
}
|
|
95
|
+
return ((_d = state.prevItem) == null ? void 0 : _d.type) !== item.type;
|
|
96
|
+
};
|
|
97
|
+
return {
|
|
98
|
+
editTag,
|
|
99
|
+
confirmEditTag,
|
|
100
|
+
selectPropChange,
|
|
101
|
+
selectItemIsDisable
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
useEdit
|
|
106
|
+
};
|