@cozeloop/components 0.0.3 → 0.0.4
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/package.json +9 -3
- package/.eslintcache +0 -1
- package/.rush/temp/shrinkwrap-deps.json +0 -770
- package/OWNERS +0 -5
- package/config/rush-project.json +0 -8
- package/eslint.config.js +0 -7
- package/rslib.config.js +0 -7
- package/script/publish.js +0 -146
- package/src/base-search-select/base-search-form-select.tsx +0 -10
- package/src/base-search-select/base-search-select.tsx +0 -200
- package/src/base-search-select/index.module.less +0 -16
- package/src/base-search-select/index.tsx +0 -3
- package/src/base-search-select/types.ts +0 -16
- package/src/base-search-select/utils.ts +0 -78
- package/src/basic-card/index.tsx +0 -23
- package/src/card-pane/index.module.less +0 -14
- package/src/card-pane/index.tsx +0 -25
- package/src/chip-select/index.module.less +0 -17
- package/src/chip-select/index.tsx +0 -7
- package/src/code-editor/index.tsx +0 -9
- package/src/code-usage/code-item.module.less +0 -32
- package/src/code-usage/index.tsx +0 -91
- package/src/codemirror-editor/code-editor.tsx +0 -139
- package/src/codemirror-editor/index.ts +0 -4
- package/src/codemirror-editor/json-editor.tsx +0 -183
- package/src/codemirror-editor/raw-text-editor.tsx +0 -68
- package/src/codemirror-editor/text-editor.tsx +0 -58
- package/src/codemirror-editor/themes/coze-dark.ts +0 -116
- package/src/codemirror-editor/themes/coze-light.ts +0 -122
- package/src/collapse-card/index.module.less +0 -27
- package/src/collapse-card/index.tsx +0 -93
- package/src/collapsible-card/index.module.less +0 -63
- package/src/collapsible-card/index.tsx +0 -57
- package/src/column-manage-storage/index.tsx +0 -64
- package/src/columns-select/index.tsx +0 -244
- package/src/edit-icon-button/index.tsx +0 -36
- package/src/footer-actions/index.tsx +0 -33
- package/src/hooks/use-infinite-scroll.ts +0 -183
- package/src/hooks/use-mouse-down-offset.ts +0 -50
- package/src/hooks/use-unsave-leave-warning.ts +0 -49
- package/src/id-render/icon-button-container.tsx +0 -37
- package/src/id-render/index.tsx +0 -64
- package/src/index-controller/record-navigation.tsx +0 -57
- package/src/index-controller/use-item-index-controller.ts +0 -197
- package/src/index.ts +0 -208
- package/src/infinite-scroll-table/index.tsx +0 -99
- package/src/info-tooltip/index.tsx +0 -41
- package/src/input-components/radio-button.tsx +0 -63
- package/src/input-slider/index.module.less +0 -30
- package/src/input-slider/index.tsx +0 -161
- package/src/input-with-count/index.tsx +0 -31
- package/src/jump-button/jump-icon-button.tsx +0 -12
- package/src/large-txt-render/index.tsx +0 -46
- package/src/layout/content.tsx +0 -28
- package/src/layout/header.tsx +0 -15
- package/src/layout/index.module.less +0 -28
- package/src/layout/index.tsx +0 -9
- package/src/layout/tabs.tsx +0 -11
- package/src/lazy-load-component/index.tsx +0 -55
- package/src/logic-editor/index.ts +0 -3
- package/src/logic-editor/logic-editor.module.less +0 -13
- package/src/logic-editor/logic-editor.tsx +0 -200
- package/src/logic-editor/logic-left-render.tsx +0 -100
- package/src/logic-editor/logic-operator-render.tsx +0 -54
- package/src/logic-editor/logic-right-render.tsx +0 -51
- package/src/logic-editor/logic-types.tsx +0 -238
- package/src/logic-editor/utils.ts +0 -22
- package/src/logic-expr/assets/select.svg +0 -1
- package/src/logic-expr/consts.ts +0 -6
- package/src/logic-expr/expr-group-render.tsx +0 -238
- package/src/logic-expr/expr-render.tsx +0 -226
- package/src/logic-expr/index.module.less +0 -252
- package/src/logic-expr/index.ts +0 -13
- package/src/logic-expr/logic-expr.tsx +0 -261
- package/src/logic-expr/logic-not.tsx +0 -46
- package/src/logic-expr/logic-toggle.tsx +0 -96
- package/src/logic-expr/types.ts +0 -95
- package/src/loop-radio-group/index.tsx +0 -16
- package/src/multi-part-editor/components/image-item-renderer.tsx +0 -134
- package/src/multi-part-editor/components/index.module.less +0 -21
- package/src/multi-part-editor/components/multipart-item-renderer.tsx +0 -74
- package/src/multi-part-editor/components/url-input-modal.tsx +0 -317
- package/src/multi-part-editor/components/video-item-renderer.tsx +0 -145
- package/src/multi-part-editor/index.module.less +0 -8
- package/src/multi-part-editor/index.tsx +0 -571
- package/src/multi-part-editor/multi-part-render.tsx +0 -87
- package/src/multi-part-editor/type.tsx +0 -103
- package/src/multi-part-editor/upload-button.tsx +0 -256
- package/src/multi-part-editor/utils.ts +0 -64
- package/src/open-detail-button/index.tsx +0 -30
- package/src/page-content/index.tsx +0 -99
- package/src/primary-page/index.tsx +0 -1
- package/src/primary-page/primary-header.tsx +0 -64
- package/src/primary-title/index.module.less +0 -14
- package/src/primary-title/index.tsx +0 -18
- package/src/provider/index.tsx +0 -89
- package/src/resizable-side-sheet/index.tsx +0 -69
- package/src/resize-sidesheet/index.module.less +0 -14
- package/src/resize-sidesheet/index.tsx +0 -68
- package/src/resize-sidesheet/use-drag.ts +0 -43
- package/src/schema-editor/index.tsx +0 -52
- package/src/search-form/index.tsx +0 -134
- package/src/semi-schema-form/components/tmpls/array-field-item.tsx +0 -97
- package/src/semi-schema-form/components/tmpls/array-field.tsx +0 -127
- package/src/semi-schema-form/components/tmpls/base-input.tsx +0 -126
- package/src/semi-schema-form/components/tmpls/description-field.tsx +0 -23
- package/src/semi-schema-form/components/tmpls/error-list.tsx +0 -44
- package/src/semi-schema-form/components/tmpls/field-error.tsx +0 -33
- package/src/semi-schema-form/components/tmpls/field.tsx +0 -54
- package/src/semi-schema-form/components/tmpls/icon-button.tsx +0 -112
- package/src/semi-schema-form/components/tmpls/index.ts +0 -39
- package/src/semi-schema-form/components/tmpls/object-field.tsx +0 -173
- package/src/semi-schema-form/components/tmpls/submit.tsx +0 -31
- package/src/semi-schema-form/components/tmpls/title-field.tsx +0 -30
- package/src/semi-schema-form/components/widgets/checkbox.tsx +0 -67
- package/src/semi-schema-form/components/widgets/checkboxs.tsx +0 -100
- package/src/semi-schema-form/components/widgets/index.ts +0 -17
- package/src/semi-schema-form/components/widgets/radio.tsx +0 -105
- package/src/semi-schema-form/components/widgets/range.tsx +0 -73
- package/src/semi-schema-form/components/widgets/select.tsx +0 -108
- package/src/semi-schema-form/components/widgets/textarea.tsx +0 -63
- package/src/semi-schema-form/index.tsx +0 -14
- package/src/sentinel-form/enum.ts +0 -16
- package/src/sentinel-form/index.tsx +0 -382
- package/src/step-nav/index.module.less +0 -45
- package/src/step-nav/index.tsx +0 -53
- package/src/table/index.module.less +0 -144
- package/src/table/index.tsx +0 -18
- package/src/table/sort-icon.tsx +0 -73
- package/src/table/table-with-pagination.tsx +0 -150
- package/src/table/table-without-pagniation.tsx +0 -66
- package/src/table-batch-operate/table-batch-operation.tsx +0 -47
- package/src/table-batch-operate/use-batch-operate.ts +0 -111
- package/src/table-col-actions/index.module.less +0 -8
- package/src/table-col-actions/index.tsx +0 -149
- package/src/table-cols-config/index.module.less +0 -34
- package/src/table-cols-config/index.tsx +0 -171
- package/src/table-cols-config/type.ts +0 -12
- package/src/table-cols-config/use-hidden-col-keys.ts +0 -53
- package/src/table-cols-config/util.ts +0 -56
- package/src/table-empty/index.tsx +0 -23
- package/src/table-header/index.module.less +0 -7
- package/src/table-header/index.tsx +0 -70
- package/src/tabs/index.module.less +0 -48
- package/src/tabs/index.tsx +0 -9
- package/src/text-area-pro/index.module.less +0 -5
- package/src/text-area-pro/index.tsx +0 -49
- package/src/text-with-copy/index.tsx +0 -95
- package/src/title-with-sub/index.tsx +0 -27
- package/src/tooltip-when-disabled/index.tsx +0 -23
- package/src/tooltip-with-disabled/index.tsx +0 -17
- package/src/types.d.ts +0 -24
- package/src/upload/index.ts +0 -39
- package/src/user-profile/index.tsx +0 -49
- package/src/utils/basic.ts +0 -29
- package/src/version-list/index.module.less +0 -16
- package/src/version-list/version-descriptions.tsx +0 -80
- package/src/version-list/version-item.tsx +0 -30
- package/src/version-list/version-list.tsx +0 -59
- package/src/version-list/version-switch-panel.tsx +0 -31
- package/tailwind.config.ts +0 -6
- package/tsconfig.build.json +0 -44
- package/tsconfig.json +0 -17
- package/tsconfig.misc.json +0 -28
- package/vitest.config.mts +0 -7
package/src/table/sort-icon.tsx
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { type SVGAttributes } from 'react';
|
|
2
|
-
|
|
3
|
-
import { Tooltip } from '@coze-arch/coze-design';
|
|
4
|
-
|
|
5
|
-
import { IconButtonContainer } from '../id-render/icon-button-container';
|
|
6
|
-
|
|
7
|
-
const activeColor = 'rgb(var(--coze-up-brand-9))';
|
|
8
|
-
const unActiveColor = 'var(--coz-fg-dim)';
|
|
9
|
-
|
|
10
|
-
export const IconSortArrow = ({
|
|
11
|
-
sortOrder,
|
|
12
|
-
...rest
|
|
13
|
-
}: {
|
|
14
|
-
sortOrder?: 'ascend' | 'descend' | boolean;
|
|
15
|
-
} & SVGAttributes<HTMLOrSVGElement>) => {
|
|
16
|
-
let descendColor = 'currentColor';
|
|
17
|
-
let ascendColor = 'currentColor';
|
|
18
|
-
if (sortOrder === 'descend') {
|
|
19
|
-
descendColor = activeColor;
|
|
20
|
-
ascendColor = unActiveColor;
|
|
21
|
-
} else if (sortOrder === 'ascend') {
|
|
22
|
-
descendColor = unActiveColor;
|
|
23
|
-
ascendColor = activeColor;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<svg
|
|
28
|
-
width="14"
|
|
29
|
-
height="14"
|
|
30
|
-
viewBox="0 0 24 24"
|
|
31
|
-
fill="currentColor"
|
|
32
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
33
|
-
{...rest}
|
|
34
|
-
>
|
|
35
|
-
<path
|
|
36
|
-
d="M7.00012 1.99976C7.55241 1.99976 8.00012 2.44747 8.00012 2.99976V17.2677L9.6341 14.4376C9.91024 13.9593 10.5218 13.7954 11.0001 14.0715C11.4784 14.3477 11.6423 14.9593 11.3661 15.4376L7.8758 21.483C7.85628 21.5183 7.83468 21.5523 7.81118 21.5849C7.72727 21.7015 7.62174 21.7953 7.50337 21.8641C7.38229 21.9347 7.24502 21.9807 7.09848 21.995C7.06439 21.9984 7.03007 22 6.99566 21.9999C6.64882 22.0011 6.31102 21.8217 6.12517 21.4998L2.62517 15.4376C2.34903 14.9593 2.5129 14.3477 2.99119 14.0715C3.46949 13.7954 4.08108 13.9593 4.35722 14.4376L6.00012 17.2832V2.99976C6.00012 2.44747 6.44784 1.99976 7.00012 1.99976Z"
|
|
37
|
-
fill={descendColor}
|
|
38
|
-
/>
|
|
39
|
-
<path
|
|
40
|
-
d="M17.001 21.9999C16.4487 21.9999 16.001 21.5522 16.001 20.9999L16.001 6.73198L14.367 9.5621C14.0909 10.0404 13.4793 10.2043 13.001 9.92813C12.5227 9.65199 12.3589 9.04039 12.635 8.5621L16.1253 2.51665C16.1449 2.48135 16.1665 2.44735 16.19 2.41482C16.2739 2.29823 16.3794 2.20436 16.4978 2.13559C16.6189 2.06494 16.7561 2.019 16.9027 2.0047C16.9368 2.0013 16.9711 1.99964 17.0055 1.99977C17.3523 1.99854 17.6901 2.17802 17.876 2.49993L21.376 8.5621C21.6521 9.0404 21.4882 9.65199 21.0099 9.92813C20.5317 10.2043 19.9201 10.0404 19.6439 9.5621L18.001 6.71652L18.001 20.9999C18.001 21.5522 17.5533 21.9999 17.001 21.9999Z"
|
|
41
|
-
fill={ascendColor}
|
|
42
|
-
/>
|
|
43
|
-
</svg>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
/** 表格排序专用图标 */
|
|
48
|
-
export default function LoopTableSortIcon({
|
|
49
|
-
sortOrder,
|
|
50
|
-
}: {
|
|
51
|
-
sortOrder?: 'ascend' | 'descend' | boolean;
|
|
52
|
-
}) {
|
|
53
|
-
let tooltip = '点击升序';
|
|
54
|
-
if (sortOrder === 'ascend') {
|
|
55
|
-
tooltip = '点击降序';
|
|
56
|
-
} else if (sortOrder === 'descend') {
|
|
57
|
-
tooltip = '点击恢复默认排序';
|
|
58
|
-
}
|
|
59
|
-
return (
|
|
60
|
-
<Tooltip theme="dark" content={tooltip}>
|
|
61
|
-
<div className="flex items-center">
|
|
62
|
-
<IconButtonContainer
|
|
63
|
-
icon={
|
|
64
|
-
<IconSortArrow
|
|
65
|
-
sortOrder={sortOrder}
|
|
66
|
-
className="text-[var(--coz-fg-secondary)]"
|
|
67
|
-
/>
|
|
68
|
-
}
|
|
69
|
-
/>
|
|
70
|
-
</div>
|
|
71
|
-
</Tooltip>
|
|
72
|
-
);
|
|
73
|
-
}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { useEffect, useMemo, useRef } from 'react';
|
|
2
|
-
|
|
3
|
-
import cls from 'classnames';
|
|
4
|
-
import {
|
|
5
|
-
type Params,
|
|
6
|
-
type PaginationResult,
|
|
7
|
-
} from 'ahooks/lib/usePagination/types';
|
|
8
|
-
import { useSize } from 'ahooks';
|
|
9
|
-
import { CozPagination, type TableProps } from '@coze-arch/coze-design';
|
|
10
|
-
|
|
11
|
-
import LoopTableSortIcon from './sort-icon';
|
|
12
|
-
import { LoopTable } from './index';
|
|
13
|
-
|
|
14
|
-
/** 获取本地存储的表格分页数量 */
|
|
15
|
-
export function getStoragePageSize(pageSizeStorageKey: string | undefined) {
|
|
16
|
-
if (!pageSizeStorageKey) {
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
19
|
-
const pageSize = localStorage.getItem(pageSizeStorageKey);
|
|
20
|
-
if (pageSize && !isNaN(Number(pageSize))) {
|
|
21
|
-
return Number(pageSize);
|
|
22
|
-
}
|
|
23
|
-
return undefined;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const PAGE_SIZE_OPTIONS = [10, 20, 50];
|
|
27
|
-
export const DEFAULT_PAGE_SIZE = 20;
|
|
28
|
-
|
|
29
|
-
export type TableWithPaginationProps<RecordItem> = TableProps & {
|
|
30
|
-
heightFull?: boolean;
|
|
31
|
-
service: Pick<
|
|
32
|
-
PaginationResult<{ total: number; list: RecordItem[] }, Params>,
|
|
33
|
-
'data' | 'pagination' | 'loading'
|
|
34
|
-
>;
|
|
35
|
-
pageSizeOpts?: number[];
|
|
36
|
-
header?: React.ReactNode;
|
|
37
|
-
/** 该参数将插入到分页器左侧,共同作为 footer 的一部分 */
|
|
38
|
-
footerWithPagination?: React.ReactNode;
|
|
39
|
-
pageSizeStorageKey?: string;
|
|
40
|
-
showSizeChanger?: boolean;
|
|
41
|
-
footerClassName?: string;
|
|
42
|
-
};
|
|
43
|
-
// eslint-disable-next-line complexity
|
|
44
|
-
export function TableWithPagination<RecordItem>(
|
|
45
|
-
props: TableWithPaginationProps<RecordItem>,
|
|
46
|
-
) {
|
|
47
|
-
const {
|
|
48
|
-
pageSizeOpts,
|
|
49
|
-
service,
|
|
50
|
-
header,
|
|
51
|
-
heightFull = false,
|
|
52
|
-
footerWithPagination,
|
|
53
|
-
pageSizeStorageKey,
|
|
54
|
-
showSizeChanger = true,
|
|
55
|
-
footerClassName,
|
|
56
|
-
className,
|
|
57
|
-
} = props;
|
|
58
|
-
const { columns } = props.tableProps ?? {};
|
|
59
|
-
const tableContainerRef = useRef<HTMLDivElement>(null);
|
|
60
|
-
const size = useSize(tableContainerRef.current);
|
|
61
|
-
const tableHeaderSize = useSize(
|
|
62
|
-
tableContainerRef.current?.querySelector('.semi-table-header'),
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
const tablePagination = useMemo(
|
|
66
|
-
() => ({
|
|
67
|
-
currentPage: service.pagination.current,
|
|
68
|
-
pageSize:
|
|
69
|
-
getStoragePageSize(pageSizeStorageKey) || service.pagination.pageSize,
|
|
70
|
-
total: Number(service.pagination.total),
|
|
71
|
-
onChange: (page: number, pageSize: number) => {
|
|
72
|
-
service.pagination.onChange(page, pageSize);
|
|
73
|
-
},
|
|
74
|
-
onPageSizeChange(newPageSize: number) {
|
|
75
|
-
if (pageSizeStorageKey) {
|
|
76
|
-
localStorage.setItem(pageSizeStorageKey, String(newPageSize));
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
showSizeChanger,
|
|
80
|
-
pageSizeOpts: pageSizeOpts ?? PAGE_SIZE_OPTIONS,
|
|
81
|
-
}),
|
|
82
|
-
[service.pagination, pageSizeOpts, pageSizeStorageKey, showSizeChanger],
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
useEffect(() => {
|
|
86
|
-
if (service.pagination.current > 1 && service?.data?.list?.length === 0) {
|
|
87
|
-
service.pagination.changeCurrent(1);
|
|
88
|
-
}
|
|
89
|
-
}, [service.pagination.current, service?.data?.list]);
|
|
90
|
-
|
|
91
|
-
const tableHeaderHeight = tableHeaderSize?.height ?? 56;
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
<div
|
|
95
|
-
className={cls('flex flex-col gap-3 w-full', className, {
|
|
96
|
-
'h-full flex overflow-hidden': heightFull,
|
|
97
|
-
})}
|
|
98
|
-
>
|
|
99
|
-
{header ? header : null}
|
|
100
|
-
<div
|
|
101
|
-
ref={tableContainerRef}
|
|
102
|
-
className={heightFull ? 'flex-1 overflow-hidden' : ''}
|
|
103
|
-
>
|
|
104
|
-
<LoopTable
|
|
105
|
-
{...props}
|
|
106
|
-
tableProps={{
|
|
107
|
-
empty: <></>,
|
|
108
|
-
...(props.tableProps ?? {}),
|
|
109
|
-
scroll: {
|
|
110
|
-
// 表格容器的高度减去表格头的高度
|
|
111
|
-
y:
|
|
112
|
-
size?.height === undefined || !heightFull
|
|
113
|
-
? undefined
|
|
114
|
-
: size.height - tableHeaderHeight - 2,
|
|
115
|
-
...(props.tableProps?.scroll ?? {}),
|
|
116
|
-
},
|
|
117
|
-
loading: service?.loading || props?.tableProps?.loading,
|
|
118
|
-
columns: columns
|
|
119
|
-
?.filter(
|
|
120
|
-
column => column.hidden !== true && column.checked !== false,
|
|
121
|
-
)
|
|
122
|
-
?.map(column => ({
|
|
123
|
-
...column,
|
|
124
|
-
...(column.sorter && !column.sortIcon
|
|
125
|
-
? { sortIcon: LoopTableSortIcon }
|
|
126
|
-
: {}),
|
|
127
|
-
})),
|
|
128
|
-
dataSource: service?.data?.list ?? [],
|
|
129
|
-
}}
|
|
130
|
-
/>
|
|
131
|
-
</div>
|
|
132
|
-
{service.pagination.current > 1 ||
|
|
133
|
-
(service?.data?.list?.length && service?.data?.list?.length > 0) ? (
|
|
134
|
-
<div
|
|
135
|
-
className={cls(
|
|
136
|
-
'shrink-0 flex flex-row-reverse justify-between items-center',
|
|
137
|
-
footerClassName,
|
|
138
|
-
)}
|
|
139
|
-
>
|
|
140
|
-
<CozPagination
|
|
141
|
-
{...tablePagination}
|
|
142
|
-
showTotal
|
|
143
|
-
showSizeChanger={true}
|
|
144
|
-
></CozPagination>
|
|
145
|
-
{footerWithPagination}
|
|
146
|
-
</div>
|
|
147
|
-
) : null}
|
|
148
|
-
</div>
|
|
149
|
-
);
|
|
150
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/* eslint-disable complexity */
|
|
2
|
-
import { useRef } from 'react';
|
|
3
|
-
|
|
4
|
-
import cls from 'classnames';
|
|
5
|
-
import { useSize } from 'ahooks';
|
|
6
|
-
import { type TableProps } from '@coze-arch/coze-design';
|
|
7
|
-
|
|
8
|
-
import LoopTableSortIcon from './sort-icon';
|
|
9
|
-
import { LoopTable } from './index';
|
|
10
|
-
|
|
11
|
-
export type TableWithoutPaginationProps = TableProps & {
|
|
12
|
-
heightFull?: boolean;
|
|
13
|
-
header?: React.ReactNode;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export function TableWithoutPagination(props: TableWithoutPaginationProps) {
|
|
17
|
-
const { header, heightFull = false, className } = props;
|
|
18
|
-
const { columns } = props.tableProps ?? {};
|
|
19
|
-
const tableContainerRef = useRef<HTMLDivElement>(null);
|
|
20
|
-
const size = useSize(tableContainerRef.current);
|
|
21
|
-
const tableHeaderSize = useSize(
|
|
22
|
-
tableContainerRef.current?.querySelector('.semi-table-header'),
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
const tableHeaderHeight = tableHeaderSize?.height ?? 56;
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<div
|
|
29
|
-
className={cls('flex flex-col gap-3 w-full', className, {
|
|
30
|
-
'h-full flex overflow-hidden': heightFull,
|
|
31
|
-
})}
|
|
32
|
-
>
|
|
33
|
-
{header ? header : null}
|
|
34
|
-
<div
|
|
35
|
-
ref={tableContainerRef}
|
|
36
|
-
className={heightFull ? 'flex-1 overflow-hidden' : ''}
|
|
37
|
-
>
|
|
38
|
-
<LoopTable
|
|
39
|
-
{...props}
|
|
40
|
-
tableProps={{
|
|
41
|
-
empty: <></>,
|
|
42
|
-
...(props.tableProps ?? {}),
|
|
43
|
-
scroll: {
|
|
44
|
-
// 表格容器的高度减去表格头的高度
|
|
45
|
-
y:
|
|
46
|
-
size?.height === undefined || !heightFull
|
|
47
|
-
? undefined
|
|
48
|
-
: size.height - tableHeaderHeight - 2,
|
|
49
|
-
...(props.tableProps?.scroll ?? {}),
|
|
50
|
-
},
|
|
51
|
-
columns: columns
|
|
52
|
-
?.filter(
|
|
53
|
-
column => column.hidden !== true && column.checked !== false,
|
|
54
|
-
)
|
|
55
|
-
?.map(column => ({
|
|
56
|
-
...column,
|
|
57
|
-
...(column.sorter && !column.sortIcon
|
|
58
|
-
? { sortIcon: LoopTableSortIcon }
|
|
59
|
-
: {}),
|
|
60
|
-
})),
|
|
61
|
-
}}
|
|
62
|
-
/>
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
);
|
|
66
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { Button } from '@coze-arch/coze-design';
|
|
2
|
-
|
|
3
|
-
import { type BatchOperateStore } from './use-batch-operate';
|
|
4
|
-
|
|
5
|
-
export interface BatchOperateProps<RecordItem> {
|
|
6
|
-
/** 批量操作接口 */
|
|
7
|
-
batchOperateStore: BatchOperateStore<RecordItem>;
|
|
8
|
-
/** 自定义批量操作按钮 */
|
|
9
|
-
actions?: React.ReactNode;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/** 表格批量操作 */
|
|
13
|
-
export function TableBatchOperate<RecordItem>({
|
|
14
|
-
actions,
|
|
15
|
-
batchOperateStore,
|
|
16
|
-
}: BatchOperateProps<RecordItem>) {
|
|
17
|
-
const {
|
|
18
|
-
selectedItems,
|
|
19
|
-
setSelectedItems,
|
|
20
|
-
enableBatchOperate,
|
|
21
|
-
setEnableBatchOperate,
|
|
22
|
-
} = batchOperateStore;
|
|
23
|
-
if (!enableBatchOperate) {
|
|
24
|
-
return (
|
|
25
|
-
<Button color="primary" onClick={() => setEnableBatchOperate?.(true)}>
|
|
26
|
-
批量选择
|
|
27
|
-
</Button>
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
return (
|
|
31
|
-
<div className="flex items-center gap-2">
|
|
32
|
-
<div className="text-xs">
|
|
33
|
-
已选 {selectedItems.length} 条数据
|
|
34
|
-
<span
|
|
35
|
-
className="ml-1 text-[rgb(var(--coze-up-brand-9))] cursor-pointer"
|
|
36
|
-
onClick={() => {
|
|
37
|
-
setSelectedItems([]);
|
|
38
|
-
setEnableBatchOperate?.(false);
|
|
39
|
-
}}
|
|
40
|
-
>
|
|
41
|
-
取消选择
|
|
42
|
-
</span>
|
|
43
|
-
</div>
|
|
44
|
-
{actions}
|
|
45
|
-
</div>
|
|
46
|
-
);
|
|
47
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/* eslint-disable security/detect-object-injection */
|
|
2
|
-
import { useMemo, useState } from 'react';
|
|
3
|
-
|
|
4
|
-
import { type RowSelection } from '@coze-arch/coze-design';
|
|
5
|
-
|
|
6
|
-
/** 计算数组元素的映射表 */
|
|
7
|
-
function arrayToMap<T>(array: T[], key: keyof T): Record<string, T> {
|
|
8
|
-
const map: Record<string, T> = {};
|
|
9
|
-
array.forEach(item => {
|
|
10
|
-
const mapKey = item[key as keyof T] as string;
|
|
11
|
-
if (mapKey !== undefined) {
|
|
12
|
-
const val = item;
|
|
13
|
-
map[mapKey] = val;
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
return map;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** 批量操作接口 */
|
|
20
|
-
export interface BatchOperateStore<RecordItem> {
|
|
21
|
-
/** 表格行选择器 */
|
|
22
|
-
rowSelection: RowSelection<RecordItem>;
|
|
23
|
-
/** 已选择的表格行记录数据 */
|
|
24
|
-
selectedItems: RecordItem[];
|
|
25
|
-
/** 设置已选择的表格行记录数据 */
|
|
26
|
-
setSelectedItems: (items: RecordItem[]) => void;
|
|
27
|
-
/** 批量操作状态 */
|
|
28
|
-
enableBatchOperate: boolean;
|
|
29
|
-
/** 设置批量操作状态 */
|
|
30
|
-
setEnableBatchOperate: (enable: boolean) => void;
|
|
31
|
-
/** 取消批量操作 */
|
|
32
|
-
onCancelBatchOperate: () => void;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** 批量操作配置 */
|
|
36
|
-
export interface BatchOperateOptions<RecordItem> {
|
|
37
|
-
/** 表格行记录数据的唯一ID字段,默认 `id` */
|
|
38
|
-
recordKey?: keyof RecordItem;
|
|
39
|
-
/** 最大可选数量,默认不限制 */
|
|
40
|
-
maxSelectionCount?: number;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* 表格批量操作状态管理。
|
|
45
|
-
* 支持跨分页选择数据。
|
|
46
|
-
* @param recordKey 表格行记录数据的唯一ID字段,默认 `id`
|
|
47
|
-
* @returns 批量操作接口
|
|
48
|
-
*/
|
|
49
|
-
export function useBatchOperate<RecordItem>({
|
|
50
|
-
recordKey = 'id' as keyof RecordItem,
|
|
51
|
-
maxSelectionCount,
|
|
52
|
-
}: BatchOperateOptions<RecordItem> = {}): BatchOperateStore<RecordItem> {
|
|
53
|
-
const [enableBatchOperate, setEnableBatchOperate] = useState(false);
|
|
54
|
-
const [selectedItems, setSelectedItems] = useState<RecordItem[]>([]);
|
|
55
|
-
|
|
56
|
-
const rowSelection = useMemo(() => {
|
|
57
|
-
// 是否开启最大可选数量限制
|
|
58
|
-
const hasMaxLimit =
|
|
59
|
-
typeof maxSelectionCount === 'number' && !Number.isNaN(maxSelectionCount);
|
|
60
|
-
// 选择数量是否达到最大数量
|
|
61
|
-
const isSelectionMaximum =
|
|
62
|
-
hasMaxLimit && selectedItems.length >= maxSelectionCount;
|
|
63
|
-
// 表格行选择器配置
|
|
64
|
-
const newRowSelection: RowSelection<RecordItem> = {
|
|
65
|
-
// 禁用表格列标题处的checkbox
|
|
66
|
-
disabled: hasMaxLimit && selectedItems.length >= maxSelectionCount,
|
|
67
|
-
// 隐藏表格行选择器
|
|
68
|
-
hidden: !enableBatchOperate,
|
|
69
|
-
// 已选择的表格行记录数据的唯一ID字段值数组
|
|
70
|
-
selectedRowKeys: selectedItems?.map(item => item[recordKey] as string),
|
|
71
|
-
// 表格行选择器变化事件
|
|
72
|
-
onChange(newKeys = [], rows = []) {
|
|
73
|
-
const map = arrayToMap<RecordItem>(
|
|
74
|
-
[...rows, ...selectedItems],
|
|
75
|
-
recordKey,
|
|
76
|
-
);
|
|
77
|
-
const newSelectKeys = hasMaxLimit
|
|
78
|
-
? newKeys.slice(0, maxSelectionCount)
|
|
79
|
-
: newKeys;
|
|
80
|
-
const newSelectedItems = newSelectKeys
|
|
81
|
-
.map(key => map[key])
|
|
82
|
-
.filter(Boolean);
|
|
83
|
-
setSelectedItems(newSelectedItems as RecordItem[]);
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
// 表格行选择器获取checkbox属性事件, 超出最大选中数量时禁用所有未选项
|
|
87
|
-
if (hasMaxLimit) {
|
|
88
|
-
const selectedKeyMap = new Map(
|
|
89
|
-
selectedItems.map(item => [item[recordKey], item]),
|
|
90
|
-
);
|
|
91
|
-
newRowSelection.getCheckboxProps = (record: RecordItem) => ({
|
|
92
|
-
disabled: isSelectionMaximum && !selectedKeyMap.has(record[recordKey]),
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
return newRowSelection;
|
|
96
|
-
}, [enableBatchOperate, selectedItems, maxSelectionCount, recordKey]);
|
|
97
|
-
|
|
98
|
-
const onCancelBatchOperate = () => {
|
|
99
|
-
setEnableBatchOperate(false);
|
|
100
|
-
setSelectedItems([]);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
enableBatchOperate,
|
|
105
|
-
selectedItems,
|
|
106
|
-
setEnableBatchOperate,
|
|
107
|
-
onCancelBatchOperate,
|
|
108
|
-
setSelectedItems,
|
|
109
|
-
rowSelection,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { useState, type ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
import classNames from 'classnames';
|
|
4
|
-
import { IconCozMore } from '@coze-arch/coze-design/icons';
|
|
5
|
-
import {
|
|
6
|
-
Space,
|
|
7
|
-
type SpaceProps,
|
|
8
|
-
type TypographyProps,
|
|
9
|
-
Typography,
|
|
10
|
-
Menu,
|
|
11
|
-
} from '@coze-arch/coze-design';
|
|
12
|
-
|
|
13
|
-
import { TooltipWhenDisabled } from '../tooltip-when-disabled';
|
|
14
|
-
|
|
15
|
-
import styles from './index.module.less';
|
|
16
|
-
|
|
17
|
-
export interface TableColAction {
|
|
18
|
-
label: ReactNode;
|
|
19
|
-
icon?: ReactNode;
|
|
20
|
-
disabled?: boolean;
|
|
21
|
-
hide?: boolean;
|
|
22
|
-
type?: TypographyProps['type'];
|
|
23
|
-
disabledTooltip?: string;
|
|
24
|
-
onClick?: () => void;
|
|
25
|
-
tooltip?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface Props {
|
|
29
|
-
actions: TableColAction[];
|
|
30
|
-
maxCount?: number;
|
|
31
|
-
disabled?: boolean;
|
|
32
|
-
spaceProps?: SpaceProps;
|
|
33
|
-
wrapperClassName?: string;
|
|
34
|
-
textClassName?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function TableColActions({
|
|
38
|
-
actions,
|
|
39
|
-
maxCount = 2,
|
|
40
|
-
disabled,
|
|
41
|
-
spaceProps = {},
|
|
42
|
-
wrapperClassName = '',
|
|
43
|
-
textClassName = '',
|
|
44
|
-
}: Props) {
|
|
45
|
-
const [visible, setVisible] = useState(false);
|
|
46
|
-
const filteredActions = actions.filter(action => !action.hide);
|
|
47
|
-
const firstActions = filteredActions.slice(0, maxCount);
|
|
48
|
-
const moreActions = filteredActions.slice(maxCount);
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<div
|
|
52
|
-
className={wrapperClassName}
|
|
53
|
-
onClick={e => {
|
|
54
|
-
e.stopPropagation();
|
|
55
|
-
}}
|
|
56
|
-
>
|
|
57
|
-
<Space spacing={12} {...spaceProps}>
|
|
58
|
-
{firstActions.map((action, index) => (
|
|
59
|
-
<TooltipWhenDisabled
|
|
60
|
-
key={index}
|
|
61
|
-
content={action.disabledTooltip || action.label}
|
|
62
|
-
disabled={Boolean(action.disabled)}
|
|
63
|
-
needWrap={false}
|
|
64
|
-
>
|
|
65
|
-
<Typography.Text
|
|
66
|
-
size="small"
|
|
67
|
-
className={classNames(`!text-[13px] ${textClassName}`, {
|
|
68
|
-
'opacity-45': action.disabled ?? disabled,
|
|
69
|
-
})}
|
|
70
|
-
type={action.type}
|
|
71
|
-
disabled={action.disabled ?? disabled}
|
|
72
|
-
onClick={() => {
|
|
73
|
-
if (!(action.disabled ?? disabled)) {
|
|
74
|
-
action.onClick?.();
|
|
75
|
-
}
|
|
76
|
-
}}
|
|
77
|
-
link={!action.type}
|
|
78
|
-
>
|
|
79
|
-
{action.icon ? null : action.label}
|
|
80
|
-
</Typography.Text>
|
|
81
|
-
</TooltipWhenDisabled>
|
|
82
|
-
))}
|
|
83
|
-
{moreActions.length > 0 && (
|
|
84
|
-
<Menu
|
|
85
|
-
position="bottomLeft"
|
|
86
|
-
visible={visible}
|
|
87
|
-
trigger="custom"
|
|
88
|
-
className={styles.tableColActionsDropdown}
|
|
89
|
-
onClickOutSide={() => setVisible(false)}
|
|
90
|
-
render={
|
|
91
|
-
<Menu.SubMenu mode="menu">
|
|
92
|
-
{moreActions.map((action, index) => {
|
|
93
|
-
const isDisabled = action.disabled ?? disabled;
|
|
94
|
-
const disabledTooltipContent = action.disabledTooltip;
|
|
95
|
-
|
|
96
|
-
const dropdownItem = (
|
|
97
|
-
<Menu.Item
|
|
98
|
-
disabled={isDisabled}
|
|
99
|
-
onClick={() => {
|
|
100
|
-
if (!isDisabled) {
|
|
101
|
-
setVisible(false);
|
|
102
|
-
action.onClick?.();
|
|
103
|
-
}
|
|
104
|
-
}}
|
|
105
|
-
className={classNames('min-w-[90px] !p-0 !pl-2', {
|
|
106
|
-
'opacity-50': isDisabled,
|
|
107
|
-
})}
|
|
108
|
-
icon={action.icon}
|
|
109
|
-
style={{ minWidth: '90px' }}
|
|
110
|
-
>
|
|
111
|
-
<Typography.Text
|
|
112
|
-
type={action.type}
|
|
113
|
-
size="small"
|
|
114
|
-
className="!text-[13px] min-w-[80px]"
|
|
115
|
-
link={!action.type}
|
|
116
|
-
>
|
|
117
|
-
{action.label}
|
|
118
|
-
</Typography.Text>
|
|
119
|
-
</Menu.Item>
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
return (
|
|
123
|
-
<div key={index}>
|
|
124
|
-
<TooltipWhenDisabled
|
|
125
|
-
content={disabledTooltipContent}
|
|
126
|
-
disabled={Boolean(isDisabled && disabledTooltipContent)}
|
|
127
|
-
theme="dark"
|
|
128
|
-
needWrap={false}
|
|
129
|
-
>
|
|
130
|
-
{dropdownItem}
|
|
131
|
-
</TooltipWhenDisabled>
|
|
132
|
-
</div>
|
|
133
|
-
);
|
|
134
|
-
})}
|
|
135
|
-
</Menu.SubMenu>
|
|
136
|
-
}
|
|
137
|
-
>
|
|
138
|
-
<div
|
|
139
|
-
className="flex items-center justify-center"
|
|
140
|
-
onClick={() => setVisible(true)}
|
|
141
|
-
>
|
|
142
|
-
<IconCozMore className="text-[#5A4DED]" />
|
|
143
|
-
</div>
|
|
144
|
-
</Menu>
|
|
145
|
-
)}
|
|
146
|
-
</Space>
|
|
147
|
-
</div>
|
|
148
|
-
);
|
|
149
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
.row {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: row;
|
|
4
|
-
align-items: center;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.row-border {
|
|
8
|
-
border-top: 1px solid var(--semi-color-border);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.cell-thead {
|
|
12
|
-
color: var(--semi-color-text-2);
|
|
13
|
-
background-color: var(--fornax-table-header-color);
|
|
14
|
-
border: 1px solid white;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.cell {
|
|
18
|
-
padding: 8px 12px;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.cell-left {
|
|
22
|
-
width: 0;
|
|
23
|
-
flex-grow: 1;
|
|
24
|
-
flex-shrink: 1;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.cell-right {
|
|
28
|
-
width: 70px;
|
|
29
|
-
flex-grow: 0;
|
|
30
|
-
flex-shrink: 0;
|
|
31
|
-
display: flex;
|
|
32
|
-
align-items: center;
|
|
33
|
-
box-sizing: border-box;
|
|
34
|
-
}
|