plain-design 1.0.0-beta.131 → 1.0.0-beta.132
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/plain-design.commonjs.min.js +2 -2
- package/dist/plain-design.min.css +5 -4
- package/dist/plain-design.min.js +2 -2
- package/dist/report.html +2 -2
- package/package.json +1 -1
- package/src/packages/components/AutoTable/auto-table.scss +21 -0
- package/src/packages/components/AutoTable/filter/useTableOption.filter.state.ts +3 -2
- package/src/packages/components/AutoTable/use/useTableOption.column.popper.tsx +1 -1
- package/src/packages/components/AutoTable/use/useTableOption.fill.tsx +2 -2
- package/src/packages/components/AutoTable/use/useTableOption.hooks.tsx +4 -2
- package/src/packages/components/AutoTable/use/useTableOption.pagination.tsx +1 -1
- package/src/packages/components/AutoTable/use/useTableOption.table.tsx +5 -3
- package/src/packages/components/AutoTable/use/useTableOption.tips.tsx +2 -2
- package/src/packages/components/AutoTable/utils/TableOption.space.tsx +5 -2
- package/src/packages/components/Dropdown/index.tsx +14 -1
- package/src/packages/components/Form/form.scss +4 -0
- package/src/packages/components/Form/layout/useFormLayout.tsx +1 -0
- package/src/packages/components/FormItem/index.tsx +7 -0
- package/src/packages/components/Input/useSuggestionInput.tsx +2 -1
- package/src/packages/components/ListOption/index.tsx +20 -0
- package/src/packages/components/ListPanel/index.tsx +30 -0
- package/src/packages/components/ListPanel/list-panel.scss +20 -0
- package/src/packages/components/Select/createPublicSelectRender.tsx +4 -2
- package/src/packages/components/Select/decodeSelectRenderNode.tsx +4 -2
- package/src/packages/components/Select/index.tsx +13 -1
- package/src/packages/components/Select/select.utils.tsx +3 -2
- package/src/packages/components/Table/plc/use/useTableAutoSpan.tsx +112 -0
- package/src/packages/components/Table/plc/utils/plc.utils.ts +3 -0
- package/src/packages/components/Table/standard/PlcOperation/PlcOperation.tsx +3 -3
- package/src/packages/components/Table/table/Table.tsx +10 -6
- package/src/packages/components/Table/table/body/cell.tsx +34 -3
- package/src/packages/components/Table/table/body/useCellValue.tsx +14 -5
- package/src/packages/components/Table/table/head/head-cell.tsx +6 -0
- package/src/packages/components/Table/table/table.scss +4 -0
- package/src/packages/components/Table/table/use/useTableFormEditor.tsx +5 -1
- package/src/packages/components/Table/table/use/useTableModifyEditor.tsx +8 -2
- package/src/packages/components/Table/table/utils/createTableHooks.ts +5 -3
- package/src/packages/components/Table/table/utils/table.utils.ts +3 -2
- package/src/packages/components/VirtualTable/index.tsx +6 -0
- package/src/packages/components/VirtualTable/virtual-table.scss +3 -3
- package/src/packages/components/createSimpleDate/index.ts +49 -0
- package/src/packages/components/useContextmenuOptions/index.tsx +40 -0
- package/src/packages/components/useTableFilter/index.ts +73 -0
- package/src/packages/entry.tsx +6 -0
|
@@ -245,14 +245,18 @@ export const Table = designComponent({
|
|
|
245
245
|
),
|
|
246
246
|
});
|
|
247
247
|
|
|
248
|
-
hooks.onClickCell.use((
|
|
249
|
-
event.emit.onClickCell(node, e);
|
|
250
|
-
hooks.onClickRow.exec({ e, node });
|
|
248
|
+
hooks.onClickCell.use((val) => {
|
|
249
|
+
event.emit.onClickCell(val.node, val.e, val.plc);
|
|
250
|
+
hooks.onClickRow.exec({ e: val.e, node: val.node });
|
|
251
251
|
});
|
|
252
252
|
|
|
253
|
-
hooks.onDblclickCell.use((
|
|
254
|
-
event.emit.onDblclickCell(node, e);
|
|
255
|
-
hooks.onDblclickRow.exec({ e, node });
|
|
253
|
+
hooks.onDblclickCell.use((val) => {
|
|
254
|
+
event.emit.onDblclickCell(val.node, val.e, val.plc);
|
|
255
|
+
hooks.onDblclickRow.exec({ e: val.e, node: val.node });
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
hooks.onContextmenuCell.use((val) => {
|
|
259
|
+
event.emit.onContextmenuCell(val.node, val.e, val.plc);
|
|
256
260
|
});
|
|
257
261
|
|
|
258
262
|
hooks.onClickHeadCell.use(({ e, plc }) => {!plc.props.disableAutoEmitClickTitle && event.emit.onClickHead(plc, e);});
|
|
@@ -10,6 +10,7 @@ import {useCellValue} from "./useCellValue";
|
|
|
10
10
|
import {createTooltip} from "../../../useTooltip";
|
|
11
11
|
import {createEffects} from "@peryl/utils/createEffects";
|
|
12
12
|
import {usePopup} from "../../../usePopup";
|
|
13
|
+
import {injectTableAutoSpan} from "../../plc/use/useTableAutoSpan";
|
|
13
14
|
|
|
14
15
|
export const PltCell = designComponent({
|
|
15
16
|
name: 'plt-cell',
|
|
@@ -23,6 +24,9 @@ export const PltCell = designComponent({
|
|
|
23
24
|
const { refs, onRef } = useRefs({ el: iHTMLElement });
|
|
24
25
|
|
|
25
26
|
const popup = usePopup();
|
|
27
|
+
|
|
28
|
+
const tableAutoSpan = injectTableAutoSpan();
|
|
29
|
+
|
|
26
30
|
/**
|
|
27
31
|
* 单元格校验
|
|
28
32
|
* @author 韦胜健
|
|
@@ -51,6 +55,11 @@ export const PltCell = designComponent({
|
|
|
51
55
|
props.table.hooks.onDblclickCell.exec({ e, node: props.node, plc: props.plc });
|
|
52
56
|
};
|
|
53
57
|
|
|
58
|
+
const onContextmenu = (e: iMouseEvent) => {
|
|
59
|
+
// if (bodyCell.value().editable) {return;}
|
|
60
|
+
props.table.hooks.onContextmenuCell.exec({ e, node: props.node, plc: props.plc });
|
|
61
|
+
};
|
|
62
|
+
|
|
54
63
|
/**
|
|
55
64
|
* 鼠标进入单元格
|
|
56
65
|
* @author 韦胜健
|
|
@@ -70,7 +79,9 @@ export const PltCell = designComponent({
|
|
|
70
79
|
* @author 韦胜健
|
|
71
80
|
* @date 2022/12/5 20:35
|
|
72
81
|
*/
|
|
73
|
-
const {
|
|
82
|
+
const { effects: cellValueEffects } = createEffects();
|
|
83
|
+
onBeforeUnmount(() => cellValueEffects.clear());
|
|
84
|
+
const { bodyCell } = useCellValue({ optionGetter: () => ({ node: props.node, plc: props.plc }), formEdit: false, effects: cellValueEffects });
|
|
74
85
|
|
|
75
86
|
/**
|
|
76
87
|
* 单元格样式类名
|
|
@@ -143,7 +154,7 @@ export const PltCell = designComponent({
|
|
|
143
154
|
* 则不显示overflowTooltip
|
|
144
155
|
*/
|
|
145
156
|
if (!props.plc.props.overflowTooltip || !bodyCell || bodyCell.editable) {
|
|
146
|
-
return emptyOverflowTooltipOption
|
|
157
|
+
return emptyOverflowTooltipOption;
|
|
147
158
|
} else {
|
|
148
159
|
return {
|
|
149
160
|
reference: !props.plc.props.overflowTooltip || !bodyCell || bodyCell.editable ? null : refs.el,
|
|
@@ -182,14 +193,32 @@ export const PltCell = designComponent({
|
|
|
182
193
|
return { update };
|
|
183
194
|
})();
|
|
184
195
|
|
|
196
|
+
/*每次渲染都记录上一次的span,某次渲染在offsetData中找不到自己的offsetIndex时,就用上一次的span*/
|
|
197
|
+
let prevSpan = { rowspan: 1, colspan: 1 };
|
|
198
|
+
|
|
185
199
|
return {
|
|
186
200
|
render: () => {
|
|
187
201
|
const { node, plc } = props;
|
|
188
202
|
const { body, editable } = bodyCell.value();
|
|
189
|
-
|
|
203
|
+
let span = !!props.table.props.spanMethod ? props.table.props.spanMethod({ node, plc }) : { rowspan: 1, colspan: 1 };
|
|
190
204
|
if (plc.props.editColSpan != null && node.state.edit) {
|
|
191
205
|
span.colspan = typeof plc.props.editColSpan === "function" ? plc.props.editColSpan(node) : plc.props.editColSpan;
|
|
192
206
|
}
|
|
207
|
+
if (!!tableAutoSpan.value && (plc.props.autoRowSpan || plc.props.autoColSpan)) {
|
|
208
|
+
const { spans, data: offsetData } = tableAutoSpan.value;
|
|
209
|
+
/*要用offsetIndex,而不是props.node.state.index,这个是行数据在所有数据中的真实索引,而不是在虚拟列表数据中的索引*/
|
|
210
|
+
/*计算的spans仅含有虚拟数据的合并结果*/
|
|
211
|
+
const offsetIndex = offsetData.indexOf(props.node.data);
|
|
212
|
+
if (offsetIndex > -1) {
|
|
213
|
+
const rowSpan = !plc.props.field ? null : spans[offsetIndex].row?.[plc.props.field];
|
|
214
|
+
if (rowSpan != null) {span.rowspan = rowSpan;}
|
|
215
|
+
const colSpan = !plc.props.field ? null : spans[offsetIndex].col?.[plc.props.field];
|
|
216
|
+
if (colSpan != null) {span.colspan = colSpan;}
|
|
217
|
+
} else {
|
|
218
|
+
span = prevSpan;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
prevSpan = span;
|
|
193
222
|
if (span.rowspan === 0 || span.colspan === 0) {
|
|
194
223
|
/*rowspan为0时,不会正确合并单元格,如果要合并单元格则不渲染这个td*/
|
|
195
224
|
return null;
|
|
@@ -201,6 +230,7 @@ export const PltCell = designComponent({
|
|
|
201
230
|
// console.log('cell', props.plc.props.title);
|
|
202
231
|
return (
|
|
203
232
|
<td
|
|
233
|
+
data-span={String(span.rowspan != 1 || span.colspan != 1)}
|
|
204
234
|
ref={onRef.el}
|
|
205
235
|
rowSpan={span.rowspan}
|
|
206
236
|
colSpan={span.colspan}
|
|
@@ -208,6 +238,7 @@ export const PltCell = designComponent({
|
|
|
208
238
|
style={styles.value}
|
|
209
239
|
onClick={onClick}
|
|
210
240
|
onDoubleClick={onDblclick}
|
|
241
|
+
onContextMenu={onContextmenu}
|
|
211
242
|
onMouseEnter={onEnter}
|
|
212
243
|
onMouseLeave={onLeave}
|
|
213
244
|
>
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import {iTableNode} from "../utils/table.utils";
|
|
2
2
|
import {tPlc} from "../../plc/utils/plc.utils";
|
|
3
|
-
import {
|
|
3
|
+
import {globalComputed, reactive, toRaw} from "@peryl/react-compose";
|
|
4
4
|
import {PlainObject} from "@peryl/utils/event";
|
|
5
5
|
import {LoadingText} from "../../../../utils/LoadingText";
|
|
6
6
|
import {AsyncFormatter} from "../../../AsyncFormatter";
|
|
7
7
|
import {Formatter} from "../../../Formatter";
|
|
8
8
|
import {renderBodyCell} from "../../plc/utils/plc.render";
|
|
9
|
+
import {iEffects} from "@peryl/utils/createEffects";
|
|
10
|
+
import {delay} from "@peryl/utils/delay";
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* 计算cell渲染所需要的内容
|
|
@@ -16,9 +18,11 @@ export function useCellValue(
|
|
|
16
18
|
{
|
|
17
19
|
optionGetter,
|
|
18
20
|
formEdit,
|
|
21
|
+
effects,
|
|
19
22
|
}: {
|
|
20
23
|
optionGetter: () => { node: iTableNode, plc: tPlc },
|
|
21
24
|
formEdit: boolean,
|
|
25
|
+
effects: iEffects,
|
|
22
26
|
}
|
|
23
27
|
) {
|
|
24
28
|
/**
|
|
@@ -26,20 +30,22 @@ export function useCellValue(
|
|
|
26
30
|
* @author 韦胜健
|
|
27
31
|
* @date 2022.12.3 10:50
|
|
28
32
|
*/
|
|
29
|
-
const row =
|
|
33
|
+
const row = globalComputed(() => {
|
|
30
34
|
const { node } = optionGetter();
|
|
31
35
|
return node.state.edit ? node.state.editRow : node.data;
|
|
32
36
|
});
|
|
37
|
+
effects.push(() => row.effect.stop());
|
|
33
38
|
|
|
34
39
|
/**
|
|
35
40
|
* 当前单元格的目标数据
|
|
36
41
|
* @author 韦胜健
|
|
37
42
|
* @date 2022.12.3 10:50
|
|
38
43
|
*/
|
|
39
|
-
const sourceValue =
|
|
44
|
+
const sourceValue = globalComputed(() => {
|
|
40
45
|
const { plc } = optionGetter();
|
|
41
46
|
return !!plc.props.field ? row.value[plc.props.field] : null;
|
|
42
47
|
});
|
|
48
|
+
effects.push(() => sourceValue.effect.stop());
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
51
|
* 异步格式化的状态
|
|
@@ -58,8 +64,9 @@ export function useCellValue(
|
|
|
58
64
|
loading: boolean,
|
|
59
65
|
}
|
|
60
66
|
});
|
|
67
|
+
effects.push(() => delay().then(() => {asyncState.asyncValue = null;}));
|
|
61
68
|
|
|
62
|
-
const targetValue =
|
|
69
|
+
const targetValue = globalComputed(() => {
|
|
63
70
|
const { plc, node } = optionGetter();
|
|
64
71
|
const { formatter, asyncFormatter, formatterOptions } = plc.props;
|
|
65
72
|
const cellRenderScope = { plc: plc, node: node, row: row.value };
|
|
@@ -125,12 +132,14 @@ export function useCellValue(
|
|
|
125
132
|
return sourceValue.value;
|
|
126
133
|
}
|
|
127
134
|
});
|
|
135
|
+
effects.push(() => targetValue.effect.stop());
|
|
128
136
|
|
|
129
|
-
const bodyCell =
|
|
137
|
+
const bodyCell = globalComputed(() => {
|
|
130
138
|
const { node, plc } = optionGetter();
|
|
131
139
|
const bc = renderBodyCell({ node, plc, formEdit, targetValue: targetValue.value });
|
|
132
140
|
return () => bc;
|
|
133
141
|
});
|
|
142
|
+
effects.push(() => bodyCell.effect.stop());
|
|
134
143
|
|
|
135
144
|
return { bodyCell, targetValue };
|
|
136
145
|
}
|
|
@@ -7,6 +7,8 @@ import {PlainScroll} from "../../../Scroll";
|
|
|
7
7
|
import {Icon} from "../../../Icon";
|
|
8
8
|
import {renderHeadCell} from "../../plc/utils/plc.render";
|
|
9
9
|
import {useTooltip} from "../../../useTooltip";
|
|
10
|
+
import Tooltip from "../../../Tooltip";
|
|
11
|
+
import {getFunctionValue} from '@peryl/utils/getFunctionValue';
|
|
10
12
|
|
|
11
13
|
export const PltHeadCell = designComponent({
|
|
12
14
|
name: 'plt-head-cell',
|
|
@@ -77,6 +79,10 @@ export const PltHeadCell = designComponent({
|
|
|
77
79
|
onMouseLeave={handler.onLeave}
|
|
78
80
|
>
|
|
79
81
|
{content}
|
|
82
|
+
{!!props.tablePlc.props.tip && <Tooltip v-slots={{
|
|
83
|
+
default: () => <Icon icon="pi-info-circle" className="plt-head-cell-tip"/>,
|
|
84
|
+
popper: () => getFunctionValue(props.tablePlc.props.tip)
|
|
85
|
+
}}/>}
|
|
80
86
|
<span className="plt-head-cell-indicator" onMouseDown={resizeHandler.mousedown}/>
|
|
81
87
|
{sort.value != null && (
|
|
82
88
|
<div className={`plt-head-cell-sorter plt-head-cell-sorter-${sort.value ? 'desc' : 'asc'}`}>
|
|
@@ -53,10 +53,13 @@ export function useTableFormEditor(
|
|
|
53
53
|
* @author 韦胜健
|
|
54
54
|
* @date 2022/12/5 20:45
|
|
55
55
|
*/
|
|
56
|
+
const { effects: cellBodyArrayEffects } = createEffects();
|
|
57
|
+
effects.push(() => cellBodyArrayEffects.clear());
|
|
56
58
|
const cellBodyArray = computed(() => {
|
|
59
|
+
cellBodyArrayEffects.clear();
|
|
57
60
|
if (!state.optionGetter) {return [];}
|
|
58
61
|
const { node } = state.optionGetter();
|
|
59
|
-
return showPlcArray.value.map(plc => useCellValue({ optionGetter: () => ({ plc, node }), formEdit: true }));
|
|
62
|
+
return showPlcArray.value.map(plc => useCellValue({ optionGetter: () => ({ plc, node }), formEdit: true, effects: cellBodyArrayEffects }));
|
|
60
63
|
});
|
|
61
64
|
|
|
62
65
|
const handler = {
|
|
@@ -136,6 +139,7 @@ export function useTableFormEditor(
|
|
|
136
139
|
required={plc.props.required}
|
|
137
140
|
rules={plc.props.rules}
|
|
138
141
|
validator={plc.props.validator}
|
|
142
|
+
tip={plc.props.tip}
|
|
139
143
|
disabled={!editable}
|
|
140
144
|
{...validateAttrs}
|
|
141
145
|
>
|
|
@@ -3,7 +3,7 @@ import {iTableHooks} from "../utils/createTableHooks";
|
|
|
3
3
|
import {PlcValidatePropsOption, tPlc} from "../../plc/utils/plc.utils";
|
|
4
4
|
import {createEffects} from "@peryl/utils/createEffects";
|
|
5
5
|
import {PlainObject} from "@peryl/utils/event";
|
|
6
|
-
import {computed, reactive, RenderNode, useRefs} from "@peryl/react-compose";
|
|
6
|
+
import {computed, onBeforeUnmount, reactive, RenderNode, useRefs} from "@peryl/react-compose";
|
|
7
7
|
import {Dialog} from "../../../Dialog";
|
|
8
8
|
import {delay} from "@peryl/utils/delay";
|
|
9
9
|
import {Table} from "../Table";
|
|
@@ -64,11 +64,13 @@ export function useTableModifyEditor(
|
|
|
64
64
|
* @author 韦胜健
|
|
65
65
|
* @date 2022/12/5 20:45
|
|
66
66
|
*/
|
|
67
|
+
const { effects: cellBodyArrayEffects } = createEffects();
|
|
68
|
+
effects.push(() => cellBodyArrayEffects.clear());
|
|
67
69
|
const cellBodyArray = computed(() => {
|
|
68
70
|
if (!state.optionGetter) {return [];}
|
|
69
71
|
const { node } = state;
|
|
70
72
|
if (!node) {return [];}
|
|
71
|
-
return availablePlcList.value.map(i => useCellValue({ optionGetter: () => ({ plc: i.getPlc(), node }), formEdit: true }));
|
|
73
|
+
return availablePlcList.value.map(i => useCellValue({ optionGetter: () => ({ plc: i.getPlc(), node }), formEdit: true, effects: cellBodyArrayEffects }));
|
|
72
74
|
});
|
|
73
75
|
|
|
74
76
|
const handler = {
|
|
@@ -124,6 +126,7 @@ export function useTableModifyEditor(
|
|
|
124
126
|
required={plc.props.required}
|
|
125
127
|
rules={plc.props.rules}
|
|
126
128
|
validator={plc.props.validator}
|
|
129
|
+
tip={plc.props.tip}
|
|
127
130
|
disabled={!editable}
|
|
128
131
|
{...validateAttrs}
|
|
129
132
|
>
|
|
@@ -142,6 +145,7 @@ export function useTableModifyEditor(
|
|
|
142
145
|
initialize: (() => {
|
|
143
146
|
let hasInitialized = false;
|
|
144
147
|
return () => {
|
|
148
|
+
/*已经初始化过就不用再初始化了*/
|
|
145
149
|
if (hasInitialized) {return;}
|
|
146
150
|
hasInitialized = true;
|
|
147
151
|
effects.push(hooks.onRender.use(
|
|
@@ -187,6 +191,8 @@ export function useTableModifyEditor(
|
|
|
187
191
|
},
|
|
188
192
|
};
|
|
189
193
|
|
|
194
|
+
onBeforeUnmount(() => effects.clear());
|
|
195
|
+
|
|
190
196
|
return { methods, state };
|
|
191
197
|
}
|
|
192
198
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {createHooks, createRenderHook, createSyncHooks, iMouseEvent, RenderNode, StyleProperties} from "@peryl/react-compose";
|
|
2
|
-
import {tPlcType} from "../../plc/utils/plc.utils";
|
|
2
|
+
import {tPlc, tPlcType} from "../../plc/utils/plc.utils";
|
|
3
3
|
import {iTableMessyData, iTableNode} from "./table.utils";
|
|
4
4
|
import {PlainObject} from "@peryl/utils/event";
|
|
5
5
|
import {VirtualTable} from "../../../VirtualTable";
|
|
@@ -25,9 +25,11 @@ export const createTableHooks = () => {
|
|
|
25
25
|
/*双击行动作*/
|
|
26
26
|
onDblclickRow: createHooks<(data: { e: iMouseEvent, node: iTableNode }) => void>(),
|
|
27
27
|
/*单击单元格动作*/
|
|
28
|
-
onClickCell: createHooks<(data: { e: iMouseEvent, node: iTableNode, plc:
|
|
28
|
+
onClickCell: createHooks<(data: { e: iMouseEvent, node: iTableNode, plc: tPlc }) => void>(),
|
|
29
29
|
/*双击单元格动作*/
|
|
30
|
-
onDblclickCell: createHooks<(data: { e: iMouseEvent, node: iTableNode, plc:
|
|
30
|
+
onDblclickCell: createHooks<(data: { e: iMouseEvent, node: iTableNode, plc: tPlc }) => void>(),
|
|
31
|
+
/*右击单元格动作*/
|
|
32
|
+
onContextmenuCell: createHooks<(data: { e: iMouseEvent, node: iTableNode, plc: tPlc }) => void>(),
|
|
31
33
|
/*鼠标进入单元格*/
|
|
32
34
|
onEnterCell: createHooks<(data: { e: iMouseEvent, node: iTableNode, plc: tPlcType }) => void>(),
|
|
33
35
|
/*鼠标离开单元格*/
|
|
@@ -93,8 +93,9 @@ export const TableEmitsOptions = {
|
|
|
93
93
|
|
|
94
94
|
onClickRow: (node: iTableNode, e: iMouseEvent) => true,
|
|
95
95
|
onDblclickRow: (node: iTableNode, e: iMouseEvent) => true,
|
|
96
|
-
onClickCell: (node: iTableNode, e: iMouseEvent) => true,
|
|
97
|
-
onDblclickCell: (node: iTableNode, e: iMouseEvent) => true,
|
|
96
|
+
onClickCell: (node: iTableNode, e: iMouseEvent, plc: tPlc) => true,
|
|
97
|
+
onDblclickCell: (node: iTableNode, e: iMouseEvent, plc: tPlc) => true,
|
|
98
|
+
onContextmenuCell: (node: iTableNode, e: iMouseEvent, plc: tPlc) => true,
|
|
98
99
|
onClickHead: (plc: tPlcType, e: iMouseEvent) => true,
|
|
99
100
|
|
|
100
101
|
onConfigPlc: (data: { plcList: tPlcType[], stateData: tPlcCacheStateData }) => true,
|
|
@@ -7,6 +7,8 @@ import './virtual-table.scss';
|
|
|
7
7
|
import i18n from "../i18n";
|
|
8
8
|
import {doNothing} from "@peryl/utils/doNothing";
|
|
9
9
|
import {useWatchAutoClear} from "../../utils/watchEffectAutoClear";
|
|
10
|
+
import {useTableAutoSpan} from "../Table/plc/use/useTableAutoSpan";
|
|
11
|
+
import {iTableNode} from "../Table/table/utils/table.utils";
|
|
10
12
|
|
|
11
13
|
export const VirtualTable = designComponent({
|
|
12
14
|
name: 'virtual-table',
|
|
@@ -55,6 +57,8 @@ export const VirtualTable = designComponent({
|
|
|
55
57
|
/*虚拟滚动时让出顶部距离显示表头*/
|
|
56
58
|
const { virtual } = useVirtualList({ dataModel, props, refs: refs as any, emit, transform: false });
|
|
57
59
|
|
|
60
|
+
const tableAutoSpan = useTableAutoSpan(() => ({ data: virtual.offsetData.value.list.map(i => (i.item as iTableNode).data) }));
|
|
61
|
+
|
|
58
62
|
/*---------------------------------------computed-------------------------------------------*/
|
|
59
63
|
const styles = useStyles(style => {
|
|
60
64
|
style.height = unit(props.height);
|
|
@@ -154,6 +158,8 @@ export const VirtualTable = designComponent({
|
|
|
154
158
|
},
|
|
155
159
|
render: () => {
|
|
156
160
|
const { list } = virtual.offsetData.value;
|
|
161
|
+
/*触发响应式计算*/
|
|
162
|
+
doNothing(tableAutoSpan.value?.spans);
|
|
157
163
|
return (
|
|
158
164
|
<div style={styles.value} className={classes.value}>
|
|
159
165
|
<Scroll
|
|
@@ -81,19 +81,19 @@ $scrollbarSize: 12px;
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
&:hover {
|
|
84
|
-
td {
|
|
84
|
+
td:not([data-span=true]) {
|
|
85
85
|
background-color: plv(table-row-hover-color);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
&.plt-row-current {
|
|
90
|
-
td {
|
|
90
|
+
td:not([data-span=true]) {
|
|
91
91
|
background-color: plv(table-row-current-color);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
&.plt-row-checked {
|
|
96
|
-
td {
|
|
96
|
+
td:not([data-span=true]) {
|
|
97
97
|
background-color: plv(primary-light-1);
|
|
98
98
|
border-bottom-color: plv(primary-light-2);
|
|
99
99
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function createSimpleDate(_date?: Date) {
|
|
2
|
+
const date = _date || new Date();
|
|
3
|
+
const year = date.getFullYear();
|
|
4
|
+
const month = date.getMonth() + 1;
|
|
5
|
+
const day = date.getDate();
|
|
6
|
+
const hour = date.getHours();
|
|
7
|
+
const minute = date.getMinutes();
|
|
8
|
+
const second = date.getSeconds();
|
|
9
|
+
|
|
10
|
+
const YYYY = String(year);
|
|
11
|
+
const MM = String(month).padStart(2, '0');
|
|
12
|
+
const DD = String(day).padStart(2, '0');
|
|
13
|
+
const HH = String(hour).padStart(2, '0');
|
|
14
|
+
const mm = String(minute).padStart(2, '0');
|
|
15
|
+
const ss = String(second).padStart(2, '0');
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
'YYYY-MM-DD HH:mm:ss': `${YYYY}-${MM}-${DD} ${HH}:${mm}:${ss}`,
|
|
19
|
+
'YYYY-MM-DD': `${YYYY}-${MM}-${DD}`,
|
|
20
|
+
'HH:mm:ss': `${HH}:${mm}:${ss}`,
|
|
21
|
+
YMDHms: Number(`${YYYY}${MM}${DD}${HH}${mm}${ss}`),
|
|
22
|
+
YMD: Number(`${YYYY}${MM}${DD}`),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const parseDateString = (dateString: string): Date | null => {
|
|
27
|
+
const match = /(\d\d\d\d)-(\d\d)-(\d\d)/.exec(dateString);
|
|
28
|
+
if (!match) {return null;}
|
|
29
|
+
const year = Number(match[1]);
|
|
30
|
+
const month = Number(match[2]);
|
|
31
|
+
const date = Number(match[3]);
|
|
32
|
+
return new Date(year, month - 1, date);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const parseDatetimeString = (datetimeString: string) => {
|
|
36
|
+
const match = /(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)/.exec(datetimeString);
|
|
37
|
+
if (!match) {return null;}
|
|
38
|
+
const year = Number(match[1]);
|
|
39
|
+
const month = Number(match[2]);
|
|
40
|
+
const date = Number(match[3]);
|
|
41
|
+
const hour = Number(match[4]);
|
|
42
|
+
const minute = Number(match[5]);
|
|
43
|
+
const second = Number(match[6]);
|
|
44
|
+
return new Date(year, month - 1, date, hour, minute, second);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const nowDate = () => createSimpleDate()['YYYY-MM-DD'];
|
|
48
|
+
export const nowTime = () => createSimpleDate()['HH:mm:ss'];
|
|
49
|
+
export const nowDatetime = () => createSimpleDate()['YYYY-MM-DD HH:mm:ss'];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {usePopup} from "../usePopup";
|
|
2
|
+
import {ListPanel} from "../ListPanel";
|
|
3
|
+
import {ListOption} from "../ListOption";
|
|
4
|
+
import {iMouseEvent} from "@peryl/react-compose";
|
|
5
|
+
import {getFunctionValue} from "@peryl/utils/getFunctionValue";
|
|
6
|
+
|
|
7
|
+
export const useContextmenuOptions = () => {
|
|
8
|
+
|
|
9
|
+
const { $popup } = usePopup();
|
|
10
|
+
|
|
11
|
+
const open = ({ x, y ,options}: { x: number, y: number, options: iContextmenuOption[]}) => {
|
|
12
|
+
const pop = $popup.absolute({
|
|
13
|
+
x, y,
|
|
14
|
+
noArrow: true,
|
|
15
|
+
noPadding: true,
|
|
16
|
+
type: 'contextmenu-option',
|
|
17
|
+
placement: 'bottom-start',
|
|
18
|
+
trigger: 'contextmenu',
|
|
19
|
+
render: () => (
|
|
20
|
+
<ListPanel>
|
|
21
|
+
{options.map((option, index) => (
|
|
22
|
+
<ListOption key={index} label="管理该类型" onClick={async (e) => {
|
|
23
|
+
const flag = await option.handler(e);
|
|
24
|
+
if (flag != false) {pop.hide();}
|
|
25
|
+
}}>
|
|
26
|
+
{getFunctionValue(option.label)}
|
|
27
|
+
</ListOption>
|
|
28
|
+
))}
|
|
29
|
+
</ListPanel>
|
|
30
|
+
)
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return { open };
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export interface iContextmenuOption {
|
|
38
|
+
label: string | (() => any);
|
|
39
|
+
handler: (e: iMouseEvent) => void | boolean | Promise<void | boolean>,
|
|
40
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {TableOptionSpace} from "../AutoTable/utils/TableOption.space";
|
|
2
|
+
import {computed, reactive, RenderNode} from "@peryl/react-compose";
|
|
3
|
+
import {iFilterQueryParam} from "../FilterService/utils/filter.service.utils";
|
|
4
|
+
|
|
5
|
+
export function useTableFilter<T>(
|
|
6
|
+
{
|
|
7
|
+
modelValue,
|
|
8
|
+
option,
|
|
9
|
+
defaultValue,
|
|
10
|
+
display,
|
|
11
|
+
handleClickTip,
|
|
12
|
+
handleClear,
|
|
13
|
+
getQueryParam,
|
|
14
|
+
noClear,
|
|
15
|
+
}: {
|
|
16
|
+
option: TableOptionSpace.iTableOption,
|
|
17
|
+
display: (val: T) => RenderNode,
|
|
18
|
+
getQueryParam: (val: T) => iFilterQueryParam,
|
|
19
|
+
modelValue?: { set: (newVal: T | null) => void, get: () => T | null },
|
|
20
|
+
defaultValue?: T,
|
|
21
|
+
handleClickTip?: (val: T) => void,
|
|
22
|
+
handleClear?: (val: T) => void,
|
|
23
|
+
noClear?: boolean,
|
|
24
|
+
}) {
|
|
25
|
+
|
|
26
|
+
const model = (() => {
|
|
27
|
+
const _modelValue = modelValue || (() => {
|
|
28
|
+
const state = reactive({ value: defaultValue });
|
|
29
|
+
return { get: (): T | null => state.value as any, set: (newVal: T | null) => {state.value = newVal as any;} };
|
|
30
|
+
})();
|
|
31
|
+
return {
|
|
32
|
+
get: () => _modelValue.get(),
|
|
33
|
+
set: (newVal: T | null) => {_modelValue.set(newVal);}
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
|
|
37
|
+
const clear = (val: T) => {
|
|
38
|
+
if (noClear) {return;}
|
|
39
|
+
!!handleClear ? handleClear(val) : model.set(null);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const tips = computed((): TableOptionSpace.iTableOptionTipMeta | null => {
|
|
43
|
+
const val = model.get();
|
|
44
|
+
if (val == null) {return null;}
|
|
45
|
+
return {
|
|
46
|
+
noClear,
|
|
47
|
+
display: () => display(val),
|
|
48
|
+
onClear: () => {
|
|
49
|
+
clear(val);
|
|
50
|
+
reload();
|
|
51
|
+
},
|
|
52
|
+
onClick: () => {handleClickTip?.(val);},
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
option.hooks.onClearFilter.use(() => {
|
|
57
|
+
const val = model.get();
|
|
58
|
+
if (val == null) {return;}
|
|
59
|
+
clear(val);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
option.hooks.onTips.use((list) => {!!tips.value && list.unshift(tips.value);});
|
|
63
|
+
|
|
64
|
+
option.hooks.onQueryParam.use(async () => {
|
|
65
|
+
const val = model.get();
|
|
66
|
+
if (val == null) {return;}
|
|
67
|
+
return getQueryParam(val);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const reload = () => option.methods.pageMethods.reload();
|
|
71
|
+
|
|
72
|
+
return { model, reload };
|
|
73
|
+
}
|
package/src/packages/entry.tsx
CHANGED
|
@@ -16,6 +16,8 @@ export {useDialog} from "./components/useDialog";
|
|
|
16
16
|
export {$dialog} from "./components/$dialog";
|
|
17
17
|
export {List} from "./components/List";
|
|
18
18
|
// export {Item} from "./components/Item";
|
|
19
|
+
export {ListPanel} from './components/ListPanel';
|
|
20
|
+
export {ListOption} from './components/ListOption';
|
|
19
21
|
export {useMessage} from "./components/useMessage";
|
|
20
22
|
export {$message} from "./components/$message";
|
|
21
23
|
export {useNotice} from "./components/useNotice";
|
|
@@ -131,6 +133,8 @@ export {Paragraph} from './components/Paragraph';
|
|
|
131
133
|
export {ParagraphItem} from './components/ParagraphItem';
|
|
132
134
|
export {ImagePreviewer} from './components/ImagePreviewer/ImagePreviewer';
|
|
133
135
|
export {Corner} from './components/Corner';
|
|
136
|
+
export {useContextmenuOptions} from './components/useContextmenuOptions';
|
|
137
|
+
export type {iContextmenuOption} from './components/useContextmenuOptions';
|
|
134
138
|
|
|
135
139
|
export {VirtualTable} from './components/VirtualTable';
|
|
136
140
|
export {Table} from './components/Table';
|
|
@@ -284,6 +288,8 @@ export {createWebDraggier} from './components/createWebDraggier';
|
|
|
284
288
|
export {createScrollDraggier} from './components/createScrollDraggier';
|
|
285
289
|
export {loadFile} from './components/loadFile';
|
|
286
290
|
export {getDeviceInfo, clearDeviceInfo, eDeviceType} from './utils/getDeviceInfo';
|
|
291
|
+
export {useTableFilter} from './components/useTableFilter';
|
|
292
|
+
export {createSimpleDate} from './components/createSimpleDate';
|
|
287
293
|
|
|
288
294
|
// @ts-ignore
|
|
289
295
|
setComponentPrefix(globalComponentPrefix);
|