yc-pro-components 0.0.47 → 0.0.49
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/es/components/index.mjs +1 -0
- package/es/components/yc-plus-page/index.d.ts +2 -0
- package/es/components/yc-plus-page/index.mjs +1 -0
- package/es/components/yc-plus-page/src/header-filter-cell.vue.mjs +1 -1
- package/es/components/yc-plus-page/src/header-filter-cell.vue2.mjs +55 -31
- package/es/components/yc-plus-page/src/use-local-header-filter.d.ts +93 -0
- package/es/components/yc-plus-page/src/use-local-header-filter.mjs +151 -0
- package/es/index.css +10 -10
- package/es/index.mjs +1 -0
- package/index.css +13 -7
- package/index.js +218 -48
- package/index.min.css +1 -1
- package/index.min.js +11 -11
- package/index.min.mjs +11 -11
- package/index.mjs +218 -49
- package/lib/components/index.js +2 -0
- package/lib/components/yc-plus-page/index.d.ts +2 -0
- package/lib/components/yc-plus-page/index.js +2 -0
- package/lib/components/yc-plus-page/src/header-filter-cell.vue.js +1 -1
- package/lib/components/yc-plus-page/src/header-filter-cell.vue2.js +53 -29
- package/lib/components/yc-plus-page/src/use-local-header-filter.d.ts +93 -0
- package/lib/components/yc-plus-page/src/use-local-header-filter.js +153 -0
- package/lib/index.css +11 -11
- package/lib/index.js +2 -0
- package/locale/en.js +1 -1
- package/locale/en.min.js +1 -1
- package/locale/en.min.mjs +1 -1
- package/locale/en.mjs +1 -1
- package/locale/ja.js +1 -1
- package/locale/ja.min.js +1 -1
- package/locale/ja.min.mjs +1 -1
- package/locale/ja.mjs +1 -1
- package/locale/ko.js +1 -1
- package/locale/ko.min.js +1 -1
- package/locale/ko.min.mjs +1 -1
- package/locale/ko.mjs +1 -1
- package/locale/zh-cn.js +1 -1
- package/locale/zh-cn.min.js +1 -1
- package/locale/zh-cn.min.mjs +1 -1
- package/locale/zh-cn.mjs +1 -1
- package/locale/zh-tw.js +1 -1
- package/locale/zh-tw.min.js +1 -1
- package/locale/zh-tw.min.mjs +1 -1
- package/locale/zh-tw.mjs +1 -1
- package/package.json +1 -1
package/es/components/index.mjs
CHANGED
|
@@ -47,6 +47,7 @@ export { useVirtualScroll } from './virtual-table/src/use-virtual-scroll.mjs';
|
|
|
47
47
|
export { DEFAULT_CDN_CONFIG, DEFAULT_YC_CONFIG, YC_CONFIG_KEY } from './yc-config-provider/src/type.mjs';
|
|
48
48
|
export { useYcAuth, useYcCdn, useYcCdnUrl, useYcComponentConfig, useYcConfig, useYcPerms, useYcShowPageSearch, useYcTranslate } from './yc-config-provider/src/useYcConfig.mjs';
|
|
49
49
|
export { useHeaderFilter } from './yc-plus-page/src/use-header-filter.mjs';
|
|
50
|
+
export { useLocalHeaderFilter } from './yc-plus-page/src/use-local-header-filter.mjs';
|
|
50
51
|
export { DEFAULT_OPERATORS, NO_VALUE_OPERATORS, OPERATOR_CATALOG, OPERATOR_LABELS } from './yc-plus-page/src/constants.mjs';
|
|
51
52
|
export { default as ReSelectV2, default as YcSelectV2 } from './yc-select-v2/src/index.vue.mjs';
|
|
52
53
|
export { findNodeById, findNodeByPath, findNodePosition, insertAsChild, insertAsSibling, insertNodeAtPosition, removeNode, reorderNodeChildren, reorderSiblingNodes } from './yc-plus-tree/src/treeDataUtils.mjs';
|
|
@@ -4,6 +4,8 @@ import { DefineComponent } from 'vue';
|
|
|
4
4
|
export type { YcPlusPageProps, FieldCatalogItem, FieldCatalog, OperatorOption, HeaderFilterConfig, ColumnHeaderFilterConfig, HeaderFilterPayload, HeaderFilterResetPayload, FilterItem, HeaderFiltersState, OrderByItem, RequestResponse } from './src/type';
|
|
5
5
|
export { useHeaderFilter } from './src/use-header-filter';
|
|
6
6
|
export type { UseHeaderFilterOptions, UseHeaderFilterReturn } from './src/use-header-filter';
|
|
7
|
+
export { useLocalHeaderFilter } from './src/use-local-header-filter';
|
|
8
|
+
export type { LocalFilterColumnConfig, UseLocalHeaderFilterOptions, UseLocalHeaderFilterReturn } from './src/use-local-header-filter';
|
|
7
9
|
export { OPERATOR_CATALOG, OPERATOR_LABELS, NO_VALUE_OPERATORS, DEFAULT_OPERATORS } from './src/constants';
|
|
8
10
|
export type YcPlusPageInstance = InstanceType<typeof YcPlusPageComponent>;
|
|
9
11
|
export declare const YcPlusPage: DefineComponent;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import YcPlusPageComponent from './src/index.vue.mjs';
|
|
2
2
|
import YcTableHeaderFilterCellComponent from './src/header-filter-cell.vue.mjs';
|
|
3
3
|
export { useHeaderFilter } from './src/use-header-filter.mjs';
|
|
4
|
+
export { useLocalHeaderFilter } from './src/use-local-header-filter.mjs';
|
|
4
5
|
export { DEFAULT_OPERATORS, NO_VALUE_OPERATORS, OPERATOR_CATALOG, OPERATOR_LABELS } from './src/constants.mjs';
|
|
5
6
|
|
|
6
7
|
const YcPlusPage = YcPlusPageComponent;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _sfc_main from './header-filter-cell.vue2.mjs';
|
|
2
2
|
import _export_sfc from '../../../_virtual/_plugin-vue_export-helper.mjs';
|
|
3
3
|
|
|
4
|
-
var YcTableHeaderFilterCellComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
var YcTableHeaderFilterCellComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-3330af37"], ["__file", "header-filter-cell.vue"]]);
|
|
5
5
|
|
|
6
6
|
export { YcTableHeaderFilterCellComponent as default };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineComponent, computed, reactive, ref, watch, onMounted, onBeforeUnmount, openBlock, createElementBlock, createCommentVNode, createElementVNode, normalizeClass,
|
|
1
|
+
import { defineComponent, computed, reactive, ref, watch, onMounted, onBeforeUnmount, openBlock, createElementBlock, withModifiers, createCommentVNode, createElementVNode, normalizeClass, createBlock, resolveDynamicComponent, Fragment, unref, withCtx, toDisplayString, createTextVNode, mergeProps, createVNode, normalizeStyle, renderList, h } from 'vue';
|
|
2
2
|
import { ElTooltip, ElIcon, ElPopover, ElButton, ElTimePicker, ElTimeSelect, ElDatePicker, ElInput } from 'element-plus';
|
|
3
|
-
import { QuestionFilled } from '@element-plus/icons-vue';
|
|
3
|
+
import { QuestionFilled, CaretTop, CaretBottom } from '@element-plus/icons-vue';
|
|
4
4
|
import { NO_VALUE_OPERATORS } from './constants.mjs';
|
|
5
5
|
import { getTooltip } from '../../utils/index.mjs';
|
|
6
6
|
import YcSvgIcon from '../../yc-svg-icon/src/index.vue.mjs';
|
|
@@ -8,7 +8,8 @@ import { useYcCdnUrl } from '../../yc-config-provider/src/useYcConfig.mjs';
|
|
|
8
8
|
|
|
9
9
|
const _hoisted_1 = { class: "yc-header-filter-cell__label-text" };
|
|
10
10
|
const _hoisted_2 = { class: "yc-header-filter-cell__label-text" };
|
|
11
|
-
const _hoisted_3 = {
|
|
11
|
+
const _hoisted_3 = { style: { cursor: "pointer", display: "inline-flex", alignItems: "center" } };
|
|
12
|
+
const _hoisted_4 = {
|
|
12
13
|
class: "yc-header-filter-cell__content",
|
|
13
14
|
style: {
|
|
14
15
|
display: "flex",
|
|
@@ -18,10 +19,10 @@ const _hoisted_3 = {
|
|
|
18
19
|
gap: "4px"
|
|
19
20
|
}
|
|
20
21
|
};
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
22
|
+
const _hoisted_5 = { class: "yc-header-filter-cell__operators" };
|
|
23
|
+
const _hoisted_6 = ["onClick"];
|
|
24
|
+
const _hoisted_7 = { key: 0 };
|
|
25
|
+
const _hoisted_8 = {
|
|
25
26
|
class: "yc-header-filter-cell__actions",
|
|
26
27
|
style: {
|
|
27
28
|
display: "flex",
|
|
@@ -49,7 +50,6 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
49
50
|
const emit = __emit;
|
|
50
51
|
const { getCdnUrl } = useYcCdnUrl();
|
|
51
52
|
const filterIconUrl = computed(() => getCdnUrl("images", "table_filter_icon.svg"));
|
|
52
|
-
const sortIconUrl = computed(() => getCdnUrl("images", "table_sort_icon.svg"));
|
|
53
53
|
const state = reactive({
|
|
54
54
|
selectedOp: "=",
|
|
55
55
|
inputVal: ""
|
|
@@ -193,6 +193,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
193
193
|
modelValue: state.inputVal,
|
|
194
194
|
"onUpdate:modelValue": (v) => state.inputVal = v,
|
|
195
195
|
placeholder: "",
|
|
196
|
+
maxlength: 50,
|
|
196
197
|
style: "margin-top: 4px; width: 100%"
|
|
197
198
|
});
|
|
198
199
|
};
|
|
@@ -208,14 +209,22 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
208
209
|
alignItems: "center",
|
|
209
210
|
gap: "4px",
|
|
210
211
|
cursor: "default"
|
|
211
|
-
}
|
|
212
|
+
},
|
|
213
|
+
onMousedown: _cache[1] || (_cache[1] = withModifiers(() => {
|
|
214
|
+
}, ["stop"])),
|
|
215
|
+
onClick: _cache[2] || (_cache[2] = withModifiers(() => {
|
|
216
|
+
}, ["stop"]))
|
|
212
217
|
},
|
|
213
218
|
[
|
|
219
|
+
createCommentVNode(" @mousedown.stop / @click.stop \u963B\u6B62 el-table <th> \u7684 handleHeaderClick \u548C\u5217 resize \u4E8B\u4EF6\u7A7F\u900F "),
|
|
214
220
|
createCommentVNode(" \u6807\u7B7E\u5185\u5BB9 "),
|
|
215
221
|
createElementVNode(
|
|
216
222
|
"span",
|
|
217
223
|
{
|
|
218
|
-
class: normalizeClass(["yc-header-filter-cell__label", {
|
|
224
|
+
class: normalizeClass(["yc-header-filter-cell__label", {
|
|
225
|
+
"yc-header-filter-cell__label--ellipsis": shouldShowEllipsis.value,
|
|
226
|
+
"yc-header-filter-cell__label--active": isAscActive.value || isDescActive.value || isActive.value
|
|
227
|
+
}]),
|
|
219
228
|
style: {
|
|
220
229
|
userSelect: "none",
|
|
221
230
|
cursor: "pointer"
|
|
@@ -314,19 +323,35 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
314
323
|
class: "yc-header-filter-cell__sort",
|
|
315
324
|
style: {
|
|
316
325
|
display: "inline-flex",
|
|
326
|
+
flexDirection: "column",
|
|
317
327
|
alignItems: "center",
|
|
318
|
-
cursor: "pointer"
|
|
328
|
+
cursor: "pointer",
|
|
329
|
+
lineHeight: 1
|
|
319
330
|
},
|
|
320
331
|
onClick: withModifiers(cycleSort, ["stop"])
|
|
321
332
|
}, [
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
size:
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
333
|
+
createCommentVNode(" \u5347\u5E8F\u7BAD\u5934\uFF1A\u6FC0\u6D3B\u65F6\u9AD8\u4EAE "),
|
|
334
|
+
createVNode(unref(ElIcon), {
|
|
335
|
+
size: 10,
|
|
336
|
+
style: normalizeStyle({ color: isAscActive.value ? "var(--el-color-primary)" : "var(--el-text-color-placeholder)", marginBottom: "-4px" })
|
|
337
|
+
}, {
|
|
338
|
+
default: withCtx(() => [
|
|
339
|
+
createVNode(unref(CaretTop))
|
|
340
|
+
]),
|
|
341
|
+
_: 1
|
|
342
|
+
/* STABLE */
|
|
343
|
+
}, 8, ["style"]),
|
|
344
|
+
createCommentVNode(" \u964D\u5E8F\u7BAD\u5934\uFF1A\u6FC0\u6D3B\u65F6\u9AD8\u4EAE "),
|
|
345
|
+
createVNode(unref(ElIcon), {
|
|
346
|
+
size: 10,
|
|
347
|
+
style: normalizeStyle({ color: isDescActive.value ? "var(--el-color-primary)" : "var(--el-text-color-placeholder)" })
|
|
348
|
+
}, {
|
|
349
|
+
default: withCtx(() => [
|
|
350
|
+
createVNode(unref(CaretBottom))
|
|
351
|
+
]),
|
|
352
|
+
_: 1
|
|
353
|
+
/* STABLE */
|
|
354
|
+
}, 8, ["style"])
|
|
330
355
|
]),
|
|
331
356
|
createCommentVNode(" \u7B5B\u9009\u56FE\u6807\u548C\u5F39\u7A97 "),
|
|
332
357
|
!_ctx.disableFilter ? (openBlock(), createBlock(unref(ElPopover), {
|
|
@@ -335,25 +360,24 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
335
360
|
placement: "bottom-start",
|
|
336
361
|
width: 220,
|
|
337
362
|
visible: popVisible.value,
|
|
363
|
+
"onUpdate:visible": _cache[0] || (_cache[0] = ($event) => popVisible.value = $event),
|
|
338
364
|
"popper-class": "yc-header-filter-pop",
|
|
339
365
|
"popper-style": { zIndex: 4e3 }
|
|
340
366
|
}, {
|
|
341
367
|
reference: withCtx(() => [
|
|
342
|
-
createElementVNode("span",
|
|
343
|
-
style: { cursor: "pointer", display: "inline-flex", alignItems: "center" },
|
|
344
|
-
onClick: _cache[0] || (_cache[0] = withModifiers(($event) => popVisible.value = !popVisible.value, ["stop"]))
|
|
345
|
-
}, [
|
|
368
|
+
createElementVNode("span", _hoisted_3, [
|
|
346
369
|
createVNode(unref(YcSvgIcon), {
|
|
347
370
|
src: filterIconUrl.value,
|
|
348
371
|
size: 14,
|
|
372
|
+
color: isActive.value ? "var(--el-color-primary)" : "currentColor",
|
|
349
373
|
class: normalizeClass({ "yc-header-filter-cell__filter-icon--active": isActive.value })
|
|
350
|
-
}, null, 8, ["src", "class"])
|
|
374
|
+
}, null, 8, ["src", "color", "class"])
|
|
351
375
|
])
|
|
352
376
|
]),
|
|
353
377
|
default: withCtx(() => [
|
|
354
|
-
createElementVNode("div",
|
|
378
|
+
createElementVNode("div", _hoisted_4, [
|
|
355
379
|
createCommentVNode(" \u64CD\u4F5C\u7B26\u5217\u8868 "),
|
|
356
|
-
createElementVNode("div",
|
|
380
|
+
createElementVNode("div", _hoisted_5, [
|
|
357
381
|
(openBlock(true), createElementBlock(
|
|
358
382
|
Fragment,
|
|
359
383
|
null,
|
|
@@ -380,8 +404,8 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
380
404
|
1
|
|
381
405
|
/* TEXT */
|
|
382
406
|
),
|
|
383
|
-
state.selectedOp === op.code ? (openBlock(), createElementBlock("span",
|
|
384
|
-
], 12,
|
|
407
|
+
state.selectedOp === op.code ? (openBlock(), createElementBlock("span", _hoisted_7, "\u2713")) : createCommentVNode("v-if", true)
|
|
408
|
+
], 12, _hoisted_6);
|
|
385
409
|
}),
|
|
386
410
|
128
|
|
387
411
|
/* KEYED_FRAGMENT */
|
|
@@ -390,7 +414,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
390
414
|
createCommentVNode(" \u503C\u8F93\u5165 "),
|
|
391
415
|
needValueInput.value ? (openBlock(), createBlock(resolveDynamicComponent(renderValueField), { key: 0 })) : createCommentVNode("v-if", true),
|
|
392
416
|
createCommentVNode(" \u64CD\u4F5C\u6309\u94AE "),
|
|
393
|
-
createElementVNode("div",
|
|
417
|
+
createElementVNode("div", _hoisted_8, [
|
|
394
418
|
createVNode(unref(ElButton), { onClick: handleReset }, {
|
|
395
419
|
default: withCtx(() => [
|
|
396
420
|
createTextVNode("\u91CD\u7F6E")
|
|
@@ -415,8 +439,8 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
415
439
|
/* STABLE */
|
|
416
440
|
}, 8, ["visible"])) : createCommentVNode("v-if", true)
|
|
417
441
|
],
|
|
418
|
-
|
|
419
|
-
/* NEED_PATCH */
|
|
442
|
+
544
|
|
443
|
+
/* NEED_HYDRATION, NEED_PATCH */
|
|
420
444
|
);
|
|
421
445
|
};
|
|
422
446
|
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { HeaderFiltersState, OrderByItem, OperatorOption, HeaderFilterPayload, HeaderFilterResetPayload } from './type';
|
|
2
|
+
import { Ref, ComputedRef } from 'vue';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 可筛选列配置
|
|
6
|
+
*/
|
|
7
|
+
export interface LocalFilterColumnConfig {
|
|
8
|
+
/** 列字段名(对应 el-table-column 的 prop) */
|
|
9
|
+
prop: string;
|
|
10
|
+
/** 字段类型,决定可用的操作符集合,默认 'string' */
|
|
11
|
+
type?: 'string' | 'number' | 'date' | 'boolean';
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* useLocalHeaderFilter 配置项
|
|
15
|
+
*/
|
|
16
|
+
export interface UseLocalHeaderFilterOptions {
|
|
17
|
+
/** 需要启用筛选的列配置,未配置的列不显示筛选 */
|
|
18
|
+
filterableColumns?: LocalFilterColumnConfig[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* useLocalHeaderFilter 返回值
|
|
22
|
+
*/
|
|
23
|
+
export interface UseLocalHeaderFilterReturn<T> {
|
|
24
|
+
/** 经过筛选和排序后的数据,绑定到表格的 :data */
|
|
25
|
+
filteredData: ComputedRef<T[]>;
|
|
26
|
+
/** 当前筛选状态,传给 YcTableHeaderFilterCell 的 :filters */
|
|
27
|
+
headerFiltersState: HeaderFiltersState;
|
|
28
|
+
/** 当前排序状态,传给 YcTableHeaderFilterCell 的 :order-by */
|
|
29
|
+
orderByState: OrderByItem[];
|
|
30
|
+
/** 筛选确认处理,传给 YcTableHeaderFilterCell 的 @confirm */
|
|
31
|
+
handleFilterConfirm: (payload: HeaderFilterPayload) => void;
|
|
32
|
+
/** 筛选重置处理,传给 YcTableHeaderFilterCell 的 @reset */
|
|
33
|
+
handleFilterReset: (payload: HeaderFilterResetPayload) => void;
|
|
34
|
+
/** 排序切换处理,传给 YcTableHeaderFilterCell 的 @sort-change */
|
|
35
|
+
handleSortChange: (payload: {
|
|
36
|
+
field: string;
|
|
37
|
+
direction?: 'asc' | 'desc';
|
|
38
|
+
}) => void;
|
|
39
|
+
/** 根据 prop 获取操作符列表,传给 YcTableHeaderFilterCell 的 :operators */
|
|
40
|
+
getOpsByProp: (prop: string) => OperatorOption[];
|
|
41
|
+
/** 重置所有筛选和排序 */
|
|
42
|
+
resetAllFilters: () => void;
|
|
43
|
+
/** 是否有激活的筛选条件 */
|
|
44
|
+
hasActiveFilters: ComputedRef<boolean>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 本地数据表头筛选组合式函数
|
|
48
|
+
*
|
|
49
|
+
* @param data - 响应式数据源
|
|
50
|
+
* @param options - 可筛选列配置
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { useLocalHeaderFilter, YcTableHeaderFilterCell } from 'yc-pro-components'
|
|
55
|
+
*
|
|
56
|
+
* const {
|
|
57
|
+
* filteredData,
|
|
58
|
+
* headerFiltersState,
|
|
59
|
+
* orderByState,
|
|
60
|
+
* handleFilterConfirm,
|
|
61
|
+
* handleFilterReset,
|
|
62
|
+
* handleSortChange,
|
|
63
|
+
* getOpsByProp
|
|
64
|
+
* } = useLocalHeaderFilter(tableData, {
|
|
65
|
+
* filterableColumns: [
|
|
66
|
+
* { prop: 'userName', type: 'string' },
|
|
67
|
+
* { prop: 'realShortName', type: 'string' },
|
|
68
|
+
* { prop: 'weight', type: 'number' }
|
|
69
|
+
* ]
|
|
70
|
+
* })
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* 模板中配合 el-table 使用:
|
|
74
|
+
* ```vue
|
|
75
|
+
* <el-table :data="filteredData">
|
|
76
|
+
* <el-table-column prop="userName">
|
|
77
|
+
* <template #header>
|
|
78
|
+
* <YcTableHeaderFilterCell
|
|
79
|
+
* label="客户名称"
|
|
80
|
+
* :column="{ prop: 'userName' }"
|
|
81
|
+
* :operators="getOpsByProp('userName')"
|
|
82
|
+
* :filters="headerFiltersState.filters"
|
|
83
|
+
* :order-by="orderByState"
|
|
84
|
+
* @confirm="handleFilterConfirm"
|
|
85
|
+
* @reset="handleFilterReset"
|
|
86
|
+
* @sort-change="handleSortChange"
|
|
87
|
+
* />
|
|
88
|
+
* </template>
|
|
89
|
+
* </el-table-column>
|
|
90
|
+
* </el-table>
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare function useLocalHeaderFilter<T = Record<string, unknown>>(data: Ref<T[]> | ComputedRef<T[]>, options?: UseLocalHeaderFilterOptions): UseLocalHeaderFilterReturn<T>;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { computed, unref } from 'vue';
|
|
2
|
+
import { useHeaderFilter } from './use-header-filter.mjs';
|
|
3
|
+
|
|
4
|
+
function compareValues(a, b) {
|
|
5
|
+
if (a == null && b == null) return 0;
|
|
6
|
+
if (a == null) return -1;
|
|
7
|
+
if (b == null) return 1;
|
|
8
|
+
const numA = Number(a);
|
|
9
|
+
const numB = Number(b);
|
|
10
|
+
if (!isNaN(numA) && !isNaN(numB)) return numA - numB;
|
|
11
|
+
return String(a).localeCompare(String(b), "zh-CN");
|
|
12
|
+
}
|
|
13
|
+
function matchFilter(value, op, filterValue) {
|
|
14
|
+
const strValue = String(value != null ? value : "").toLowerCase();
|
|
15
|
+
const strFilter = String(filterValue != null ? filterValue : "").toLowerCase();
|
|
16
|
+
switch (op) {
|
|
17
|
+
case "=":
|
|
18
|
+
return strValue === strFilter;
|
|
19
|
+
case "!=":
|
|
20
|
+
return strValue !== strFilter;
|
|
21
|
+
case "like":
|
|
22
|
+
return strValue.includes(strFilter);
|
|
23
|
+
case "not like":
|
|
24
|
+
return !strValue.includes(strFilter);
|
|
25
|
+
case ">":
|
|
26
|
+
return Number(value) > Number(filterValue);
|
|
27
|
+
case ">=":
|
|
28
|
+
return Number(value) >= Number(filterValue);
|
|
29
|
+
case "<":
|
|
30
|
+
return Number(value) < Number(filterValue);
|
|
31
|
+
case "<=":
|
|
32
|
+
return Number(value) <= Number(filterValue);
|
|
33
|
+
case "is null":
|
|
34
|
+
case "empty":
|
|
35
|
+
return value == null || strValue === "";
|
|
36
|
+
case "is not null":
|
|
37
|
+
case "not_empty":
|
|
38
|
+
return value != null && strValue !== "";
|
|
39
|
+
case "in": {
|
|
40
|
+
const set = strFilter.split(",").map((s) => s.trim().toLowerCase());
|
|
41
|
+
return set.includes(strValue);
|
|
42
|
+
}
|
|
43
|
+
case "not in": {
|
|
44
|
+
const set = strFilter.split(",").map((s) => s.trim().toLowerCase());
|
|
45
|
+
return !set.includes(strValue);
|
|
46
|
+
}
|
|
47
|
+
case "between": {
|
|
48
|
+
let parts = strFilter.split(",").map((s) => Number(s.trim()));
|
|
49
|
+
if (parts.length < 2 || isNaN(parts[0]) || isNaN(parts[1])) {
|
|
50
|
+
const hyphenMatch = strFilter.match(/^(-?\d+(?:\.\d+)?)-(-?\d+(?:\.\d+)?)$/);
|
|
51
|
+
if (hyphenMatch) {
|
|
52
|
+
parts = [Number(hyphenMatch[1]), Number(hyphenMatch[2])];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const num = Number(value);
|
|
56
|
+
return parts.length === 2 && !isNaN(num) && !isNaN(parts[0]) && !isNaN(parts[1]) && num >= parts[0] && num <= parts[1];
|
|
57
|
+
}
|
|
58
|
+
case "is true":
|
|
59
|
+
return value === true || strValue === "true" || strValue === "1";
|
|
60
|
+
case "is false":
|
|
61
|
+
return value === false || strValue === "false" || strValue === "0";
|
|
62
|
+
default:
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function useLocalHeaderFilter(data, options) {
|
|
67
|
+
const fieldCatalog = computed(() => {
|
|
68
|
+
const cols = options == null ? void 0 : options.filterableColumns;
|
|
69
|
+
if (!(cols == null ? void 0 : cols.length)) return {};
|
|
70
|
+
const catalog = {};
|
|
71
|
+
for (const col of cols) {
|
|
72
|
+
catalog[col.prop] = {
|
|
73
|
+
type: col.type || "string",
|
|
74
|
+
filter: true,
|
|
75
|
+
allowedField: col.prop
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return catalog;
|
|
79
|
+
});
|
|
80
|
+
const {
|
|
81
|
+
headerFiltersState,
|
|
82
|
+
orderByState,
|
|
83
|
+
upsertHeaderFilter,
|
|
84
|
+
removeHeaderFilter,
|
|
85
|
+
setOrderBy,
|
|
86
|
+
getOpsByProp,
|
|
87
|
+
isEnabled: _isEnabled
|
|
88
|
+
} = useHeaderFilter({
|
|
89
|
+
headerFilterConfig: () => ({
|
|
90
|
+
enabled: true,
|
|
91
|
+
fieldCatalog: fieldCatalog.value
|
|
92
|
+
}),
|
|
93
|
+
hideHeaderFilter: () => false
|
|
94
|
+
});
|
|
95
|
+
const filteredData = computed(() => {
|
|
96
|
+
let result = [...unref(data) || []];
|
|
97
|
+
if (headerFiltersState.filters.length > 0) {
|
|
98
|
+
result = result.filter((row) => {
|
|
99
|
+
const record = row;
|
|
100
|
+
return headerFiltersState.filters.every(
|
|
101
|
+
(filter) => matchFilter(record[filter.field], filter.op, filter.value)
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
if (orderByState.length > 0) {
|
|
106
|
+
result.sort((a, b) => {
|
|
107
|
+
const recA = a;
|
|
108
|
+
const recB = b;
|
|
109
|
+
for (const order of orderByState) {
|
|
110
|
+
const cmp = compareValues(recA[order.field], recB[order.field]);
|
|
111
|
+
if (cmp !== 0) return order.direction === "asc" ? cmp : -cmp;
|
|
112
|
+
}
|
|
113
|
+
return 0;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
});
|
|
118
|
+
const handleFilterConfirm = (payload) => {
|
|
119
|
+
var _a;
|
|
120
|
+
const field = String(((_a = payload.column) == null ? void 0 : _a.prop) || "");
|
|
121
|
+
upsertHeaderFilter(field, payload.op, payload.value);
|
|
122
|
+
};
|
|
123
|
+
const handleFilterReset = (payload) => {
|
|
124
|
+
var _a;
|
|
125
|
+
const field = String(((_a = payload.column) == null ? void 0 : _a.prop) || "");
|
|
126
|
+
removeHeaderFilter(field);
|
|
127
|
+
};
|
|
128
|
+
const handleSortChange = (payload) => {
|
|
129
|
+
setOrderBy(payload.field, payload.direction);
|
|
130
|
+
};
|
|
131
|
+
const resetAllFilters = () => {
|
|
132
|
+
headerFiltersState.filters.splice(0);
|
|
133
|
+
orderByState.splice(0);
|
|
134
|
+
};
|
|
135
|
+
const hasActiveFilters = computed(() => {
|
|
136
|
+
return headerFiltersState.filters.length > 0 || orderByState.length > 0;
|
|
137
|
+
});
|
|
138
|
+
return {
|
|
139
|
+
filteredData,
|
|
140
|
+
headerFiltersState,
|
|
141
|
+
orderByState,
|
|
142
|
+
handleFilterConfirm,
|
|
143
|
+
handleFilterReset,
|
|
144
|
+
handleSortChange,
|
|
145
|
+
getOpsByProp,
|
|
146
|
+
resetAllFilters,
|
|
147
|
+
hasActiveFilters
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export { useLocalHeaderFilter };
|