qidian-vue-ui 2.0.33 → 2.0.35

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.
Files changed (28) hide show
  1. package/dist/components/config-provider/index.d.ts +9 -0
  2. package/dist/components/config-provider/types.d.ts +3 -0
  3. package/dist/components/config-provider/useConfig.d.ts +12 -0
  4. package/dist/components/crud/table/index.vue2.mjs +3 -0
  5. package/dist/components/crud/table/props.d.ts +1 -0
  6. package/dist/components/crud/tabs-table/index.vue.d.ts +1 -0
  7. package/dist/components/crud/tabs-table/index.vue2.mjs +1 -0
  8. package/dist/components/crud/tabs-table/props.d.ts +1 -0
  9. package/dist/components/service/table/filter-item.d.ts +50 -0
  10. package/dist/components/service/table/filter-item.mjs +170 -0
  11. package/dist/components/service/table/index.css +96 -28
  12. package/dist/components/service/table/index.d.ts +1 -1
  13. package/dist/components/service/table/index.vue.mjs +1 -1
  14. package/dist/components/service/table/index.vue2.mjs +258 -19
  15. package/dist/components/service/table/props.d.ts +1 -0
  16. package/dist/components/service/table/props.mjs +1 -0
  17. package/dist/components/service/table/types.d.ts +15 -1
  18. package/dist/components/service-dialog-table-select/index.vue2.mjs +3 -3
  19. package/dist/components/service-dialog-tabs-table-select/index.vue2.mjs +3 -3
  20. package/dist/components/service-popup-table-select/index.vue2.mjs +3 -3
  21. package/dist/components/upload/index.vue2.mjs +2 -2
  22. package/dist/locales/en-US.d.ts +5 -0
  23. package/dist/locales/en-US.mjs +5 -0
  24. package/dist/locales/zh-CN.d.ts +5 -0
  25. package/dist/locales/zh-CN.mjs +5 -0
  26. package/dist/locales/zh-TW.d.ts +5 -0
  27. package/dist/locales/zh-TW.mjs +5 -0
  28. package/package.json +1 -1
@@ -105,6 +105,9 @@ export declare const QdConfigProvider: import("vue").DefineComponent<{
105
105
  table?: Omit<NonNullable<NonNullable<import("tdesign-vue-next").TdConfigProviderProps["globalConfig"]>["table"]>, "size"> & {
106
106
  size?: import("..").QdServiceTableProps["size"];
107
107
  bordered?: boolean;
108
+ filterItemInputPlaceholder?: string;
109
+ filterItemSearchPlaceholder?: string;
110
+ filterItemAllText?: string;
108
111
  };
109
112
  wrapper?: {
110
113
  attach?: import("..").QdDialogProps["attach"];
@@ -249,6 +252,9 @@ export declare const QdConfigProvider: import("vue").DefineComponent<{
249
252
  table?: Omit<NonNullable<NonNullable<import("tdesign-vue-next").TdConfigProviderProps["globalConfig"]>["table"]>, "size"> & {
250
253
  size?: import("..").QdServiceTableProps["size"];
251
254
  bordered?: boolean;
255
+ filterItemInputPlaceholder?: string;
256
+ filterItemSearchPlaceholder?: string;
257
+ filterItemAllText?: string;
252
258
  };
253
259
  wrapper?: {
254
260
  attach?: import("..").QdDialogProps["attach"];
@@ -378,6 +384,9 @@ export declare const QdConfigProvider: import("vue").DefineComponent<{
378
384
  table?: Omit<NonNullable<NonNullable<import("tdesign-vue-next").TdConfigProviderProps["globalConfig"]>["table"]>, "size"> & {
379
385
  size?: import("..").QdServiceTableProps["size"];
380
386
  bordered?: boolean;
387
+ filterItemInputPlaceholder?: string;
388
+ filterItemSearchPlaceholder?: string;
389
+ filterItemAllText?: string;
381
390
  };
382
391
  wrapper?: {
383
392
  attach?: import("..").QdDialogProps["attach"];
@@ -122,6 +122,9 @@ export interface QdConfigProviderProps {
122
122
  table?: Omit<NonNullable<NonNullable<TdConfigProviderProps['globalConfig']>['table']>, 'size'> & {
123
123
  size?: QdServiceTableProps['size'];
124
124
  bordered?: boolean;
125
+ filterItemInputPlaceholder?: string;
126
+ filterItemSearchPlaceholder?: string;
127
+ filterItemAllText?: string;
125
128
  };
126
129
  wrapper?: {
127
130
  attach?: QdDialogProps['attach'];
@@ -93,6 +93,9 @@ export declare function useConfig<T extends keyof NonNullable<QdConfigProviderPr
93
93
  table?: Omit<NonNullable<NonNullable<import("tdesign-vue-next").TdConfigProviderProps["globalConfig"]>["table"]>, "size"> & {
94
94
  size?: import("..").QdServiceTableProps["size"];
95
95
  bordered?: boolean;
96
+ filterItemInputPlaceholder?: string;
97
+ filterItemSearchPlaceholder?: string;
98
+ filterItemAllText?: string;
96
99
  };
97
100
  wrapper?: {
98
101
  attach?: import("..").QdDialogProps["attach"];
@@ -220,6 +223,9 @@ export declare function useConfig<T extends keyof NonNullable<QdConfigProviderPr
220
223
  table?: Omit<NonNullable<NonNullable<import("tdesign-vue-next").TdConfigProviderProps["globalConfig"]>["table"]>, "size"> & {
221
224
  size?: import("..").QdServiceTableProps["size"];
222
225
  bordered?: boolean;
226
+ filterItemInputPlaceholder?: string;
227
+ filterItemSearchPlaceholder?: string;
228
+ filterItemAllText?: string;
223
229
  };
224
230
  wrapper?: {
225
231
  attach?: import("..").QdDialogProps["attach"];
@@ -347,6 +353,9 @@ export declare function useConfig<T extends keyof NonNullable<QdConfigProviderPr
347
353
  table?: Omit<NonNullable<NonNullable<import("tdesign-vue-next").TdConfigProviderProps["globalConfig"]>["table"]>, "size"> & {
348
354
  size?: import("..").QdServiceTableProps["size"];
349
355
  bordered?: boolean;
356
+ filterItemInputPlaceholder?: string;
357
+ filterItemSearchPlaceholder?: string;
358
+ filterItemAllText?: string;
350
359
  };
351
360
  wrapper?: {
352
361
  attach?: import("..").QdDialogProps["attach"];
@@ -475,6 +484,9 @@ export declare function useConfig<T extends keyof NonNullable<QdConfigProviderPr
475
484
  table?: Omit<NonNullable<NonNullable<import("tdesign-vue-next").TdConfigProviderProps["globalConfig"]>["table"]>, "size"> & {
476
485
  size?: import("..").QdServiceTableProps["size"];
477
486
  bordered?: boolean;
487
+ filterItemInputPlaceholder?: string;
488
+ filterItemSearchPlaceholder?: string;
489
+ filterItemAllText?: string;
478
490
  };
479
491
  wrapper?: {
480
492
  attach?: import("..").QdDialogProps["attach"];
@@ -85,6 +85,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
85
85
  emptyImage: {
86
86
  type: [Boolean, String]
87
87
  },
88
+ readonly: {
89
+ type: Boolean
90
+ },
88
91
  lazyForm: {
89
92
  type: Boolean
90
93
  },
@@ -22,6 +22,7 @@ export declare const qdCrudTableProps: {
22
22
  readonly searchData: () => {};
23
23
  readonly emptyText: undefined;
24
24
  readonly emptyImage: true;
25
+ readonly readonly: undefined;
25
26
  readonly lazyForm: true;
26
27
  readonly editCellValidationBlock: "error";
27
28
  readonly rowKey: "id";
@@ -66,6 +66,7 @@ declare const _default: <D extends TableRowData = TableRowData, R = unknown, P =
66
66
  }) => import("tdesign-vue-next").TNodeReturnValue) | undefined;
67
67
  emptyText?: string | undefined;
68
68
  attach?: import("tdesign-vue-next").AttachNode | undefined;
69
+ readonly?: boolean | undefined;
69
70
  onValidate?: ((context: import("tdesign-vue-next").PrimaryTableValidateContext) => void) | undefined;
70
71
  rowKey?: string | undefined;
71
72
  scroll?: import("../..").QdServiceTableScroll | undefined;
@@ -47,6 +47,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
47
47
  headerBg: { type: Boolean },
48
48
  emptyText: {},
49
49
  emptyImage: { type: [Boolean, String] },
50
+ readonly: { type: Boolean },
50
51
  lazyForm: { type: Boolean },
51
52
  editCellValidationBlock: {},
52
53
  scroll: {},
@@ -16,6 +16,7 @@ export declare const qdCrudTabsTableProps: {
16
16
  readonly searchData: () => {};
17
17
  readonly emptyText: undefined;
18
18
  readonly emptyImage: true;
19
+ readonly readonly: undefined;
19
20
  readonly lazyForm: true;
20
21
  readonly editCellValidationBlock: "error";
21
22
  readonly rowKey: "id";
@@ -0,0 +1,50 @@
1
+ import type { PropType, VNodeChild } from 'vue';
2
+ import type { QdServiceTableFilterOption } from './types';
3
+ type FilterValue = string | number | Array<string | number> | null;
4
+ type FilterOption = QdServiceTableFilterOption & {
5
+ render?: () => VNodeChild;
6
+ };
7
+ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
8
+ options: {
9
+ type: PropType<FilterOption[]>;
10
+ default: () => never[];
11
+ };
12
+ type: {
13
+ type: PropType<"single" | "multiple">;
14
+ default: string;
15
+ };
16
+ value: {
17
+ type: PropType<FilterValue>;
18
+ };
19
+ showConfirmAndReset: {
20
+ type: BooleanConstructor;
21
+ default: boolean;
22
+ };
23
+ onChange: {
24
+ type: PropType<(value: FilterValue) => void>;
25
+ };
26
+ }>, () => JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
27
+ options: {
28
+ type: PropType<FilterOption[]>;
29
+ default: () => never[];
30
+ };
31
+ type: {
32
+ type: PropType<"single" | "multiple">;
33
+ default: string;
34
+ };
35
+ value: {
36
+ type: PropType<FilterValue>;
37
+ };
38
+ showConfirmAndReset: {
39
+ type: BooleanConstructor;
40
+ default: boolean;
41
+ };
42
+ onChange: {
43
+ type: PropType<(value: FilterValue) => void>;
44
+ };
45
+ }>> & Readonly<{}>, {
46
+ type: "multiple" | "single";
47
+ options: FilterOption[];
48
+ showConfirmAndReset: boolean;
49
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
50
+ export default _default;
@@ -0,0 +1,170 @@
1
+ import { defineComponent, ref, computed, createVNode, onMounted, onBeforeUnmount } from "vue";
2
+ import { SearchIcon } from "tdesign-icons-vue-next";
3
+ import { Input, Checkbox, Radio } from "tdesign-vue-next";
4
+ import { useConfig } from "../../config-provider/useConfig.mjs";
5
+ const FilterOptionContent = /* @__PURE__ */ defineComponent({
6
+ props: {
7
+ render: {
8
+ type: Function,
9
+ required: true
10
+ },
11
+ onTextChange: {
12
+ type: Function,
13
+ required: true
14
+ }
15
+ },
16
+ setup(props) {
17
+ const content = ref();
18
+ let observer;
19
+ function syncText() {
20
+ props.onTextChange(content.value?.textContent?.trim() ?? "");
21
+ }
22
+ onMounted(() => {
23
+ syncText();
24
+ observer = new MutationObserver(syncText);
25
+ if (content.value) observer.observe(content.value, {
26
+ characterData: true,
27
+ childList: true,
28
+ subtree: true
29
+ });
30
+ });
31
+ onBeforeUnmount(() => observer?.disconnect());
32
+ return () => createVNode("span", {
33
+ "ref": content,
34
+ "class": "qd-service-table-filter-item__cell",
35
+ "inert": true
36
+ }, [props.render()]);
37
+ }
38
+ });
39
+ const QdServiceTableFilterItem = /* @__PURE__ */ defineComponent({
40
+ name: "QdServiceTableFilterItem",
41
+ props: {
42
+ options: {
43
+ type: Array,
44
+ default: () => []
45
+ },
46
+ type: {
47
+ type: String,
48
+ default: "multiple"
49
+ },
50
+ value: {
51
+ type: [String, Number, Array]
52
+ },
53
+ showConfirmAndReset: {
54
+ type: Boolean,
55
+ default: true
56
+ },
57
+ onChange: {
58
+ type: Function
59
+ }
60
+ },
61
+ setup(props) {
62
+ const {
63
+ t
64
+ } = useConfig("table");
65
+ const keyword = ref("");
66
+ const renderedTexts = ref(/* @__PURE__ */ new Map());
67
+ const selectedValues = computed(() => {
68
+ if (props.type === "multiple") return Array.isArray(props.value) ? props.value : [];
69
+ return props.value === "" || props.value === void 0 ? [] : [props.value];
70
+ });
71
+ const allSelected = computed(() => props.type === "multiple" && props.value !== null && (!selectedValues.value.length || props.options.every((option) => selectedValues.value.includes(option.value))));
72
+ const filteredOptions = computed(() => {
73
+ const keywords = keyword.value.trim().toLowerCase().split(/\s+/).filter(Boolean);
74
+ if (!keywords.length) return props.options;
75
+ return props.options.filter((option) => {
76
+ const label = (renderedTexts.value.get(option.value) || option.label).toLowerCase();
77
+ return keywords.some((item) => label.includes(item));
78
+ });
79
+ });
80
+ const totalCount = computed(() => props.options.reduce((total, option) => total + (option.count ?? 0), 0));
81
+ const selectedCount = computed(() => {
82
+ if (props.value === null) return 0;
83
+ if (allSelected.value || !selectedValues.value.length) return totalCount.value;
84
+ return props.options.reduce((total, option) => selectedValues.value.includes(option.value) ? total + (option.count ?? 0) : total, 0);
85
+ });
86
+ function selectAll() {
87
+ props.onChange?.(props.type === "multiple" ? [] : "");
88
+ }
89
+ function selectOption(value, checked) {
90
+ if (props.type === "single") {
91
+ props.onChange?.(value);
92
+ return;
93
+ }
94
+ const current = allSelected.value ? props.options.map((option) => option.value) : selectedValues.value;
95
+ const next = checked ? [.../* @__PURE__ */ new Set([...current, value])] : current.filter((item) => item !== value);
96
+ if (!next.length) {
97
+ if (!props.showConfirmAndReset) return;
98
+ props.onChange?.(null);
99
+ return;
100
+ }
101
+ const valueAllSelected = props.options.every((option) => next.includes(option.value));
102
+ props.onChange?.(valueAllSelected ? [] : next);
103
+ }
104
+ function renderOption(option) {
105
+ if (!option.render) return option.label;
106
+ return createVNode(FilterOptionContent, {
107
+ "render": option.render,
108
+ "onTextChange": (text) => {
109
+ option.label = text || option.label;
110
+ renderedTexts.value.set(option.value, text);
111
+ }
112
+ }, null);
113
+ }
114
+ function isOptionDisabled(option) {
115
+ if (option.disabled) return true;
116
+ if (props.showConfirmAndReset || allSelected.value) return false;
117
+ return selectedValues.value.length === 1 && selectedValues.value.includes(option.value);
118
+ }
119
+ return () => createVNode("div", {
120
+ "class": "qd-service-table-filter-item"
121
+ }, [createVNode("div", {
122
+ "class": "qd-service-table-filter-item__search"
123
+ }, [createVNode(Input, {
124
+ "modelValue": keyword.value,
125
+ "onUpdate:modelValue": ($event) => keyword.value = $event,
126
+ "clearable": true,
127
+ "placeholder": t("filterItemSearchPlaceholder"),
128
+ "prefixIcon": () => createVNode(SearchIcon, null, null)
129
+ }, null)]), createVNode("div", {
130
+ "class": "qd-service-table-filter-item__all"
131
+ }, [props.type === "multiple" ? createVNode(Checkbox, {
132
+ "checked": allSelected.value,
133
+ "onChange": selectAll
134
+ }, {
135
+ default: () => [t("filterItemAllText"), createVNode("span", {
136
+ "class": "qd-service-table-filter-item__count"
137
+ }, [`(${selectedCount.value}/${totalCount.value})`])]
138
+ }) : createVNode(Radio, {
139
+ "checked": !selectedValues.value.length,
140
+ "onChange": selectAll
141
+ }, {
142
+ default: () => [t("filterItemAllText"), createVNode("span", {
143
+ "class": "qd-service-table-filter-item__count"
144
+ }, [`(${selectedCount.value}/${totalCount.value})`])]
145
+ })]), createVNode("div", {
146
+ "class": "qd-service-table-filter-item__options"
147
+ }, [filteredOptions.value.map((option) => props.type === "multiple" ? createVNode(Checkbox, {
148
+ "key": option.value,
149
+ "checked": allSelected.value || selectedValues.value.includes(option.value),
150
+ "disabled": isOptionDisabled(option),
151
+ "onChange": (checked) => selectOption(option.value, checked)
152
+ }, {
153
+ default: () => [renderOption(option), createVNode("span", {
154
+ "class": "qd-service-table-filter-item__count"
155
+ }, [`(${option.count ?? 0})`])]
156
+ }) : createVNode(Radio, {
157
+ "key": option.value,
158
+ "checked": selectedValues.value.includes(option.value),
159
+ "disabled": option.disabled,
160
+ "onChange": () => selectOption(option.value, true)
161
+ }, {
162
+ default: () => [renderOption(option), createVNode("span", {
163
+ "class": "qd-service-table-filter-item__count"
164
+ }, [`(${option.count ?? 0})`])]
165
+ }))])]);
166
+ }
167
+ });
168
+ export {
169
+ QdServiceTableFilterItem as default
170
+ };
@@ -1,88 +1,156 @@
1
- .qd-service-table[data-v-92206ee3] {
1
+ .qd-service-table[data-v-bff70dd6] {
2
2
  height: 100%;
3
3
  display: flex;
4
4
  flex-direction: column;
5
5
  }
6
- .qd-service-table[data-v-92206ee3] > .t-table__content {
6
+ .qd-service-table[data-v-bff70dd6] > .t-table__content {
7
7
  flex: 1;
8
8
  }
9
- .qd-service-table--mini[data-v-92206ee3] {
9
+ .qd-service-table--mini[data-v-bff70dd6] {
10
10
  font: var(--td-font-body-small);
11
11
  }
12
- .qd-service-table--mini[data-v-92206ee3] th,
13
- .qd-service-table--mini[data-v-92206ee3] tr:not(.t-table__expanded-row) > td {
12
+ .qd-service-table--mini[data-v-bff70dd6] th,
13
+ .qd-service-table--mini[data-v-bff70dd6] tr:not(.t-table__expanded-row) > td {
14
14
  padding: var(--td-comp-paddingTB-xxs) var(--td-comp-paddingLR-xxs);
15
15
  line-height: var(--td-line-height-body-small);
16
16
  }
17
- .qd-service-table--mini[data-v-92206ee3] .t-table__row-full-element {
17
+ .qd-service-table--mini[data-v-bff70dd6] .t-table__row-full-element {
18
18
  padding: var(--td-comp-paddingTB-xs) var(--td-comp-paddingLR-s);
19
19
  }
20
- .qd-service-table--hide-empty-image[data-v-92206ee3] .t-table__empty {
20
+ .qd-service-table--hide-empty-image[data-v-bff70dd6] .t-table__empty {
21
21
  min-height: auto;
22
22
  }
23
- .qd-service-table--hide-empty-image[data-v-92206ee3] .t-table__empty .t-empty {
23
+ .qd-service-table--hide-empty-image[data-v-bff70dd6] .t-table__empty .t-empty {
24
24
  padding: 0 !important;
25
25
  }
26
- .qd-service-table--hide-empty-image[data-v-92206ee3] .t-table__empty .t-empty__image {
26
+ .qd-service-table--hide-empty-image[data-v-bff70dd6] .t-table__empty .t-empty__image {
27
27
  display: none;
28
28
  }
29
- .qd-service-table--hide-empty-image[data-v-92206ee3] .t-table__empty .t-empty__title {
29
+ .qd-service-table--hide-empty-image[data-v-bff70dd6] .t-table__empty .t-empty__title {
30
30
  margin-top: 0;
31
31
  }
32
- .qd-service-table[data-v-92206ee3] .t-table__tree-col:not(:has(.t-table__tree-op-icon)) {
32
+ .qd-service-table[data-v-bff70dd6] .t-table__tree-col:not(:has(.t-table__tree-op-icon)) {
33
33
  margin-left: calc(var(--td-font-size-body-large) + var(--td-comp-margin-s));
34
34
  }
35
- .qd-service-table[data-v-92206ee3] .t-table__tree-leaf-node .t-table__tree-op-icon:empty {
35
+ .qd-service-table[data-v-bff70dd6] .t-table__tree-leaf-node .t-table__tree-op-icon:empty {
36
36
  width: calc(var(--td-font-size-body-large) + var(--td-comp-margin-s));
37
37
  }
38
- .qd-service-table[data-v-92206ee3] .t-affix > .t-table__affixed-header-elm-wrap,
39
- .qd-service-table[data-v-92206ee3] .t-affix > .t-table__scrollbar--obvious {
40
- transform: var(--v48c62e9a);
38
+ .qd-service-table[data-v-bff70dd6] .t-affix > .t-table__affixed-header-elm-wrap,
39
+ .qd-service-table[data-v-bff70dd6] .t-affix > .t-table__scrollbar--obvious {
40
+ transform: var(--d0bff1fe);
41
41
  }
42
- .qd-service-table--horizontal-bar-static[data-v-92206ee3] .t-table__scrollbar--obvious {
42
+ .qd-service-table--horizontal-bar-static[data-v-bff70dd6] .t-table__scrollbar--obvious {
43
43
  visibility: hidden;
44
44
  pointer-events: none;
45
45
  }
46
- .qd-service-table[data-v-92206ee3] .t-table__expanded-row .qd-service-table--horizontal-bar-static > div:has(> div > .t-table__scrollbar--obvious) {
46
+ .qd-service-table[data-v-bff70dd6] .t-table__expanded-row .qd-service-table--horizontal-bar-static > div:has(> div > .t-table__scrollbar--obvious) {
47
47
  display: none;
48
48
  }
49
- .qd-service-table[data-v-92206ee3] .t-table__expanded-row > td {
49
+ .qd-service-table[data-v-bff70dd6] .t-table__expanded-row > td {
50
50
  height: 0;
51
51
  }
52
- .qd-service-table[data-v-92206ee3] .t-table__affixed-header-elm-wrap {
52
+ .qd-service-table[data-v-bff70dd6] .t-table__affixed-header-elm-wrap {
53
53
  height: auto !important;
54
54
  }
55
- .qd-service-table[data-v-92206ee3] .t-table__affixed-header-elm {
55
+ .qd-service-table[data-v-bff70dd6] .t-table__affixed-header-elm {
56
56
  position: relative;
57
57
  scrollbar-width: none;
58
58
  }
59
- .qd-service-table[data-v-92206ee3] .t-table__affixed-header-elm::-webkit-scrollbar {
59
+ .qd-service-table[data-v-bff70dd6] .t-table__affixed-header-elm::-webkit-scrollbar {
60
60
  display: none;
61
61
  width: 0;
62
62
  height: 0;
63
63
  }
64
- .qd-service-table[data-v-92206ee3] .t-table__virtual-scroll-cursor + table {
64
+ .qd-service-table[data-v-bff70dd6] .t-table__virtual-scroll-cursor + table {
65
65
  border-collapse: separate;
66
66
  }
67
- .qd-service-table[data-v-92206ee3] .t-table__expanded-row-inner {
67
+ .qd-service-table[data-v-bff70dd6] .t-table__expanded-row-inner {
68
68
  display: block;
69
69
  position: sticky;
70
70
  left: 0;
71
- width: var(--v442c3de2) !important;
71
+ width: var(--v2ce85a94) !important;
72
72
  }
73
- .qd-service-table[data-v-92206ee3] .t-table__cell-wrap > .t-form__controls > .t-form__controls-content > *:not(.t-switch):not(.t-tag):not(.t-icon):not(.qd-file-icon) {
73
+ .qd-service-table[data-v-bff70dd6] .t-table__cell-wrap > .t-form__controls > .t-form__controls-content > *:not(.t-switch):not(.t-tag):not(.t-icon):not(.qd-file-icon) {
74
74
  width: 100%;
75
75
  }
76
- .qd-service-table[data-v-92206ee3] .qd-service-table__non-editable-col {
76
+ .qd-service-table[data-v-bff70dd6] .qd-service-table__non-editable-col {
77
77
  background-color: color-mix(in srgb, var(--td-bg-color-component) 50%, transparent);
78
78
  }
79
- .qd-service-table[data-v-92206ee3] .qd-service-table__non-editable-col:is(
79
+ .qd-service-table[data-v-bff70dd6] .qd-service-table__non-editable-col:is(
80
80
  .t-table__cell--fixed-left,
81
81
  .t-table__cell--fixed-right
82
82
  ) {
83
83
  background-color: inherit;
84
84
  background-image: linear-gradient(color-mix(in srgb, var(--td-bg-color-secondarycontainer) 50%, transparent), color-mix(in srgb, var(--td-bg-color-secondarycontainer) 50%, transparent));
85
85
  }
86
- .qd-service-table--disable-horizontal-scroll[data-v-92206ee3] colgroup > col {
86
+ .qd-service-table--disable-horizontal-scroll[data-v-bff70dd6] colgroup > col {
87
87
  width: auto !important;
88
88
  }
89
+ .qd-service-table[data-v-bff70dd6] .t-table__filter-pop-content-inner {
90
+ padding: var(--td-comp-paddingTB-s) var(--td-comp-paddingLR-s) 0;
91
+ }
92
+ .qd-service-table[data-v-bff70dd6] .t-table__filter-pop-content-inner:has(.qd-service-table-filter-item) {
93
+ padding: 0;
94
+ }
95
+ .qd-service-table[data-v-bff70dd6] .t-table__filter-pop-content-inner:has(
96
+ .qd-service-table-filter-input,
97
+ .qd-service-table-filter-custom
98
+ ) {
99
+ padding-bottom: var(--td-comp-paddingTB-s);
100
+ }
101
+ .qd-service-table[data-v-bff70dd6] .t-table__filter--bottom-buttons {
102
+ padding: var(--td-comp-paddingTB-s) var(--td-comp-paddingLR-s);
103
+ }
104
+ .qd-service-table--mini[data-v-bff70dd6] .t-table__filter-pop-content-inner {
105
+ padding: var(--td-comp-paddingTB-xs) var(--td-comp-paddingLR-xs) 0;
106
+ }
107
+ .qd-service-table--mini[data-v-bff70dd6] .t-table__filter--bottom-buttons {
108
+ padding: var(--td-comp-paddingTB-xs) var(--td-comp-paddingLR-xs);
109
+ }
110
+ .qd-service-table--mini[data-v-bff70dd6] .t-table__filter-pop-content-inner:has(.qd-service-table-filter-item) {
111
+ padding: 0;
112
+ }
113
+ .qd-service-table--mini[data-v-bff70dd6] .t-table__filter-pop-content-inner:has(
114
+ .qd-service-table-filter-input,
115
+ .qd-service-table-filter-custom
116
+ ) {
117
+ padding-bottom: var(--td-comp-paddingTB-xs);
118
+ }
119
+ .qd-service-table[data-v-bff70dd6] .qd-service-table-filter-item {
120
+ width: 266px;
121
+ }
122
+ .qd-service-table[data-v-bff70dd6] .qd-service-table-filter-item__search,
123
+ .qd-service-table[data-v-bff70dd6] .qd-service-table-filter-item__all,
124
+ .qd-service-table[data-v-bff70dd6] .qd-service-table-filter-item__options {
125
+ padding: var(--td-comp-paddingTB-s) var(--td-comp-paddingLR-s) 0;
126
+ }
127
+ .qd-service-table[data-v-bff70dd6] .qd-service-table-filter-item__all {
128
+ padding: 0 var(--td-comp-paddingLR-s);
129
+ border-bottom: 1px solid var(--td-component-stroke);
130
+ }
131
+ .qd-service-table[data-v-bff70dd6] .qd-service-table-filter-item__options {
132
+ display: flex;
133
+ flex-direction: column;
134
+ height: 206px;
135
+ padding: 0 var(--td-comp-paddingLR-s);
136
+ overflow-y: auto;
137
+ }
138
+ .qd-service-table[data-v-bff70dd6] .qd-service-table-filter-item__count {
139
+ margin-left: var(--td-comp-margin-xs);
140
+ color: var(--td-text-color-placeholder);
141
+ }
142
+ .qd-service-table[data-v-bff70dd6] .qd-service-table-filter-item__cell {
143
+ pointer-events: none;
144
+ }
145
+ .qd-service-table[data-v-bff70dd6] .qd-service-table-filter-item .t-checkbox__label,
146
+ .qd-service-table[data-v-bff70dd6] .qd-service-table-filter-item .t-radio__label {
147
+ display: inline-flex;
148
+ align-items: center;
149
+ }
150
+ .qd-service-table--mini[data-v-bff70dd6] .qd-service-table-filter-item__search {
151
+ padding: var(--td-comp-paddingTB-xs) var(--td-comp-paddingLR-xs) 0;
152
+ }
153
+ .qd-service-table--mini[data-v-bff70dd6] .qd-service-table-filter-item__all,
154
+ .qd-service-table--mini[data-v-bff70dd6] .qd-service-table-filter-item__options {
155
+ padding: 0 var(--td-comp-paddingLR-xs);
156
+ }
@@ -1,2 +1,2 @@
1
1
  export { default as QdServiceTable } from './index.vue';
2
- export type { QdServiceTableCol, QdServiceTableFormItem, QdServiceTableInstanceFunctions, QdServiceTableProps, QdServiceTableScroll, QdServiceTableSubmitRowContext, QdServiceTableSubmitTableContext, QdServiceTableValidateParams, QdServiceTableValidateRowContext, QdServiceTableValidateTableContext } from './types';
2
+ export type { QdServiceTableCol, QdServiceTableFilterItem, QdServiceTableFilterOption, QdServiceTableFormItem, QdServiceTableInstanceFunctions, QdServiceTableProps, QdServiceTableScroll, QdServiceTableSubmitRowContext, QdServiceTableSubmitTableContext, QdServiceTableValidateParams, QdServiceTableValidateRowContext, QdServiceTableValidateTableContext } from './types';
@@ -2,7 +2,7 @@ import './index.css'
2
2
  import _sfc_main from "./index.vue2.mjs";
3
3
  /* empty css */
4
4
  import _export_sfc from "../../../_virtual/_plugin-vue_export-helper.mjs";
5
- const QdServiceTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-92206ee3"]]);
5
+ const QdServiceTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-bff70dd6"]]);
6
6
  export {
7
7
  QdServiceTable as default
8
8
  };
@@ -1,18 +1,22 @@
1
1
  import './index.css'
2
- import { defineComponent, mergeDefaults, useCssVars, computed, ref, useSlots, useTemplateRef, shallowRef, inject, getCurrentInstance, reactive, createVNode, watch, nextTick, onMounted, onActivated, onDeactivated, onBeforeUnmount, withDirectives, createBlock, openBlock, resolveDynamicComponent, unref, mergeProps, isRef, createSlots, withCtx, renderList, renderSlot, normalizeProps, guardReactiveProps, render, h } from "vue";
2
+ import { defineComponent, mergeDefaults, useCssVars, computed, ref, useSlots, useTemplateRef, shallowRef, inject, getCurrentInstance, reactive, createVNode, watch, nextTick, onMounted, onActivated, onDeactivated, onBeforeUnmount, withDirectives, createBlock, openBlock, resolveDynamicComponent, unref, mergeProps, isRef, createSlots, withCtx, renderList, renderSlot, normalizeProps, guardReactiveProps, h, render } from "vue";
3
3
  import { useVModels, useElementSize, useElementBounding, useIntersectionObserver } from "../../../node_modules/.pnpm/@vueuse_core@14.2.0_vue@3.5.26_typescript@5.9.3_/node_modules/@vueuse/core/dist/index.mjs";
4
- import { useActivated, useTimer, easyCopy, isEmpty, suspectedWrapperPromise, getScrollEl, useServicePagination, createExposeProxy, resizeDirective } from "qidian-shared";
4
+ import { useActivated, useTimer, useServicePagination, easyCopy, isEmpty, suspectedWrapperPromise, getScrollEl, createExposeProxy, resizeDirective } from "qidian-shared";
5
5
  import { LoadingIcon, AddRectangleIcon, MinusRectangleIcon } from "tdesign-icons-vue-next";
6
6
  import { EnhancedTable, Table, Empty } from "tdesign-vue-next";
7
7
  import { validate } from "tdesign-vue-next/es/form/utils/form-model.mjs";
8
8
  import { useModal } from "../../../hooks/useModal.mjs";
9
9
  import { getTransformOffset } from "../../../utils/tools.mjs";
10
10
  import { useConfig } from "../../config-provider/useConfig.mjs";
11
- import { resolveQdFormItemOptions, getQdFormComponentName } from "../../form/utils.mjs";
11
+ import { getQdFormComponentName, resolveQdFormItemOptions } from "../../form/utils.mjs";
12
12
  import QdServiceTableEditCell from "./edit-cell.mjs";
13
+ import QdServiceTableFilterItem from "./filter-item.mjs";
13
14
  import { qdServiceTableTreeConfig, qdServiceTableProps, getSortParams } from "./props.mjs";
15
+ import { useReadonly } from "../../../hooks/useReadonly.mjs";
16
+ import { useDisabled } from "../../../hooks/useDisabled.mjs";
14
17
  import { PROVIDE_FORM_ADD_BEFORE_SUBMIT_QUEUE } from "../../form/config.mjs";
15
18
  import get from "../../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/get.mjs";
19
+ import _sfc_main$1 from "../../config-renderer/index.vue.mjs";
16
20
  import QdForm from "../../form/index.vue.mjs";
17
21
  import set from "../../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/set.mjs";
18
22
  const defaultMinWidth = 80;
@@ -38,6 +42,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
38
42
  emptyImage: {
39
43
  type: [Boolean, String]
40
44
  },
45
+ readonly: {
46
+ type: Boolean
47
+ },
41
48
  lazyForm: {
42
49
  type: Boolean
43
50
  },
@@ -325,8 +332,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
325
332
  emit: __emit
326
333
  }) {
327
334
  useCssVars((_ctx) => ({
328
- "v48c62e9a": affixedHeaderTransform.value,
329
- "v442c3de2": expandedRowWidth.value
335
+ "d0bff1fe": affixedHeaderTransform.value,
336
+ "v2ce85a94": expandedRowWidth.value
330
337
  }));
331
338
  const props = __props;
332
339
  const emit = __emit;
@@ -376,6 +383,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
376
383
  const {
377
384
  msgError
378
385
  } = useModal();
386
+ const tdReadonly = useReadonly();
387
+ const tdDisabled = useDisabled();
388
+ const tableReadonly = computed(() => tdReadonly.value || tdDisabled.value);
379
389
  const tableRef = useTemplateRef("table");
380
390
  const treeLoadIds = ref([]);
381
391
  const editingCells = shallowRef([]);
@@ -495,7 +505,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
495
505
  let affixRefreshRafId = 0;
496
506
  let animatingAncestorCleanup = null;
497
507
  const adaptedColumns = computed(() => {
498
- const columns = wrapFormItemColumns(props.columns || []);
508
+ const columns = wrapColumns(props.columns || []);
499
509
  const selectType = props.selectType;
500
510
  if (!selectType) return columns;
501
511
  const selectIdx = columns.findIndex((item) => item.type === "single" || item.type === "multiple");
@@ -515,6 +525,24 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
515
525
  }
516
526
  return columns;
517
527
  });
528
+ const displayData = computed(() => {
529
+ if (props.onFilterChange) return data.value;
530
+ if (props.service && props.pagination !== false) return data.value;
531
+ const activeFilters = getActiveFilterEntries();
532
+ if (!activeFilters.length) return data.value;
533
+ return data.value.filter((row) => activeFilters.every(({
534
+ colKey,
535
+ type,
536
+ value
537
+ }) => {
538
+ const rowValue = get(row, colKey);
539
+ if (type === "input") {
540
+ return String(rowValue ?? "").toLowerCase().includes(String(value).toLowerCase());
541
+ }
542
+ if (Array.isArray(value)) return value.includes(rowValue);
543
+ return rowValue === value;
544
+ }));
545
+ });
518
546
  const {
519
547
  stop: tableContentStop,
520
548
  pause: tableContentPause,
@@ -550,12 +578,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
550
578
  columnControllerVisible: columnControllerVisible2,
551
579
  displayColumns: displayColumns2,
552
580
  expandedRowKeys: expandedRowKeys2,
553
- filterValue: filterValue2,
581
+ filterValue: inFilterValue,
554
582
  sort: sort2,
555
583
  searchData: _searchData,
556
584
  expandedTreeNodes: expandedTreeNodes2,
557
585
  emptyText,
558
586
  emptyImage: _emptyImage,
587
+ readonly: _readonly,
559
588
  lazyForm: _lazyForm,
560
589
  scroll,
561
590
  selectOnRowClick,
@@ -582,6 +611,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
582
611
  const reTableOptions = tableOptions;
583
612
  const onValidate = reTableOptions.onValidate;
584
613
  const onRowValidate = reTableOptions.onRowValidate;
614
+ const onFilterChange = reTableOptions.onFilterChange;
585
615
  reTableOptions.onValidate = (context) => {
586
616
  replaceTableValidationErrors(context.result);
587
617
  onValidate?.(context);
@@ -590,6 +620,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
590
620
  syncCellValidationErrors(context.result);
591
621
  onRowValidate?.(context);
592
622
  };
623
+ reTableOptions.onFilterChange = (value, context) => {
624
+ if (filterValue) filterValue.value = value;
625
+ onFilterChange?.(value, context);
626
+ if (onFilterChange) return;
627
+ if (!service || pagination === false) return;
628
+ changeCurrent(1);
629
+ };
593
630
  const expandedRow = reTableOptions.expandedRow;
594
631
  if (expandedRow) {
595
632
  reTableOptions.expandedRow = (h2, context) => expandedRow(h2, {
@@ -736,7 +773,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
736
773
  };
737
774
  const hasFormItemColumns = formItemColumns.value.length > 0;
738
775
  const callerEditableCellState = reTableOptions.editableCellState;
739
- const reEditableCellState = hasFormItemColumns ? (context) => {
776
+ const reEditableCellState = tableReadonly.value ? () => false : hasFormItemColumns ? (context) => {
740
777
  const column = context.col;
741
778
  if (!column.formItem) {
742
779
  if (callerEditableCellState) return callerEditableCellState(context);
@@ -745,7 +782,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
745
782
  }
746
783
  return !resolveFormItemLazy(column) || isEditingCell(context.row, column.colKey);
747
784
  } : callerEditableCellState;
748
- const reEditableRowKeys = hasFormItemColumns ? (data2 || []).map((row) => getRowValue(row)) : reTableOptions.editableRowKeys;
785
+ const reEditableRowKeys = tableReadonly.value ? [] : hasFormItemColumns ? (data2 || []).map((row) => getRowValue(row)) : reTableOptions.editableRowKeys;
749
786
  const {
750
787
  offsetBottom: horizontalScrollOffsetBottom = 0,
751
788
  onFixedChange: onHorizontalScrollFixedChange,
@@ -838,7 +875,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
838
875
  columnControllerVisible: columnControllerVisible2,
839
876
  displayColumns: displayColumns2,
840
877
  expandedRowKeys: expandedRowKeys2,
841
- filterValue: filterValue2,
878
+ filterValue: inFilterValue,
842
879
  sort: sort2,
843
880
  expandedTreeNodes: expandedTreeNodes2
844
881
  }
@@ -867,7 +904,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
867
904
  };
868
905
  });
869
906
  });
870
- watch([reSort, () => searchData.value?.orderByColumn, () => searchData.value?.isAsc], syncSearchDataSort, {
907
+ watch([reSort, () => props.columns, () => searchData.value?.orderByColumn, () => searchData.value?.isAsc], syncSearchDataSort, {
871
908
  immediate: true,
872
909
  flush: "sync"
873
910
  });
@@ -902,6 +939,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
902
939
  });
903
940
  const reOnSortChange = (sortValue, options) => {
904
941
  reProps.value.tableOptions.onSortChange?.(sortValue, options);
942
+ if (typeof options.col.sorter === "function") return;
905
943
  changeCurrent(1);
906
944
  };
907
945
  const tableLoad = computed(() => {
@@ -952,16 +990,32 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
952
990
  if (props.defaultSort) return normalizeSort(props.defaultSort);
953
991
  return props.multipleSort ? [] : void 0;
954
992
  }
993
+ function isLocalSortColumn(sortBy) {
994
+ function findColumn(columns) {
995
+ for (const column of columns) {
996
+ if (column.colKey === sortBy) return column;
997
+ const child = column.children ? findColumn(column.children) : void 0;
998
+ if (child) return child;
999
+ }
1000
+ }
1001
+ return typeof findColumn(props.columns ?? [])?.sorter === "function";
1002
+ }
1003
+ function getRemoteSort(value) {
1004
+ const sortList = Array.isArray(value) ? value : value ? [value] : [];
1005
+ const remoteSortList = sortList.filter((item) => !isLocalSortColumn(item.sortBy));
1006
+ return Array.isArray(value) ? remoteSortList : remoteSortList[0];
1007
+ }
955
1008
  async function transformServiceParams(params) {
956
1009
  const mergedParams = {
957
1010
  ...params,
958
- ...searchData.value
1011
+ ...searchData.value,
1012
+ ...getActiveFilterParams()
959
1013
  };
960
1014
  if (props.transformParams) return props.transformParams(mergedParams);
961
1015
  return mergedParams;
962
1016
  }
963
1017
  function syncSearchDataSort() {
964
- const sortParams = getSortParams(reSort.value);
1018
+ const sortParams = getSortParams(getRemoteSort(reSort.value));
965
1019
  const current2 = searchData.value;
966
1020
  if (!current2) return;
967
1021
  if (sortParams.orderByColumn) {
@@ -1183,6 +1237,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1183
1237
  }, 0);
1184
1238
  }
1185
1239
  function enterEditingCell(target, autofocus = true) {
1240
+ if (tableReadonly.value) return;
1186
1241
  const currentActiveCell = activeEditingCell.value;
1187
1242
  if (currentActiveCell && !isSameEditingCell(currentActiveCell, target)) {
1188
1243
  clearAutofocusEditingCell(currentActiveCell);
@@ -1203,6 +1258,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1203
1258
  void exitEditingCell(activeEditingCell.value);
1204
1259
  }
1205
1260
  function handleCellClick(context) {
1261
+ if (tableReadonly.value) return;
1206
1262
  const column = context.col;
1207
1263
  if (column.formItem) {
1208
1264
  const editingCell = findEditingCell(context.row, column.colKey);
@@ -1654,24 +1710,194 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1654
1710
  rowData: row ? easyCopy(row) : void 0
1655
1711
  };
1656
1712
  }
1657
- function wrapFormItemColumns(columns) {
1713
+ function isActiveFilterValue(value) {
1714
+ if (Array.isArray(value)) return value.length > 0;
1715
+ return value !== void 0 && value !== null && value !== "";
1716
+ }
1717
+ function getActiveFilterParams() {
1718
+ return Object.fromEntries(Object.entries(filterValue?.value ?? {}).filter(([, value]) => isActiveFilterValue(value)));
1719
+ }
1720
+ function getFilterColumns(columns) {
1721
+ return columns.flatMap((column) => column.children ? getFilterColumns(column.children) : column.colKey ? [column] : []);
1722
+ }
1723
+ function getActiveFilterEntries() {
1724
+ const values = filterValue?.value ?? {};
1725
+ return getFilterColumns(props.columns || []).flatMap((column) => {
1726
+ if (!column.colKey) return [];
1727
+ const value = values[column.colKey];
1728
+ if (!isActiveFilterValue(value)) return [];
1729
+ const filterItem = column.filterItem === true ? {} : column.filterItem;
1730
+ const type = column.filter?.type ?? (filterItem?.component ? void 0 : filterItem?.type);
1731
+ return [{
1732
+ colKey: column.colKey,
1733
+ type,
1734
+ value
1735
+ }];
1736
+ });
1737
+ }
1738
+ function resolveFilterOptions(column, configuredOptions, reuseCell = true) {
1739
+ const counts = /* @__PURE__ */ new Map();
1740
+ const firstRows = /* @__PURE__ */ new Map();
1741
+ const colKey = column.colKey;
1742
+ data.value.forEach((row, rowIndex) => {
1743
+ const value = colKey ? get(row, colKey) : void 0;
1744
+ if (typeof value !== "string" && typeof value !== "number") return;
1745
+ if (value === "") return;
1746
+ counts.set(value, (counts.get(value) ?? 0) + 1);
1747
+ if (!firstRows.has(value)) firstRows.set(value, {
1748
+ row,
1749
+ rowIndex
1750
+ });
1751
+ });
1752
+ if (configuredOptions) {
1753
+ return configuredOptions.map((option) => ({
1754
+ ...option,
1755
+ count: option.count ?? counts.get(option.value) ?? 0
1756
+ }));
1757
+ }
1758
+ const colIndex = getFilterColumns(props.columns || []).indexOf(column);
1759
+ return [...counts].map(([value, count]) => {
1760
+ const firstRow = firstRows.get(value);
1761
+ return {
1762
+ label: String(value),
1763
+ value,
1764
+ count,
1765
+ ...reuseCell && firstRow ? {
1766
+ render: () => renderDisplayCell(h, column, {
1767
+ ...firstRow,
1768
+ col: column,
1769
+ colIndex
1770
+ })
1771
+ } : {}
1772
+ };
1773
+ });
1774
+ }
1775
+ function createConfigFilterComponent(component) {
1776
+ return /* @__PURE__ */ defineComponent({
1777
+ inheritAttrs: false,
1778
+ setup(_, {
1779
+ attrs
1780
+ }) {
1781
+ return () => {
1782
+ const filterAttrs = Object.fromEntries(Object.entries(attrs).filter(([, value]) => value !== void 0));
1783
+ return h(_sfc_main$1, {
1784
+ config: component,
1785
+ ...filterAttrs,
1786
+ class: ["qd-service-table-filter-custom", filterAttrs.class]
1787
+ });
1788
+ };
1789
+ }
1790
+ });
1791
+ }
1792
+ function resolveColumnFilter(column, filterItem, filter) {
1793
+ const config = filterItem === true ? {} : filterItem;
1794
+ const {
1795
+ component,
1796
+ options,
1797
+ reuseCell = true,
1798
+ type = "multiple",
1799
+ props: filterProps,
1800
+ ...filterOptions
1801
+ } = config;
1802
+ let generatedFilter;
1803
+ if (component) {
1804
+ generatedFilter = {
1805
+ resetValue: "",
1806
+ showConfirmAndReset: true,
1807
+ ...filterOptions,
1808
+ props: filterProps,
1809
+ component: createConfigFilterComponent(component)
1810
+ };
1811
+ } else if (type === "input") {
1812
+ generatedFilter = {
1813
+ resetValue: "",
1814
+ showConfirmAndReset: true,
1815
+ ...filterOptions,
1816
+ props: {
1817
+ placeholder: tableT("filterItemInputPlaceholder"),
1818
+ ...filterProps,
1819
+ class: "qd-service-table-filter-input"
1820
+ },
1821
+ type
1822
+ };
1823
+ } else {
1824
+ const resolvedOptions = resolveFilterOptions(column, options, reuseCell);
1825
+ generatedFilter = {
1826
+ resetValue: type === "multiple" ? [] : "",
1827
+ showConfirmAndReset: true,
1828
+ ...filterOptions,
1829
+ list: resolvedOptions,
1830
+ props: {
1831
+ ...filterProps,
1832
+ options: resolvedOptions,
1833
+ type
1834
+ },
1835
+ component: QdServiceTableFilterItem,
1836
+ ...type === "multiple" ? {
1837
+ confirmDisabled: (value) => value === null
1838
+ } : {},
1839
+ ...!options && reuseCell ? {
1840
+ renderFilterValue: (_h, {
1841
+ value
1842
+ }) => {
1843
+ const values = Array.isArray(value) ? value : [value];
1844
+ return values.map((item, index) => {
1845
+ const option = resolvedOptions.find((option2) => option2.value === item);
1846
+ const content = option?.render?.() ?? option?.label ?? String(item);
1847
+ return [index ? "," : null, h("span", {
1848
+ class: "qd-service-table-filter-item__cell",
1849
+ inert: true
1850
+ }, [content])];
1851
+ });
1852
+ }
1853
+ } : {}
1854
+ };
1855
+ }
1856
+ const resolvedFilter = {
1857
+ ...generatedFilter,
1858
+ ...filter,
1859
+ props: {
1860
+ ...generatedFilter.props,
1861
+ ...filter?.props
1862
+ }
1863
+ };
1864
+ if (resolvedFilter.component === QdServiceTableFilterItem) {
1865
+ resolvedFilter.props = {
1866
+ ...resolvedFilter.props,
1867
+ showConfirmAndReset: resolvedFilter.showConfirmAndReset !== false
1868
+ };
1869
+ }
1870
+ return resolvedFilter;
1871
+ }
1872
+ function wrapColumns(columns) {
1658
1873
  return columns.map((column) => {
1659
1874
  const {
1660
1875
  children,
1876
+ edit,
1877
+ filter,
1878
+ filterItem,
1661
1879
  formItem,
1662
1880
  ...tableColumn
1663
1881
  } = column;
1664
1882
  const reColumn = {
1665
1883
  ...tableColumn,
1884
+ ...!tableReadonly.value && edit ? {
1885
+ edit
1886
+ } : {},
1887
+ ...filterItem ? {
1888
+ filter: resolveColumnFilter(column, filterItem, filter)
1889
+ } : {
1890
+ filter
1891
+ },
1666
1892
  ...formItem ? {
1667
1893
  formItem
1668
1894
  } : {},
1669
1895
  ...children ? {
1670
- children: wrapFormItemColumns(children)
1896
+ children: wrapColumns(children)
1671
1897
  } : {}
1672
1898
  };
1673
1899
  const columnClassName = reColumn.className === void 0 ? [] : Array.isArray(reColumn.className) ? reColumn.className : [reColumn.className];
1674
- if (!formItem) {
1900
+ if (tableReadonly.value || !formItem) {
1675
1901
  if (!children && formItemColumns.value.length) {
1676
1902
  reColumn.className = [...columnClassName, (context) => context.type === "td" ? "qd-service-table__non-editable-col" : ""];
1677
1903
  }
@@ -1685,7 +1911,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1685
1911
  ...attrs,
1686
1912
  onDblclick: (event) => {
1687
1913
  if (typeof onDblclick === "function") onDblclick(event);
1688
- if (event.defaultPrevented || !resolveFormItemLazy(column)) return;
1914
+ if (event.defaultPrevented || tableReadonly.value || !resolveFormItemLazy(column)) {
1915
+ return;
1916
+ }
1689
1917
  enterEditingCell({
1690
1918
  row: context.row,
1691
1919
  colKey: column.colKey
@@ -1753,7 +1981,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1753
1981
  };
1754
1982
  }
1755
1983
  };
1756
- const explicitEdit = column.edit;
1984
+ const explicitEdit = edit;
1757
1985
  const generatedProps = generatedEdit.props;
1758
1986
  reColumn.edit = {
1759
1987
  ...generatedEdit,
@@ -1771,6 +1999,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1771
1999
  if (!(rootEl instanceof HTMLElement)) return tableContentEl.value;
1772
2000
  return rootEl.querySelector(".t-table__content") ?? tableContentEl.value;
1773
2001
  }
2002
+ function clearEditingState() {
2003
+ editingCells.value = [];
2004
+ activeEditingCell.value = void 0;
2005
+ autofocusEditingCell.value = void 0;
2006
+ }
1774
2007
  function setScrollElTo(position = scrollRecord) {
1775
2008
  const scrollEl = getCurrentTableContentEl();
1776
2009
  if (!scrollEl) return;
@@ -1993,6 +2226,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1993
2226
  }, {
1994
2227
  immediate: true
1995
2228
  });
2229
+ watch(tableReadonly, (readonly) => {
2230
+ if (!readonly) return;
2231
+ clearEditingState();
2232
+ }, {
2233
+ flush: "sync"
2234
+ });
1996
2235
  watch(expandedTreeNodes, adjustScrollWhenTreeExpanded, {
1997
2236
  flush: "post"
1998
2237
  });
@@ -2120,7 +2359,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2120
2359
  "on-sort-change": reOnSortChange,
2121
2360
  columns: autoWidthColumns.value,
2122
2361
  loading: tableLoad.value,
2123
- data: unref(data),
2362
+ data: displayData.value,
2124
2363
  pagination: rePagination.value
2125
2364
  }), createSlots({
2126
2365
  empty: withCtx(() => [createVNode(unref(Empty), mergeProps({
@@ -11,6 +11,7 @@ export declare const qdServiceTableProps: {
11
11
  readonly searchData: () => {};
12
12
  readonly emptyText: undefined;
13
13
  readonly emptyImage: true;
14
+ readonly readonly: undefined;
14
15
  readonly lazyForm: true;
15
16
  readonly editCellValidationBlock: "error";
16
17
  readonly rowKey: "id";
@@ -10,6 +10,7 @@ const qdServiceTableProps = {
10
10
  searchData: () => ({}),
11
11
  emptyText: void 0,
12
12
  emptyImage: true,
13
+ readonly: void 0,
13
14
  lazyForm: true,
14
15
  editCellValidationBlock: "error",
15
16
  rowKey: "id",
@@ -1,5 +1,6 @@
1
1
  import type { ServicePageParams, ServicePageRes, ServicePagination, ServicePaginationOptions, useServicePagination } from 'qidian-shared';
2
- import type { BaseTableCellParams, EnhancedTableInstanceFunctions, ErrorListObjectType, PrimaryTableInstanceFunctions, TableErrorListMap, TableRowData, TableRowValue, TableTreeNodeExpandOptions, TdEmptyProps, TdEnhancedTableProps, TNode } from 'tdesign-vue-next';
2
+ import type { BaseTableCellParams, EnhancedTableInstanceFunctions, ErrorListObjectType, OptionData, PrimaryTableInstanceFunctions, TableColumnFilter, TableErrorListMap, TableRowData, TableRowValue, TableTreeNodeExpandOptions, TdEmptyProps, TdEnhancedTableProps, TNode } from 'tdesign-vue-next';
3
+ import type { QdComponentConfig } from '../../config-renderer';
3
4
  import type { QdFormItemProps } from '../../form';
4
5
  type TDesignServiceTableCol<D extends TableRowData> = NonNullable<TdEnhancedTableProps<D>['columns']>[number];
5
6
  export type QdServiceTableScroll = NonNullable<TdEnhancedTableProps['scroll']> & {
@@ -9,8 +10,20 @@ export type QdServiceTableScroll = NonNullable<TdEnhancedTableProps['scroll']> &
9
10
  export interface QdServiceTableCol<D extends TableRowData = TableRowData> extends Omit<TDesignServiceTableCol<D>, 'children' | 'foot'> {
10
11
  children?: QdServiceTableCol<D>[];
11
12
  foot?: string | TNode<BaseTableCellParams<D>>;
13
+ filterItem?: true | QdServiceTableFilterItem;
12
14
  formItem?: QdServiceTableFormItem;
13
15
  }
16
+ export interface QdServiceTableFilterOption extends OptionData {
17
+ label: string;
18
+ value: NonNullable<OptionData['value']>;
19
+ count?: number;
20
+ }
21
+ export interface QdServiceTableFilterItem extends Omit<TableColumnFilter, 'component' | 'list' | 'type'> {
22
+ component?: QdComponentConfig;
23
+ options?: QdServiceTableFilterOption[];
24
+ reuseCell?: boolean;
25
+ type?: 'input' | 'single' | 'multiple';
26
+ }
14
27
  export type QdServiceTableFormItem = Omit<QdFormItemProps, 'name' | 'label' | 'context' | 'col' | 'row' | 'labelWidth' | 'labelAlign'> & {
15
28
  lazy?: boolean;
16
29
  virtualValidateRender?: boolean;
@@ -61,6 +74,7 @@ export interface QdServiceTableProps<D extends TableRowData = TableRowData, R =
61
74
  searchData?: Record<string, unknown>;
62
75
  emptyText?: string;
63
76
  emptyImage?: boolean | TdEmptyProps['image'];
77
+ readonly?: boolean;
64
78
  lazyForm?: boolean;
65
79
  editCellValidationBlock?: QdServiceTableEditCellValidationBlock;
66
80
  scroll?: QdServiceTableScroll;
@@ -73,6 +73,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
73
73
  emptyImage: {
74
74
  type: [Boolean, String]
75
75
  },
76
+ readonly: {
77
+ type: Boolean
78
+ },
76
79
  lazyForm: {
77
80
  type: Boolean
78
81
  },
@@ -302,9 +305,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
302
305
  multiple: {
303
306
  type: Boolean
304
307
  },
305
- readonly: {
306
- type: Boolean
307
- },
308
308
  disabled: {
309
309
  type: Boolean
310
310
  },
@@ -87,6 +87,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
87
87
  emptyImage: {
88
88
  type: [Boolean, String]
89
89
  },
90
+ readonly: {
91
+ type: Boolean
92
+ },
90
93
  lazyForm: {
91
94
  type: Boolean
92
95
  },
@@ -308,9 +311,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
308
311
  multiple: {
309
312
  type: Boolean
310
313
  },
311
- readonly: {
312
- type: Boolean
313
- },
314
314
  disabled: {
315
315
  type: Boolean
316
316
  },
@@ -63,6 +63,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
63
63
  emptyImage: {
64
64
  type: [Boolean, String]
65
65
  },
66
+ readonly: {
67
+ type: Boolean
68
+ },
66
69
  lazyForm: {
67
70
  type: Boolean
68
71
  },
@@ -295,9 +298,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
295
298
  multiple: {
296
299
  type: Boolean
297
300
  },
298
- readonly: {
299
- type: Boolean
300
- },
301
301
  disabled: {
302
302
  type: Boolean
303
303
  },
@@ -12,13 +12,13 @@ import { qdUploadAcceptMap } from "./config.mjs";
12
12
  import { qdUploadSizeLimit, qdUploadProps } from "./props.mjs";
13
13
  import { uploadByXhr, calcUploadTimeout } from "./request.mjs";
14
14
  import { PROVIDE_FORM_ADD_BEFORE_SUBMIT_QUEUE, PROVIDE_FORM_ADD_AFTER_SUBMIT_QUEUE, PROVIDE_FORM_RESET_QUEUE } from "../form/config.mjs";
15
- import { useReadonly } from "../../hooks/useReadonly.mjs";
16
- import { useDisabled } from "../../hooks/useDisabled.mjs";
17
15
  import _sfc_main$1 from "./image-file-list-display/index.vue.mjs";
18
16
  import QdUploadFileFlowFileListDisplay from "./file-flow-file-list-display/index.vue.mjs";
19
17
  import _sfc_main$2 from "../multi-file-viewer/index.vue.mjs";
20
18
  /* empty css */
21
19
  import _sfc_main$3 from "./image-flow-file-list-display/index.vue.mjs";
20
+ import { useReadonly } from "../../hooks/useReadonly.mjs";
21
+ import { useDisabled } from "../../hooks/useDisabled.mjs";
22
22
  import { useModal } from "../../hooks/useModal.mjs";
23
23
  const tempOssIdPrefix = "__qd_upload_temp_";
24
24
  const _sfc_main = /* @__PURE__ */ defineComponent({
@@ -350,6 +350,11 @@ declare const _default: {
350
350
  uploadText: string;
351
351
  inputText: string;
352
352
  };
353
+ table: {
354
+ filterItemInputPlaceholder: string;
355
+ filterItemSearchPlaceholder: string;
356
+ filterItemAllText: string;
357
+ };
353
358
  columnsController: {
354
359
  titleText: string;
355
360
  columnNameText: string;
@@ -92,6 +92,11 @@ const enUS = merge(enUS$1, {
92
92
  uploadText: "Please upload",
93
93
  inputText: "Please enter"
94
94
  },
95
+ table: {
96
+ filterItemInputPlaceholder: "Enter keywords to filter",
97
+ filterItemSearchPlaceholder: "Search; separate keywords with spaces",
98
+ filterItemAllText: "All"
99
+ },
95
100
  columnsController: {
96
101
  titleText: "Column Configuration",
97
102
  columnNameText: "Column Name",
@@ -350,6 +350,11 @@ declare const _default: {
350
350
  uploadText: string;
351
351
  inputText: string;
352
352
  };
353
+ table: {
354
+ filterItemInputPlaceholder: string;
355
+ filterItemSearchPlaceholder: string;
356
+ filterItemAllText: string;
357
+ };
353
358
  columnsController: {
354
359
  titleText: string;
355
360
  columnNameText: string;
@@ -89,6 +89,11 @@ const zhCN = merge(zhCN$1, {
89
89
  uploadText: "请上传",
90
90
  inputText: "请输入"
91
91
  },
92
+ table: {
93
+ filterItemInputPlaceholder: "输入关键词过滤",
94
+ filterItemSearchPlaceholder: "搜索,支持用空格分隔多个关键词",
95
+ filterItemAllText: "全部"
96
+ },
92
97
  columnsController: {
93
98
  titleText: "列配置",
94
99
  columnNameText: "列名",
@@ -350,6 +350,11 @@ declare const _default: {
350
350
  uploadText: string;
351
351
  inputText: string;
352
352
  };
353
+ table: {
354
+ filterItemInputPlaceholder: string;
355
+ filterItemSearchPlaceholder: string;
356
+ filterItemAllText: string;
357
+ };
353
358
  columnsController: {
354
359
  titleText: string;
355
360
  columnNameText: string;
@@ -89,6 +89,11 @@ const zhTW = merge(zhTW$1, {
89
89
  uploadText: "請上傳",
90
90
  inputText: "請輸入"
91
91
  },
92
+ table: {
93
+ filterItemInputPlaceholder: "輸入關鍵詞過濾",
94
+ filterItemSearchPlaceholder: "搜尋,支援用空格分隔多個關鍵詞",
95
+ filterItemAllText: "全部"
96
+ },
92
97
  columnsController: {
93
98
  titleText: "列配置",
94
99
  columnNameText: "列名",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qidian-vue-ui",
3
- "version": "2.0.33",
3
+ "version": "2.0.35",
4
4
  "description": "基于 TDesign 的 QiDian Vue UI 组件库",
5
5
  "author": "qidian",
6
6
  "license": "MIT",