@veltra/desktop 1.1.14 → 1.1.18
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/action/action-group.vue.d.ts +1 -1
- package/dist/components/action/action-group.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/action/action.js.map +1 -1
- package/dist/components/action/action.vue.d.ts +1 -1
- package/dist/components/action/style2.css +0 -4
- package/dist/components/auto-complete/auto-complete.js.map +1 -1
- package/dist/components/auto-complete/style.js +1 -1
- package/dist/components/auto-complete/use-keyboard.js.map +1 -1
- package/dist/components/auto-complete/use-suggestions.js.map +1 -1
- package/dist/components/badge/badge.js +1 -1
- package/dist/components/badge/badge.js.map +1 -1
- package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
- package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.js.map +1 -1
- package/dist/components/batch-edit/helper.js.map +1 -1
- package/dist/components/batch-edit/style.js +1 -1
- package/dist/components/batch-edit/use-edit.js.map +1 -1
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/button/button-group.js.map +1 -1
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/calendar/calendar.js.map +1 -1
- package/dist/components/calendar/utils.js.map +1 -1
- package/dist/components/card/card-action.js.map +1 -1
- package/dist/components/card/card-content.js.map +1 -1
- package/dist/components/card/card-cover.js.map +1 -1
- package/dist/components/card/card-header.js.map +1 -1
- package/dist/components/card/card.js.map +1 -1
- package/dist/components/cascade/cascade-panel-item.js.map +1 -1
- package/dist/components/cascade/cascade.js.map +1 -1
- package/dist/components/cascade/cascade.vue.d.ts +3 -3
- package/dist/components/cascade/node.js.map +1 -1
- package/dist/components/cascade/use-check.js.map +1 -1
- package/dist/components/cascade/use-data-map.js.map +1 -1
- package/dist/components/cascade/use-select.js +1 -1
- package/dist/components/cascade/use-select.js.map +1 -1
- package/dist/components/check-tag/check-tag.js.map +1 -1
- package/dist/components/checkbox/checkbox-button.js.map +1 -1
- package/dist/components/checkbox/checkbox.js.map +1 -1
- package/dist/components/checkbox/style.js +1 -1
- package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
- package/dist/components/code-editor/code-editor.js.map +1 -1
- package/dist/components/collapse/collapse-item.js.map +1 -1
- package/dist/components/collapse/collapse.js.map +1 -1
- package/dist/components/condition-editor/components/condition-group.js +138 -103
- package/dist/components/condition-editor/components/condition-group.js.map +1 -1
- package/dist/components/condition-editor/components/condition-row.js +146 -95
- package/dist/components/condition-editor/components/condition-row.js.map +1 -1
- package/dist/components/condition-editor/condition-editor.js +18 -40
- package/dist/components/condition-editor/condition-editor.js.map +1 -1
- package/dist/components/condition-editor/condition-editor.vue.d.ts +0 -2
- package/dist/components/condition-editor/core/evaluator.d.ts +22 -0
- package/dist/components/condition-editor/core/evaluator.js +111 -50
- package/dist/components/condition-editor/core/evaluator.js.map +1 -1
- package/dist/components/condition-editor/core/operators.js.map +1 -1
- package/dist/components/condition-editor/index.d.ts +2 -1
- package/dist/components/condition-editor/style2.css +159 -82
- package/dist/components/context-menu/api.js.map +1 -1
- package/dist/components/context-menu/context-menu-item.js.map +1 -1
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/context-menu/style.js +1 -1
- package/dist/components/date-panel/date-panel.js.map +1 -1
- package/dist/components/date-panel/headers/day.js.map +1 -1
- package/dist/components/date-panel/headers/month.js.map +1 -1
- package/dist/components/date-panel/headers/year.js.map +1 -1
- package/dist/components/date-panel/panels/day.js.map +1 -1
- package/dist/components/date-panel/panels/month.js.map +1 -1
- package/dist/components/date-panel/panels/year.js.map +1 -1
- package/dist/components/date-panel/use-date-select.js.map +1 -1
- package/dist/components/date-panel/use-panel-date.js.map +1 -1
- package/dist/components/date-panel/use-panel.js.map +1 -1
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/dialog/dialog.js.map +1 -1
- package/dist/components/dialog/style.js +2 -2
- package/dist/components/dialog/use-maximum.js.map +1 -1
- package/dist/components/drawer/drawer.js.map +1 -1
- package/dist/components/drawer/style.js +1 -1
- package/dist/components/dropdown/dropdown.js +1 -0
- package/dist/components/dropdown/dropdown.js.map +1 -1
- package/dist/components/dropdown/style.js +1 -1
- package/dist/components/empty/empty.js.map +1 -1
- package/dist/components/expression-editor/components/path-preview.js.map +1 -1
- package/dist/components/expression-editor/components/variable-picker.js.map +1 -1
- package/dist/components/expression-editor/core/chip.js.map +1 -1
- package/dist/components/expression-editor/core/editor.js.map +1 -1
- package/dist/components/expression-editor/core/mention.js.map +1 -1
- package/dist/components/expression-editor/core/model.js.map +1 -1
- package/dist/components/expression-editor/di.js.map +1 -1
- package/dist/components/expression-editor/expression-editor.js.map +1 -1
- package/dist/components/file-picker/file-picker.js.map +1 -1
- package/dist/components/file-picker/helper.js.map +1 -1
- package/dist/components/file-viewer/file-viewer.js.map +1 -1
- package/dist/components/file-viewer/helper.js.map +1 -1
- package/dist/components/file-viewer/previewers/docx-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/image-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js.map +1 -1
- package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js.map +1 -1
- package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/text-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/video-previewer.js.map +1 -1
- package/dist/components/float-button/float-button.js.map +1 -1
- package/dist/components/form/dynamic-form-model.js.map +1 -1
- package/dist/components/form/form-model.js.map +1 -1
- package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/form/helper.js.map +1 -1
- package/dist/components/form/use-node-interceptor.js.map +1 -1
- package/dist/components/form-item/form-item.js.map +1 -1
- package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/gantt-chart/gantt-chart.js.map +1 -1
- package/dist/components/grid/breakpoint.js.map +1 -1
- package/dist/components/grid/grid-item.js.map +1 -1
- package/dist/components/grid/grid.js.map +1 -1
- package/dist/components/grid/use-responsive.js.map +1 -1
- package/dist/components/grid-input/grid-input.js.map +1 -1
- package/dist/components/group-input/group-input.js.map +1 -1
- package/dist/components/group-input/use-group-items.js.map +1 -1
- package/dist/components/icon/icon.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +4 -0
- package/dist/components/input/input.vue.d.ts +2 -2
- package/dist/components/input/input.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/input/style.js +1 -1
- package/dist/components/kbd/kbd.js.map +1 -1
- package/dist/components/layout/layout-resizer.js.map +1 -1
- package/dist/components/layout/layout.js.map +1 -1
- package/dist/components/list/list-item.js.map +1 -1
- package/dist/components/list/list.js.map +1 -1
- package/dist/components/loading/directive.js.map +1 -1
- package/dist/components/loading/loading.js.map +1 -1
- package/dist/components/loading/style.js +1 -1
- package/dist/components/menu/helper.js.map +1 -1
- package/dist/components/menu/menu-item-collapsed.js.map +1 -1
- package/dist/components/menu/menu-item.js.map +1 -1
- package/dist/components/menu/menu-sub-collapsed.js.map +1 -1
- package/dist/components/menu/menu-sub.js.map +1 -1
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menu/use-menu-item.js.map +1 -1
- package/dist/components/menu/walk-menu-path.js.map +1 -1
- package/dist/components/message/helper.js.map +1 -1
- package/dist/components/message/message-box.js.map +1 -1
- package/dist/components/message/message.js.map +1 -1
- package/dist/components/message/message2.js.map +1 -1
- package/dist/components/message-confirm/message-confirm.js.map +1 -1
- package/dist/components/message-confirm/message-confirm2.js.map +1 -1
- package/dist/components/multi-select/multi-select-option.js.map +1 -1
- package/dist/components/multi-select/multi-select.js.map +1 -1
- package/dist/components/multi-select/multi-select.vue.d.ts +1 -1
- package/dist/components/multi-select/style.js +1 -1
- package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
- package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +3 -3
- package/dist/components/multi-tree-select/style.js +1 -1
- package/dist/components/node-render/node-render.js.map +1 -1
- package/dist/components/notification/index.js.map +1 -1
- package/dist/components/notification/notification.js.map +1 -1
- package/dist/components/notification/notification.vue.d.ts +1 -1
- package/dist/components/number/number.js.map +1 -1
- package/dist/components/number-input/number-input.js.map +1 -1
- package/dist/components/number-input/number-input.vue.d.ts +2 -2
- package/dist/components/number-range-input/number-range-input.js.map +1 -1
- package/dist/components/paginator/paginator.js.map +1 -1
- package/dist/components/palette/color-transform.js.map +1 -1
- package/dist/components/palette/palette-alpha.js.map +1 -1
- package/dist/components/palette/palette-color-switch.js.map +1 -1
- package/dist/components/palette/palette-hue.js.map +1 -1
- package/dist/components/palette/palette-sv.js.map +1 -1
- package/dist/components/palette/palette.js.map +1 -1
- package/dist/components/palette/use-hsv.js.map +1 -1
- package/dist/components/password-input/password-input.js.map +1 -1
- package/dist/components/pop-confirm/pop-confirm.js.map +1 -1
- package/dist/components/progress/progress.js.map +1 -1
- package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
- package/dist/components/radio/radio.js.map +1 -1
- package/dist/components/radio/style.js +1 -1
- package/dist/components/radio-group/radio-group.js.map +1 -1
- package/dist/components/rich-text-editor/rich-text-editor.js.map +1 -1
- package/dist/components/rich-text-editor/toolbar.js.map +1 -1
- package/dist/components/scroll/scroll-bar.js +2 -0
- package/dist/components/scroll/scroll-bar.js.map +1 -1
- package/dist/components/scroll/scroll.js.map +1 -1
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select/use-keyboard.js.map +1 -1
- package/dist/components/select/use-options.js.map +1 -1
- package/dist/components/slider/slider-thumb.js.map +1 -1
- package/dist/components/slider/slider.js +1 -1
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/slider/use-slider.js.map +1 -1
- package/dist/components/steps/steps.js.map +1 -1
- package/dist/components/switch/switch.js.map +1 -1
- package/dist/components/table/di.js.map +1 -1
- package/dist/components/table/node/col.js.map +1 -1
- package/dist/components/table/node/row.js.map +1 -1
- package/dist/components/table/table-body.js.map +1 -1
- package/dist/components/table/table-cell.js.map +1 -1
- package/dist/components/table/table-foot.js.map +1 -1
- package/dist/components/table/table-head.js.map +1 -1
- package/dist/components/table/table-row.js.map +1 -1
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/table/use-check.js.map +1 -1
- package/dist/components/table/use-col-resize.js.map +1 -1
- package/dist/components/table/use-columns.js.map +1 -1
- package/dist/components/table/use-fixed-columns.js.map +1 -1
- package/dist/components/table/use-rows.js.map +1 -1
- package/dist/components/table/use-table.js.map +1 -1
- package/dist/components/table-editor/table-editor.js.map +1 -1
- package/dist/components/tabs/style.js +1 -1
- package/dist/components/tabs/tabs-horizontal.js.map +1 -1
- package/dist/components/tabs/tabs-horizontal.vue.d.ts +3 -3
- package/dist/components/tabs/tabs-vertical.js.map +1 -1
- package/dist/components/tabs/tabs-vertical.vue.d.ts +2 -2
- package/dist/components/tabs/tabs.js.map +1 -1
- package/dist/components/tabs/tabs.vue.d.ts +3 -3
- package/dist/components/tabs/use-tabs-bar.js.map +1 -1
- package/dist/components/tag/tag.js.map +1 -1
- package/dist/components/text/text.js.map +1 -1
- package/dist/components/textarea/style.js +1 -1
- package/dist/components/textarea/textarea.js.map +1 -1
- package/dist/components/textarea/textarea.vue.d.ts +3 -3
- package/dist/components/textarea/utils.js.map +1 -1
- package/dist/components/theme/schema.js.map +1 -1
- package/dist/components/theme/theme.js.map +1 -1
- package/dist/components/tip/tip.js.map +1 -1
- package/dist/components/tip/tip.vue.d.ts +1 -1
- package/dist/components/tip/use-nest.js.map +1 -1
- package/dist/components/tree/tree-node.js.map +1 -1
- package/dist/components/tree/tree-node2.js.map +1 -1
- package/dist/components/tree/tree.js.map +1 -1
- package/dist/components/tree/use-check.js.map +1 -1
- package/dist/components/tree/use-filter.js.map +1 -1
- package/dist/components/tree/use-select.js.map +1 -1
- package/dist/components/tree/use-tree-nodes.js.map +1 -1
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/components/tree-select/tree-select.vue.d.ts +3 -3
- package/dist/components/watermark/watermark.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -1
- package/dist/install.js.map +1 -1
- package/dist/types/batch-edit.d.ts +2 -2
- package/dist/types/condition-editor.d.ts +21 -9
- package/dist/types/index.d.ts +2 -2
- package/package.json +13 -16
- package/src/components/action/style.scss +0 -6
- package/src/components/auto-complete/style.scss +0 -1
- package/src/components/auto-complete/style.ts +1 -1
- package/src/components/badge/badge.vue +1 -1
- package/src/components/batch-edit/style.ts +1 -1
- package/src/components/button/style.scss +1 -1
- package/src/components/cascade/use-select.ts +8 -6
- package/src/components/checkbox/style.ts +1 -1
- package/src/components/collapse/__test__/collapse.test.ts +3 -3
- package/src/components/condition-editor/components/condition-group.vue +118 -87
- package/src/components/condition-editor/components/condition-row.vue +137 -89
- package/src/components/condition-editor/condition-editor.vue +19 -48
- package/src/components/condition-editor/core/evaluator.ts +143 -57
- package/src/components/condition-editor/index.ts +6 -0
- package/src/components/condition-editor/style.scss +189 -102
- package/src/components/context-menu/style.ts +1 -1
- package/src/components/dialog/style.ts +2 -2
- package/src/components/drawer/style.ts +1 -1
- package/src/components/dropdown/style.ts +1 -1
- package/src/components/expression-editor/style.scss +1 -1
- package/src/components/form-item/form-item.vue +4 -9
- package/src/components/input/style.ts +1 -1
- package/src/components/loading/style.ts +1 -1
- package/src/components/menu/style.scss +1 -1
- package/src/components/message/style.scss +1 -1
- package/src/components/multi-select/style.ts +1 -1
- package/src/components/multi-tree-select/style.ts +1 -1
- package/src/components/number-input/__test__/number-input.test.ts +1 -1
- package/src/components/radio/style.ts +1 -1
- package/src/components/slider/slider.vue +1 -1
- package/src/components/table/di.ts +1 -1
- package/src/components/tabs/style.ts +1 -1
- package/src/components/textarea/style.ts +1 -1
- package/src/types/batch-edit.ts +2 -2
- package/src/types/condition-editor.ts +22 -8
|
@@ -1,66 +1,127 @@
|
|
|
1
|
+
import { o } from "@cat-kit/core";
|
|
1
2
|
//#region src/components/condition-editor/core/evaluator.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* 求值表达式
|
|
5
|
+
*
|
|
6
|
+
* - 纯函数,不修改入参
|
|
7
|
+
* - 空表达式(无任何叶子节点)返回 `true`(视作"无限制")
|
|
8
|
+
* - 不完整的叶子(field/operator 缺失、或缺少所需值且 operator 需要值)按 `false` 计
|
|
9
|
+
* - 同组内 AND/OR 按 **从左到右、等优先级** 求值;需要更高优先级请用子分组
|
|
10
|
+
*/
|
|
11
|
+
function evaluate(expression, options = {}) {
|
|
12
|
+
return evaluateGroup(expression, options);
|
|
5
13
|
}
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
14
|
+
function evaluateGroup(group, options) {
|
|
15
|
+
const { children, connectors } = group;
|
|
16
|
+
if (children.length === 0) return true;
|
|
17
|
+
let acc = evaluateNode(children[0], options);
|
|
18
|
+
for (let i = 1; i < children.length; i++) {
|
|
19
|
+
const connector = connectors[i - 1] ?? "and";
|
|
20
|
+
const current = evaluateNode(children[i], options);
|
|
21
|
+
acc = connector === "and" ? acc && current : acc || current;
|
|
22
|
+
}
|
|
23
|
+
return acc;
|
|
9
24
|
}
|
|
10
|
-
function
|
|
11
|
-
return
|
|
25
|
+
function evaluateNode(node, options) {
|
|
26
|
+
return node.type === "group" ? evaluateGroup(node, options) : evaluateLeaf(node, options);
|
|
12
27
|
}
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
case "
|
|
27
|
-
case "
|
|
28
|
-
case "
|
|
29
|
-
case "
|
|
30
|
-
case "
|
|
31
|
-
case "
|
|
28
|
+
function evaluateLeaf(leaf, options) {
|
|
29
|
+
if (!leaf.field || !leaf.operator) return false;
|
|
30
|
+
const field = options.fields?.find((f) => f.value === leaf.field);
|
|
31
|
+
const left = readField(leaf.field, options.data);
|
|
32
|
+
const op = leaf.operator;
|
|
33
|
+
if (op === "empty") return isEmpty(left);
|
|
34
|
+
if (op === "not_empty") return !isEmpty(left);
|
|
35
|
+
if (op === "is_true") return toBool(left) === true;
|
|
36
|
+
if (op === "is_false") return toBool(left) === false;
|
|
37
|
+
if (!isValueProvided(leaf.value)) return false;
|
|
38
|
+
const right = resolveValue(leaf.value, options.data);
|
|
39
|
+
const fieldType = field?.type ?? "string";
|
|
40
|
+
switch (op) {
|
|
41
|
+
case "eq": return compareEq(left, right, fieldType);
|
|
42
|
+
case "ne": return !compareEq(left, right, fieldType);
|
|
43
|
+
case "contains": return toStr(left).includes(toStr(right));
|
|
44
|
+
case "not_contains": return !toStr(left).includes(toStr(right));
|
|
45
|
+
case "gt": return toNumber(left) > toNumber(right);
|
|
46
|
+
case "lt": return toNumber(left) < toNumber(right);
|
|
47
|
+
case "gte": return toNumber(left) >= toNumber(right);
|
|
48
|
+
case "lte": return toNumber(left) <= toNumber(right);
|
|
49
|
+
case "before": return toTime(left) < toTime(right);
|
|
50
|
+
case "after": return toTime(left) > toTime(right);
|
|
51
|
+
case "in": return (Array.isArray(right) ? right.map(toStr) : toStr(right).split(",").map((s) => s.trim()).filter(Boolean)).includes(toStr(left));
|
|
32
52
|
default: return false;
|
|
33
53
|
}
|
|
34
54
|
}
|
|
35
|
-
function
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
function readField(path, data) {
|
|
56
|
+
if (!data) return void 0;
|
|
57
|
+
return o(data).get(path);
|
|
58
|
+
}
|
|
59
|
+
function resolveValue(value, data) {
|
|
60
|
+
if (value.kind === "constant") return value.value;
|
|
61
|
+
return readField(value.name, data);
|
|
62
|
+
}
|
|
63
|
+
function isValueProvided(value) {
|
|
64
|
+
if (value.kind === "constant") return value.value !== "";
|
|
65
|
+
return value.name !== "";
|
|
66
|
+
}
|
|
67
|
+
function isEmpty(v) {
|
|
68
|
+
if (v == null) return true;
|
|
69
|
+
if (typeof v === "string") return v.trim() === "";
|
|
70
|
+
if (Array.isArray(v)) return v.length === 0;
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
function toBool(v) {
|
|
74
|
+
if (typeof v === "boolean") return v;
|
|
75
|
+
if (typeof v === "number") return v !== 0;
|
|
76
|
+
if (typeof v === "string") {
|
|
77
|
+
const s = v.trim().toLowerCase();
|
|
78
|
+
if (s === "true" || s === "1") return true;
|
|
79
|
+
if (s === "false" || s === "0" || s === "") return false;
|
|
80
|
+
}
|
|
81
|
+
return Boolean(v);
|
|
49
82
|
}
|
|
50
|
-
function
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
83
|
+
function toNumber(v) {
|
|
84
|
+
if (typeof v === "number") return v;
|
|
85
|
+
if (typeof v === "boolean") return v ? 1 : 0;
|
|
86
|
+
if (typeof v === "string") {
|
|
87
|
+
const n = Number(v);
|
|
88
|
+
return Number.isNaN(n) ? NaN : n;
|
|
89
|
+
}
|
|
90
|
+
return NaN;
|
|
91
|
+
}
|
|
92
|
+
function toTime(v) {
|
|
93
|
+
if (v instanceof Date) return v.getTime();
|
|
94
|
+
if (typeof v === "number") return v;
|
|
95
|
+
if (typeof v === "string" && v) return new Date(v).getTime();
|
|
96
|
+
return NaN;
|
|
97
|
+
}
|
|
98
|
+
function compareEq(left, right, type) {
|
|
99
|
+
if (type === "number") return toNumber(left) === toNumber(right);
|
|
100
|
+
if (type === "boolean") return toBool(left) === toBool(right);
|
|
101
|
+
if (type === "date") return toTime(left) === toTime(right);
|
|
102
|
+
return toStr(left) === toStr(right);
|
|
103
|
+
}
|
|
104
|
+
function toStr(v) {
|
|
105
|
+
if (v == null) return "";
|
|
106
|
+
if (typeof v === "string") return v;
|
|
107
|
+
if (typeof v === "number" || typeof v === "boolean" || typeof v === "bigint") return String(v);
|
|
108
|
+
if (v instanceof Date) return v.toISOString();
|
|
109
|
+
try {
|
|
110
|
+
return JSON.stringify(v);
|
|
111
|
+
} catch {
|
|
112
|
+
return "";
|
|
113
|
+
}
|
|
54
114
|
}
|
|
55
115
|
function createEmptyGroup() {
|
|
56
116
|
return {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
117
|
+
type: "group",
|
|
118
|
+
children: [],
|
|
119
|
+
connectors: []
|
|
60
120
|
};
|
|
61
121
|
}
|
|
62
|
-
function
|
|
122
|
+
function createEmptyLeaf() {
|
|
63
123
|
return {
|
|
124
|
+
type: "condition",
|
|
64
125
|
field: "",
|
|
65
126
|
operator: "eq",
|
|
66
127
|
value: {
|
|
@@ -70,6 +131,6 @@ function createEmptyItem() {
|
|
|
70
131
|
};
|
|
71
132
|
}
|
|
72
133
|
//#endregion
|
|
73
|
-
export { createEmptyGroup,
|
|
134
|
+
export { createEmptyGroup, createEmptyLeaf, evaluate };
|
|
74
135
|
|
|
75
136
|
//# sourceMappingURL=evaluator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluator.js","names":[],"sources":["../../../../src/components/condition-editor/core/evaluator.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"evaluator.js","names":[],"sources":["../../../../src/components/condition-editor/core/evaluator.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\n\nimport type {\n ConditionConnector,\n ConditionExpression,\n ConditionField,\n ConditionGroup,\n ConditionLeaf,\n ConditionNode,\n ConditionValue\n} from '../../../types'\n\nexport interface EvaluateOptions {\n /** 字段定义 —— 提供后按字段类型做类型感知比较 */\n fields?: ConditionField[]\n /** 上下文数据,用于解析 `kind: 'variable'` 引用 */\n data?: Record<string, unknown>\n}\n\n/**\n * 求值表达式\n *\n * - 纯函数,不修改入参\n * - 空表达式(无任何叶子节点)返回 `true`(视作\"无限制\")\n * - 不完整的叶子(field/operator 缺失、或缺少所需值且 operator 需要值)按 `false` 计\n * - 同组内 AND/OR 按 **从左到右、等优先级** 求值;需要更高优先级请用子分组\n */\nexport function evaluate(expression: ConditionExpression, options: EvaluateOptions = {}): boolean {\n return evaluateGroup(expression, options)\n}\n\nfunction evaluateGroup(group: ConditionGroup, options: EvaluateOptions): boolean {\n const { children, connectors } = group\n if (children.length === 0) return true\n\n let acc = evaluateNode(children[0]!, options)\n for (let i = 1; i < children.length; i++) {\n const connector: ConditionConnector = connectors[i - 1] ?? 'and'\n const current = evaluateNode(children[i]!, options)\n acc = connector === 'and' ? acc && current : acc || current\n }\n return acc\n}\n\nfunction evaluateNode(node: ConditionNode, options: EvaluateOptions): boolean {\n return node.type === 'group' ? evaluateGroup(node, options) : evaluateLeaf(node, options)\n}\n\nfunction evaluateLeaf(leaf: ConditionLeaf, options: EvaluateOptions): boolean {\n if (!leaf.field || !leaf.operator) return false\n const field = options.fields?.find((f) => f.value === leaf.field)\n const left = readField(leaf.field, options.data)\n const op = leaf.operator\n\n if (op === 'empty') return isEmpty(left)\n if (op === 'not_empty') return !isEmpty(left)\n if (op === 'is_true') return toBool(left) === true\n if (op === 'is_false') return toBool(left) === false\n\n // 其余 operator 需要一个右侧比较值\n if (!isValueProvided(leaf.value)) return false\n const right = resolveValue(leaf.value, options.data)\n\n const fieldType = field?.type ?? 'string'\n\n switch (op) {\n case 'eq':\n return compareEq(left, right, fieldType)\n case 'ne':\n return !compareEq(left, right, fieldType)\n case 'contains':\n return toStr(left).includes(toStr(right))\n case 'not_contains':\n return !toStr(left).includes(toStr(right))\n case 'gt':\n return toNumber(left) > toNumber(right)\n case 'lt':\n return toNumber(left) < toNumber(right)\n case 'gte':\n return toNumber(left) >= toNumber(right)\n case 'lte':\n return toNumber(left) <= toNumber(right)\n case 'before':\n return toTime(left) < toTime(right)\n case 'after':\n return toTime(left) > toTime(right)\n case 'in': {\n // 右侧可能是数组、逗号分隔字符串或单值\n const list = Array.isArray(right)\n ? right.map(toStr)\n : toStr(right)\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n return list.includes(toStr(left))\n }\n default:\n return false\n }\n}\n\nfunction readField(path: string, data?: Record<string, unknown>): unknown {\n if (!data) return undefined\n return o(data).get(path)\n}\n\nfunction resolveValue(value: ConditionValue, data?: Record<string, unknown>): unknown {\n if (value.kind === 'constant') return value.value\n return readField(value.name, data)\n}\n\nfunction isValueProvided(value: ConditionValue): boolean {\n if (value.kind === 'constant') return value.value !== ''\n return value.name !== ''\n}\n\nfunction isEmpty(v: unknown): boolean {\n if (v == null) return true\n if (typeof v === 'string') return v.trim() === ''\n if (Array.isArray(v)) return v.length === 0\n return false\n}\n\nfunction toBool(v: unknown): boolean {\n if (typeof v === 'boolean') return v\n if (typeof v === 'number') return v !== 0\n if (typeof v === 'string') {\n const s = v.trim().toLowerCase()\n if (s === 'true' || s === '1') return true\n if (s === 'false' || s === '0' || s === '') return false\n }\n return Boolean(v)\n}\n\nfunction toNumber(v: unknown): number {\n if (typeof v === 'number') return v\n if (typeof v === 'boolean') return v ? 1 : 0\n if (typeof v === 'string') {\n const n = Number(v)\n return Number.isNaN(n) ? Number.NaN : n\n }\n return Number.NaN\n}\n\nfunction toTime(v: unknown): number {\n if (v instanceof Date) return v.getTime()\n if (typeof v === 'number') return v\n if (typeof v === 'string' && v) return new Date(v).getTime()\n return Number.NaN\n}\n\nfunction compareEq(left: unknown, right: unknown, type: ConditionField['type']): boolean {\n if (type === 'number') return toNumber(left) === toNumber(right)\n if (type === 'boolean') return toBool(left) === toBool(right)\n if (type === 'date') return toTime(left) === toTime(right)\n return toStr(left) === toStr(right)\n}\n\nfunction toStr(v: unknown): string {\n if (v == null) return ''\n if (typeof v === 'string') return v\n if (typeof v === 'number' || typeof v === 'boolean' || typeof v === 'bigint') return String(v)\n if (v instanceof Date) return v.toISOString()\n try {\n return JSON.stringify(v)\n } catch {\n return ''\n }\n}\n\n// ── 工厂 ─────────────────────────────────────────\n\nexport function createEmptyGroup(): ConditionGroup {\n return { type: 'group', children: [], connectors: [] }\n}\n\nexport function createEmptyLeaf(): ConditionLeaf {\n return { type: 'condition', field: '', operator: 'eq', value: { kind: 'constant', value: '' } }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operators.js","names":[],"sources":["../../../../src/components/condition-editor/core/operators.ts"],"sourcesContent":["export interface OperatorDef {\n label: string\n value: string\n needValue: boolean\n}\n\nconst STRING_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '包含', value: 'contains', needValue: true },\n { label: '不包含', value: 'not_contains', needValue: true },\n { label: '为空', value: 'empty', needValue: false },\n { label: '不为空', value: 'not_empty', needValue: false }\n]\n\nconst NUMBER_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '大于', value: 'gt', needValue: true },\n { label: '小于', value: 'lt', needValue: true },\n { label: '大于等于', value: 'gte', needValue: true },\n { label: '小于等于', value: 'lte', needValue: true }\n]\n\nconst BOOLEAN_OPERATORS: OperatorDef[] = [\n { label: '是', value: 'is_true', needValue: false },\n { label: '否', value: 'is_false', needValue: false }\n]\n\nconst DATE_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '早于', value: 'before', needValue: true },\n { label: '晚于', value: 'after', needValue: true }\n]\n\nconst ENUM_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '包含于', value: 'in', needValue: true }\n]\n\nconst OPERATOR_MAP: Record<string, OperatorDef[]> = {\n string: STRING_OPERATORS,\n number: NUMBER_OPERATORS,\n boolean: BOOLEAN_OPERATORS,\n date: DATE_OPERATORS,\n enum: ENUM_OPERATORS\n}\n\nexport function getOperatorsByFieldType(type: string): OperatorDef[] {\n return OPERATOR_MAP[type] ?? STRING_OPERATORS\n}\n\nexport function getOperatorDef(type: string, operator: string): OperatorDef | undefined {\n return getOperatorsByFieldType(type).find((op) => op.value === operator)\n}\n"],"mappings":";AAMA,MAAM,mBAAkC;CACtC;EAAE,OAAO;EAAM,OAAO;EAAM,WAAW;EAAM;CAC7C;EAAE,OAAO;EAAO,OAAO;EAAM,WAAW;EAAM;CAC9C;EAAE,OAAO;EAAM,OAAO;EAAY,WAAW;EAAM;CACnD;EAAE,OAAO;EAAO,OAAO;EAAgB,WAAW;EAAM;CACxD;EAAE,OAAO;EAAM,OAAO;EAAS,WAAW;EAAO;CACjD;EAAE,OAAO;EAAO,OAAO;EAAa,WAAW;EAAO;CACvD;AA6BD,MAAM,eAA8C;CAClD,QAAQ;CACR,QAAQ;EA5BR;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAQ,OAAO;GAAO,WAAW;GAAM;EAChD;GAAE,OAAO;GAAQ,OAAO;GAAO,WAAW;GAAM;EAuBxB;CACxB,SAAS,CApBT;EAAE,OAAO;EAAK,OAAO;EAAW,WAAW;EAAO,EAClD;EAAE,OAAO;EAAK,OAAO;EAAY,WAAW;EAAO,CAmBzB;CAC1B,MAAM;EAhBN;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAM,OAAO;GAAU,WAAW;GAAM;EACjD;GAAE,OAAO;GAAM,OAAO;GAAS,WAAW;GAAM;EAa5B;CACpB,MAAM;EAVN;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAQ1B;CACrB;AAED,SAAgB,wBAAwB,MAA6B;
|
|
1
|
+
{"version":3,"file":"operators.js","names":[],"sources":["../../../../src/components/condition-editor/core/operators.ts"],"sourcesContent":["export interface OperatorDef {\n label: string\n value: string\n needValue: boolean\n}\n\nconst STRING_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '包含', value: 'contains', needValue: true },\n { label: '不包含', value: 'not_contains', needValue: true },\n { label: '为空', value: 'empty', needValue: false },\n { label: '不为空', value: 'not_empty', needValue: false }\n]\n\nconst NUMBER_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '大于', value: 'gt', needValue: true },\n { label: '小于', value: 'lt', needValue: true },\n { label: '大于等于', value: 'gte', needValue: true },\n { label: '小于等于', value: 'lte', needValue: true }\n]\n\nconst BOOLEAN_OPERATORS: OperatorDef[] = [\n { label: '是', value: 'is_true', needValue: false },\n { label: '否', value: 'is_false', needValue: false }\n]\n\nconst DATE_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '早于', value: 'before', needValue: true },\n { label: '晚于', value: 'after', needValue: true }\n]\n\nconst ENUM_OPERATORS: OperatorDef[] = [\n { label: '等于', value: 'eq', needValue: true },\n { label: '不等于', value: 'ne', needValue: true },\n { label: '包含于', value: 'in', needValue: true }\n]\n\nconst OPERATOR_MAP: Record<string, OperatorDef[]> = {\n string: STRING_OPERATORS,\n number: NUMBER_OPERATORS,\n boolean: BOOLEAN_OPERATORS,\n date: DATE_OPERATORS,\n enum: ENUM_OPERATORS\n}\n\nexport function getOperatorsByFieldType(type: string): OperatorDef[] {\n return OPERATOR_MAP[type] ?? STRING_OPERATORS\n}\n\nexport function getOperatorDef(type: string, operator: string): OperatorDef | undefined {\n return getOperatorsByFieldType(type).find((op) => op.value === operator)\n}\n"],"mappings":";AAMA,MAAM,mBAAkC;CACtC;EAAE,OAAO;EAAM,OAAO;EAAM,WAAW;EAAM;CAC7C;EAAE,OAAO;EAAO,OAAO;EAAM,WAAW;EAAM;CAC9C;EAAE,OAAO;EAAM,OAAO;EAAY,WAAW;EAAM;CACnD;EAAE,OAAO;EAAO,OAAO;EAAgB,WAAW;EAAM;CACxD;EAAE,OAAO;EAAM,OAAO;EAAS,WAAW;EAAO;CACjD;EAAE,OAAO;EAAO,OAAO;EAAa,WAAW;EAAO;CACvD;AA6BD,MAAM,eAA8C;CAClD,QAAQ;CACR,QAAQ;EA5BR;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAQ,OAAO;GAAO,WAAW;GAAM;EAChD;GAAE,OAAO;GAAQ,OAAO;GAAO,WAAW;GAAM;EAuBxB;CACxB,SAAS,CApBT;EAAE,OAAO;EAAK,OAAO;EAAW,WAAW;EAAO,EAClD;EAAE,OAAO;EAAK,OAAO;EAAY,WAAW;EAAO,CAmBzB;CAC1B,MAAM;EAhBN;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAM,OAAO;GAAU,WAAW;GAAM;EACjD;GAAE,OAAO;GAAM,OAAO;GAAS,WAAW;GAAM;EAa5B;CACpB,MAAM;EAVN;GAAE,OAAO;GAAM,OAAO;GAAM,WAAW;GAAM;EAC7C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAC9C;GAAE,OAAO;GAAO,OAAO;GAAM,WAAW;GAAM;EAQ1B;CACrB;AAED,SAAgB,wBAAwB,MAA6B;CACnE,OAAO,aAAa,SAAS"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import { _default } from "./condition-editor.vue.js";
|
|
1
|
+
import { _default } from "./condition-editor.vue.js";
|
|
2
|
+
import { EvaluateOptions, createEmptyGroup, createEmptyLeaf, evaluate } from "./core/evaluator.js";
|
|
@@ -15,125 +15,213 @@
|
|
|
15
15
|
* --u-height-small: 24px;
|
|
16
16
|
*/
|
|
17
17
|
/** 暗色:data-theme 与系统偏好,与 UITheme.injectBuiltInThemes 选择器策略一致 */
|
|
18
|
-
.u-condition-
|
|
18
|
+
.u-condition-editor {
|
|
19
|
+
font-size: 13px;
|
|
20
|
+
color: var(--u-text-color-main);
|
|
21
|
+
}
|
|
22
|
+
.u-condition-editor__group {
|
|
23
|
+
position: relative;
|
|
24
|
+
background-color: var(--u-bg-color-top);
|
|
25
|
+
border: 1px solid var(--u-border-muted-color);
|
|
26
|
+
border-radius: var(--u-radius-default);
|
|
27
|
+
padding: 12px;
|
|
28
|
+
}
|
|
29
|
+
.u-condition-editor__group--nested {
|
|
30
|
+
background-color: var(--u-bg-color-middle);
|
|
31
|
+
border-left: 3px solid var(--u-color-primary-light-7);
|
|
32
|
+
}
|
|
33
|
+
.u-condition-editor__group + .u-condition-editor__group {
|
|
34
|
+
margin-top: 8px;
|
|
35
|
+
}
|
|
36
|
+
.u-condition-editor__group-list {
|
|
37
|
+
list-style: none;
|
|
38
|
+
margin: 0;
|
|
39
|
+
padding: 0;
|
|
19
40
|
display: flex;
|
|
20
|
-
|
|
41
|
+
flex-direction: column;
|
|
21
42
|
gap: 6px;
|
|
22
|
-
margin-bottom: 4px;
|
|
23
|
-
}
|
|
24
|
-
.u-condition-editor__group-body {
|
|
25
|
-
border-left: 2px solid var(--u-border-muted-color);
|
|
26
|
-
margin-left: 8px;
|
|
27
|
-
padding-left: 10px;
|
|
28
43
|
}
|
|
29
|
-
.u-condition-editor__group-
|
|
44
|
+
.u-condition-editor__group-item {
|
|
30
45
|
display: flex;
|
|
31
|
-
|
|
32
|
-
|
|
46
|
+
align-items: flex-start;
|
|
47
|
+
gap: 8px;
|
|
33
48
|
}
|
|
34
|
-
.u-condition-editor__group-
|
|
35
|
-
|
|
36
|
-
|
|
49
|
+
.u-condition-editor__group-item-body {
|
|
50
|
+
flex: 1;
|
|
51
|
+
min-width: 0;
|
|
37
52
|
}
|
|
38
|
-
.u-condition-editor__group-
|
|
39
|
-
|
|
53
|
+
.u-condition-editor__group-empty {
|
|
54
|
+
display: flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
justify-content: center;
|
|
57
|
+
padding: 8px;
|
|
58
|
+
color: var(--u-text-color-assist);
|
|
59
|
+
font-size: 12px;
|
|
40
60
|
}
|
|
41
|
-
.u-condition-editor__group-
|
|
42
|
-
|
|
61
|
+
.u-condition-editor__group-empty-tip {
|
|
62
|
+
opacity: 0.7;
|
|
43
63
|
}
|
|
44
|
-
.u-condition-
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
.u-condition-editor__connector {
|
|
65
|
+
flex-shrink: 0;
|
|
66
|
+
width: 56px;
|
|
67
|
+
height: 28px;
|
|
68
|
+
display: inline-flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
justify-content: center;
|
|
71
|
+
margin-top: 2px;
|
|
47
72
|
border-radius: var(--u-radius-small);
|
|
48
73
|
font-size: 11px;
|
|
49
74
|
font-weight: 600;
|
|
75
|
+
letter-spacing: 0.5px;
|
|
50
76
|
cursor: pointer;
|
|
51
77
|
user-select: none;
|
|
52
|
-
transition: background-color 0.
|
|
78
|
+
transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
|
|
53
79
|
}
|
|
54
|
-
.u-condition-
|
|
55
|
-
background-color: var(--u-color-primary-light-9);
|
|
80
|
+
.u-condition-editor__connector--and {
|
|
56
81
|
color: var(--u-color-primary);
|
|
82
|
+
background-color: var(--u-color-primary-light-9);
|
|
57
83
|
}
|
|
58
|
-
.u-condition-
|
|
84
|
+
.u-condition-editor__connector--and:hover {
|
|
59
85
|
background-color: var(--u-color-primary-light-8);
|
|
60
86
|
}
|
|
61
|
-
.u-condition-
|
|
87
|
+
.u-condition-editor__connector--or {
|
|
88
|
+
color: var(--u-color-warning-dark-2);
|
|
62
89
|
background-color: var(--u-color-warning-light-9);
|
|
63
|
-
color: var(--u-color-warning);
|
|
64
90
|
}
|
|
65
|
-
.u-condition-
|
|
91
|
+
.u-condition-editor__connector--or:hover {
|
|
66
92
|
background-color: var(--u-color-warning-light-8);
|
|
67
93
|
}
|
|
68
|
-
.u-condition-
|
|
94
|
+
.u-condition-editor__connector:focus-visible {
|
|
95
|
+
outline: 2px solid var(--u-color-primary);
|
|
96
|
+
outline-offset: 1px;
|
|
97
|
+
}
|
|
98
|
+
.u-condition-editor__connector-placeholder {
|
|
99
|
+
flex-shrink: 0;
|
|
100
|
+
width: 56px;
|
|
101
|
+
height: 28px;
|
|
102
|
+
display: inline-flex;
|
|
103
|
+
align-items: center;
|
|
104
|
+
justify-content: center;
|
|
105
|
+
margin-top: 2px;
|
|
106
|
+
border-radius: var(--u-radius-small);
|
|
107
|
+
font-size: 11px;
|
|
108
|
+
font-weight: 600;
|
|
109
|
+
letter-spacing: 0.5px;
|
|
110
|
+
color: var(--u-text-color-assist);
|
|
111
|
+
background-color: transparent;
|
|
112
|
+
user-select: none;
|
|
113
|
+
}
|
|
114
|
+
.u-condition-editor__group-actions {
|
|
69
115
|
display: flex;
|
|
116
|
+
flex-wrap: wrap;
|
|
70
117
|
gap: 4px;
|
|
118
|
+
margin-top: 8px;
|
|
119
|
+
padding-left: calc(56px + 8px);
|
|
120
|
+
}
|
|
121
|
+
.u-condition-editor__action-btn {
|
|
122
|
+
display: inline-flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
gap: 4px;
|
|
125
|
+
height: 26px;
|
|
126
|
+
padding: 0 8px;
|
|
127
|
+
border: none;
|
|
128
|
+
border-radius: var(--u-radius-small);
|
|
129
|
+
background-color: transparent;
|
|
130
|
+
color: var(--u-color-primary);
|
|
131
|
+
font-size: 12px;
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
transition: background-color 0.15s ease, color 0.15s ease;
|
|
134
|
+
}
|
|
135
|
+
.u-condition-editor__action-btn:hover {
|
|
136
|
+
background-color: var(--u-color-primary-light-9);
|
|
137
|
+
}
|
|
138
|
+
.u-condition-editor__action-btn:disabled {
|
|
139
|
+
cursor: not-allowed;
|
|
140
|
+
opacity: 0.5;
|
|
141
|
+
}
|
|
142
|
+
.u-condition-editor__action-btn--danger {
|
|
143
|
+
color: var(--u-color-danger);
|
|
144
|
+
}
|
|
145
|
+
.u-condition-editor__action-btn--danger:hover {
|
|
146
|
+
background-color: var(--u-color-danger-light-9);
|
|
147
|
+
}
|
|
148
|
+
.u-condition-editor__row {
|
|
149
|
+
display: flex;
|
|
150
|
+
gap: 6px;
|
|
71
151
|
align-items: center;
|
|
72
|
-
margin-bottom: 3px;
|
|
73
152
|
}
|
|
74
153
|
.u-condition-editor__field {
|
|
75
|
-
width:
|
|
154
|
+
width: 140px;
|
|
76
155
|
flex-shrink: 0;
|
|
77
156
|
}
|
|
78
157
|
.u-condition-editor__operator {
|
|
79
|
-
width:
|
|
158
|
+
width: 110px;
|
|
80
159
|
flex-shrink: 0;
|
|
81
160
|
}
|
|
82
161
|
.u-condition-editor__value {
|
|
83
162
|
flex: 1;
|
|
84
|
-
min-width:
|
|
163
|
+
min-width: 120px;
|
|
85
164
|
display: flex;
|
|
86
165
|
align-items: center;
|
|
87
166
|
}
|
|
88
167
|
.u-condition-editor__value-input {
|
|
89
168
|
width: 100%;
|
|
90
169
|
height: 28px;
|
|
91
|
-
padding: 0
|
|
170
|
+
padding: 0 10px;
|
|
92
171
|
border: 1px solid var(--u-border-muted-color);
|
|
93
172
|
border-radius: var(--u-radius-small);
|
|
94
|
-
font-size:
|
|
173
|
+
font-size: 13px;
|
|
95
174
|
color: var(--u-text-color-main);
|
|
96
175
|
background-color: var(--u-bg-color-top);
|
|
97
176
|
outline: none;
|
|
98
|
-
transition: border-color 0.
|
|
177
|
+
transition: border-color 0.15s ease;
|
|
99
178
|
}
|
|
100
179
|
.u-condition-editor__value-input::placeholder {
|
|
101
180
|
color: var(--u-text-color-placeholder);
|
|
102
181
|
}
|
|
182
|
+
.u-condition-editor__value-input:hover {
|
|
183
|
+
border-color: var(--u-color-primary-light-5);
|
|
184
|
+
}
|
|
103
185
|
.u-condition-editor__value-input:focus {
|
|
104
186
|
border-color: var(--u-color-primary);
|
|
105
187
|
}
|
|
106
|
-
.u-condition-editor__value-input:disabled {
|
|
188
|
+
.u-condition-editor__value-input:disabled, .u-condition-editor__value-input:read-only {
|
|
107
189
|
background-color: var(--u-color-disabled);
|
|
108
190
|
cursor: not-allowed;
|
|
109
191
|
}
|
|
110
192
|
.u-condition-editor__value-empty {
|
|
111
193
|
font-size: 12px;
|
|
112
194
|
color: var(--u-text-color-assist);
|
|
195
|
+
padding: 0 8px;
|
|
113
196
|
}
|
|
114
197
|
.u-condition-editor__value-chip {
|
|
115
198
|
display: inline-flex;
|
|
116
199
|
align-items: center;
|
|
117
200
|
gap: 4px;
|
|
118
|
-
|
|
119
|
-
|
|
201
|
+
max-width: 100%;
|
|
202
|
+
padding: 0 8px 0 10px;
|
|
203
|
+
height: 24px;
|
|
120
204
|
font-size: 12px;
|
|
121
205
|
color: var(--u-color-primary);
|
|
122
206
|
background-color: var(--u-color-primary-light-9);
|
|
207
|
+
border: 1px solid var(--u-color-primary-light-7);
|
|
123
208
|
border-radius: 999px;
|
|
124
209
|
cursor: pointer;
|
|
125
210
|
user-select: none;
|
|
126
|
-
transition: background-color 0.
|
|
211
|
+
transition: background-color 0.15s ease, border-color 0.15s ease;
|
|
127
212
|
}
|
|
128
213
|
.u-condition-editor__value-chip:hover {
|
|
129
214
|
background-color: var(--u-color-primary-light-8);
|
|
215
|
+
border-color: var(--u-color-primary-light-5);
|
|
130
216
|
}
|
|
131
|
-
.u-condition-editor__value-chip:
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
margin-left: 2px;
|
|
217
|
+
.u-condition-editor__value-chip:focus-visible {
|
|
218
|
+
outline: 2px solid var(--u-color-primary);
|
|
219
|
+
outline-offset: 1px;
|
|
135
220
|
}
|
|
136
221
|
.u-condition-editor__value-chip-label {
|
|
222
|
+
overflow: hidden;
|
|
223
|
+
text-overflow: ellipsis;
|
|
224
|
+
white-space: nowrap;
|
|
137
225
|
pointer-events: none;
|
|
138
226
|
}
|
|
139
227
|
.u-condition-editor__value-chip-close {
|
|
@@ -141,63 +229,52 @@
|
|
|
141
229
|
align-items: center;
|
|
142
230
|
justify-content: center;
|
|
143
231
|
width: 14px;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
overflow: hidden;
|
|
147
|
-
font-size: 14px;
|
|
232
|
+
height: 14px;
|
|
233
|
+
font-size: 10px;
|
|
148
234
|
line-height: 1;
|
|
149
|
-
color:
|
|
150
|
-
opacity: 0;
|
|
151
|
-
|
|
235
|
+
color: inherit;
|
|
236
|
+
opacity: 0.7;
|
|
237
|
+
border-radius: 50%;
|
|
238
|
+
transition: opacity 0.15s ease, background-color 0.15s ease;
|
|
152
239
|
}
|
|
153
240
|
.u-condition-editor__value-chip-close:hover {
|
|
154
|
-
|
|
241
|
+
opacity: 1;
|
|
242
|
+
background-color: var(--u-color-primary-light-7);
|
|
155
243
|
}
|
|
156
244
|
.u-condition-editor__row-delete {
|
|
157
245
|
flex-shrink: 0;
|
|
158
|
-
width:
|
|
159
|
-
|
|
160
|
-
|
|
246
|
+
width: 26px;
|
|
247
|
+
height: 26px;
|
|
248
|
+
display: inline-flex;
|
|
249
|
+
align-items: center;
|
|
250
|
+
justify-content: center;
|
|
251
|
+
border: none;
|
|
252
|
+
background-color: transparent;
|
|
161
253
|
color: var(--u-text-color-assist);
|
|
254
|
+
border-radius: var(--u-radius-small);
|
|
162
255
|
cursor: pointer;
|
|
163
|
-
|
|
256
|
+
font-size: 14px;
|
|
257
|
+
transition: color 0.15s ease, background-color 0.15s ease;
|
|
164
258
|
}
|
|
165
259
|
.u-condition-editor__row-delete:hover {
|
|
166
260
|
color: var(--u-color-danger);
|
|
261
|
+
background-color: var(--u-color-danger-light-9);
|
|
167
262
|
}
|
|
168
|
-
.u-condition-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
text-align: center;
|
|
172
|
-
font-size: 11px;
|
|
173
|
-
font-weight: 600;
|
|
174
|
-
}
|
|
175
|
-
.u-condition-editor__result--pass {
|
|
176
|
-
color: var(--u-color-success);
|
|
177
|
-
}
|
|
178
|
-
.u-condition-editor__result--fail {
|
|
179
|
-
color: var(--u-color-danger);
|
|
180
|
-
}
|
|
181
|
-
.u-condition-editor__result--none {
|
|
182
|
-
color: var(--u-text-color-assist);
|
|
183
|
-
}
|
|
184
|
-
.u-condition-editor__add-btn {
|
|
185
|
-
font-size: 11px;
|
|
186
|
-
color: var(--u-color-primary);
|
|
187
|
-
cursor: pointer;
|
|
188
|
-
transition: color 0.12s ease;
|
|
189
|
-
}
|
|
190
|
-
.u-condition-editor__add-btn:hover {
|
|
191
|
-
color: var(--u-color-primary-dark-2);
|
|
263
|
+
.u-condition-editor__row-delete:disabled {
|
|
264
|
+
cursor: not-allowed;
|
|
265
|
+
opacity: 0.4;
|
|
192
266
|
}
|
|
193
267
|
.u-condition-editor.is-disabled {
|
|
194
268
|
cursor: not-allowed;
|
|
195
269
|
}
|
|
196
|
-
.u-condition-editor.is-disabled .u-condition-
|
|
270
|
+
.u-condition-editor.is-disabled .u-condition-editor__connector {
|
|
197
271
|
cursor: not-allowed;
|
|
198
272
|
opacity: 0.6;
|
|
199
273
|
}
|
|
200
|
-
.u-condition-editor.is-disabled .u-condition-
|
|
274
|
+
.u-condition-editor.is-disabled .u-condition-editor__action-btn {
|
|
201
275
|
cursor: not-allowed;
|
|
202
276
|
opacity: 0.6;
|
|
203
277
|
}
|
|
278
|
+
.u-condition-editor.is-readonly .u-condition-editor__connector {
|
|
279
|
+
cursor: default;
|
|
280
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","names":["MContextMenu"],"sources":["../../../src/components/context-menu/api.ts"],"sourcesContent":["import { createVNode, render, type VNode } from 'vue'\n\nimport type { ContextMenuProps } from '../../types'\nimport MContextMenu from './context-menu.vue'\n\nlet node: VNode\n\nexport const contextmenu = {\n pop(options: ContextMenuProps): void {\n if (node) {\n render(null, document.body)\n }\n\n node = createVNode(MContextMenu, {\n ...options,\n onDestroy() {\n render(null, document.body)\n }\n })\n\n render(node, document.body)\n }\n}\n"],"mappings":";;;AAKA,IAAI;AAEJ,MAAa,cAAc,EACzB,IAAI,SAAiC;
|
|
1
|
+
{"version":3,"file":"api.js","names":["MContextMenu"],"sources":["../../../src/components/context-menu/api.ts"],"sourcesContent":["import { createVNode, render, type VNode } from 'vue'\n\nimport type { ContextMenuProps } from '../../types'\nimport MContextMenu from './context-menu.vue'\n\nlet node: VNode\n\nexport const contextmenu = {\n pop(options: ContextMenuProps): void {\n if (node) {\n render(null, document.body)\n }\n\n node = createVNode(MContextMenu, {\n ...options,\n onDestroy() {\n render(null, document.body)\n }\n })\n\n render(node, document.body)\n }\n}\n"],"mappings":";;;AAKA,IAAI;AAEJ,MAAa,cAAc,EACzB,IAAI,SAAiC;CACnC,IAAI,MACF,OAAO,MAAM,SAAS,KAAK;CAG7B,OAAO,YAAYA,WAAc;EAC/B,GAAG;EACH,YAAY;GACV,OAAO,MAAM,SAAS,KAAK;;EAE9B,CAAC;CAEF,OAAO,MAAM,SAAS,KAAK;GAE9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-menu-item.js","names":[],"sources":["../../../src/components/context-menu/context-menu-item.vue"],"sourcesContent":["<template>\n <li\n :class=\"[\n cls.e('item'),\n bem.is('disabled', disabled),\n bem.is('loading', loading),\n cls.em('item', 'menu')\n ]\"\n v-ripple=\"!disabled && !loading\"\n @click=\"handleClickMenu\"\n >\n <u-icon v-if=\"loading\" :class=\"bem.is('loading')\">\n <Loading />\n </u-icon>\n <template v-else>\n <u-icon v-if=\"menu.icon\">\n <component :is=\"menu.icon\" />\n </u-icon>\n <i v-else :class=\"cls.e('icon-place')\"></i>\n </template>\n\n <span :class=\"cls.e('label')\">{{ menu.label }}</span>\n </li>\n</template>\n\n<script lang=\"ts\" setup>\nimport { vRipple } from '@veltra/directives'\nimport { Loading } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, inject, shallowRef } from 'vue'\n\nimport type { ContextMenuItem } from '../../types'\nimport { UIcon } from '../icon'\nimport { ContextMenuDIKey } from './di'\n\ndefineOptions({\n name: 'ContextMenuItem'\n})\n\nconst { menu } = defineProps<{\n menu: ContextMenuItem\n}>()\n\nconst emit = defineEmits<{\n (e: 'click-start'): void\n (e: 'click-end'): void\n}>()\n\nconst { cls } = inject(ContextMenuDIKey)!\n\nconst loading = shallowRef(false)\n\nconst disabled = computed(() => {\n return (typeof menu.disabled === 'function' ? menu.disabled() : menu.disabled) ?? false\n})\n\nfunction handleClickMenu() {\n if (disabled.value || loading.value) return\n emit('click-start')\n loading.value = true\n const result = menu.callback?.()\n\n if (result instanceof Promise) {\n return result\n .then(() => {})\n .finally(() => {\n emit('click-end')\n loading.value = false\n })\n }\n loading.value = false\n emit('click-end')\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;EA2CA,MAAM,OAAO;EAKb,MAAM,EAAE,QAAQ,OAAO,
|
|
1
|
+
{"version":3,"file":"context-menu-item.js","names":[],"sources":["../../../src/components/context-menu/context-menu-item.vue"],"sourcesContent":["<template>\n <li\n :class=\"[\n cls.e('item'),\n bem.is('disabled', disabled),\n bem.is('loading', loading),\n cls.em('item', 'menu')\n ]\"\n v-ripple=\"!disabled && !loading\"\n @click=\"handleClickMenu\"\n >\n <u-icon v-if=\"loading\" :class=\"bem.is('loading')\">\n <Loading />\n </u-icon>\n <template v-else>\n <u-icon v-if=\"menu.icon\">\n <component :is=\"menu.icon\" />\n </u-icon>\n <i v-else :class=\"cls.e('icon-place')\"></i>\n </template>\n\n <span :class=\"cls.e('label')\">{{ menu.label }}</span>\n </li>\n</template>\n\n<script lang=\"ts\" setup>\nimport { vRipple } from '@veltra/directives'\nimport { Loading } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, inject, shallowRef } from 'vue'\n\nimport type { ContextMenuItem } from '../../types'\nimport { UIcon } from '../icon'\nimport { ContextMenuDIKey } from './di'\n\ndefineOptions({\n name: 'ContextMenuItem'\n})\n\nconst { menu } = defineProps<{\n menu: ContextMenuItem\n}>()\n\nconst emit = defineEmits<{\n (e: 'click-start'): void\n (e: 'click-end'): void\n}>()\n\nconst { cls } = inject(ContextMenuDIKey)!\n\nconst loading = shallowRef(false)\n\nconst disabled = computed(() => {\n return (typeof menu.disabled === 'function' ? menu.disabled() : menu.disabled) ?? false\n})\n\nfunction handleClickMenu() {\n if (disabled.value || loading.value) return\n emit('click-start')\n loading.value = true\n const result = menu.callback?.()\n\n if (result instanceof Promise) {\n return result\n .then(() => {})\n .finally(() => {\n emit('click-end')\n loading.value = false\n })\n }\n loading.value = false\n emit('click-end')\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;EA2CA,MAAM,OAAO;EAKb,MAAM,EAAE,QAAQ,OAAO,iBAAgB;EAEvC,MAAM,UAAU,WAAW,MAAK;EAEhC,MAAM,WAAW,eAAe;GAC9B,QAAQ,OAAO,QAAA,KAAK,aAAa,aAAa,QAAA,KAAK,UAAS,GAAI,QAAA,KAAK,aAAa;IACnF;EAED,SAAS,kBAAkB;GACzB,IAAI,SAAS,SAAS,QAAQ,OAAO;GACrC,KAAK,cAAa;GAClB,QAAQ,QAAQ;GAChB,MAAM,SAAS,QAAA,KAAK,YAAW;GAE/B,IAAI,kBAAkB,SACpB,OAAO,OACJ,WAAW,GAAE,CACb,cAAc;IACb,KAAK,YAAW;IAChB,QAAQ,QAAQ;KACjB;GAEL,QAAQ,QAAQ;GAChB,KAAK,YAAW;;;uCAtEhB,mBAqBK,MAAA;IApBF,OAAK,eAAA;KAAU,MAAA,IAAA,CAAI,EAAC,OAAA;KAAgB,MAAA,IAAA,CAAI,GAAE,YAAa,SAAA,MAAQ;KAAS,MAAA,IAAA,CAAI,GAAE,WAAY,QAAA,MAAO;KAAS,MAAA,IAAA,CAAI,GAAE,QAAA,OAAA;;IAOhH,SAAO;OAEM,QAAA,SAAA,WAAA,EAAd,YAES,MAAA,YAAA,EAAA;;IAFe,OAAK,eAAE,MAAA,IAAA,CAAI,GAAE,UAAA,CAAA;;2BACxB,CAAX,YAAW,MAAA,QAAA,CAAA,CAAA,CAAA;;qCAEb,mBAKW,UAAA,EAAA,KAAA,GAAA,EAAA,CAJK,QAAA,KAAK,QAAA,WAAA,EAAnB,YAES,MAAA,YAAA,EAAA,EAAA,KAAA,GAAA,EAAA;2BADsB,EAAA,WAAA,EAA7B,YAA6B,wBAAb,QAAA,KAAK,KAAI,CAAA,EAAA,CAAA;;uBAE3B,mBAA2C,KAAA;;IAAhC,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,aAAA,CAAA;wBAGzB,mBAAqD,QAAA,EAA9C,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,QAAA,CAAA,EAAA,EAAA,gBAAc,QAAA,KAAK,MAAK,EAAA,EAAA,CAAA,EAAA,EAAA,GAAA,CAAA,CAAA,MAAA,QAAA,EAAA,CAbhC,SAAA,SAAQ,CAAK,QAAA,MAAO,CAAA,CAAA"}
|