@zjlab-fe/data-hub-ui 0.31.1 → 0.32.0

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.
@@ -0,0 +1,7 @@
1
+ import type { TableRowAction } from './types';
2
+ type ActionCellProps<T> = {
3
+ record: T;
4
+ actions: TableRowAction<T>[];
5
+ };
6
+ export default function ActionCell<T>({ record, actions }: ActionCellProps<T>): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1 @@
1
+ export default function Demo(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,45 @@
1
+ import type { FilterValue } from 'antd/es/table/interface';
2
+ import type { DocumentRecord, DocumentStatus } from './mockData';
3
+ export type ListQueryParams = {
4
+ current: number;
5
+ pageSize: number;
6
+ sorter?: {
7
+ field: string;
8
+ order: 'ascend' | 'descend';
9
+ } | null;
10
+ filters?: Record<string, FilterValue | null>;
11
+ keyword?: string;
12
+ };
13
+ export type ListQueryResult = {
14
+ list: DocumentRecord[];
15
+ total: number;
16
+ };
17
+ export type CreateDocumentInput = {
18
+ name: string;
19
+ status?: DocumentStatus;
20
+ modelVersion?: string;
21
+ };
22
+ export type UpdateDocumentInput = {
23
+ id: string;
24
+ name?: string;
25
+ status?: DocumentStatus;
26
+ modelVersion?: string;
27
+ };
28
+ /** 列表查询:筛选 → 关键词 → 排序 → 分页 */
29
+ export declare function listDocuments(params: ListQueryParams): Promise<ListQueryResult>;
30
+ /** 新增 */
31
+ export declare function createDocument(input: CreateDocumentInput): Promise<DocumentRecord>;
32
+ /** 更新 */
33
+ export declare function updateDocument(input: UpdateDocumentInput): Promise<DocumentRecord>;
34
+ /** 删除 */
35
+ export declare function deleteDocument(id: string): Promise<{
36
+ id: string;
37
+ }>;
38
+ /** 批量删除 */
39
+ export declare function deleteDocuments(ids: string[]): Promise<{
40
+ ids: string[];
41
+ }>;
42
+ /** Demo 重置内存库(便于反复演示) */
43
+ export declare function resetDocuments(): Promise<{
44
+ total: number;
45
+ }>;
@@ -0,0 +1,13 @@
1
+ export type DocumentStatus = 'parsing' | 'parsed' | 'failed';
2
+ export type DocumentRecord = {
3
+ id: string;
4
+ docNo: string;
5
+ name: string;
6
+ status: DocumentStatus;
7
+ updatedAt: string;
8
+ modelVersion: string;
9
+ };
10
+ export declare const statusLabelMap: Record<DocumentStatus, string>;
11
+ export declare const statusTypeMap: Record<DocumentStatus, 'running' | 'success' | 'failed'>;
12
+ /** 初始种子数据(只读);运行时 CRUD 在 mockApi 的内存库中进行 */
13
+ export declare const seedDocuments: DocumentRecord[];
@@ -0,0 +1,4 @@
1
+ import type { DataTableProps } from './types';
2
+ declare function DataTable<T extends object>(props: DataTableProps<T>): import("react/jsx-runtime").JSX.Element;
3
+ export default DataTable;
4
+ export type { DataTableColumn, DataTableProps, RowSelectionConfig, RowTextExpandConfig, TableRowAction, } from './types';
@@ -0,0 +1,60 @@
1
+ import type { TableProps } from 'antd';
2
+ import type { ColumnType } from 'antd/es/table';
3
+ import type { Key, ReactNode } from 'react';
4
+ export type TableRowAction<T> = {
5
+ key: string;
6
+ label: string;
7
+ onClick: (record: T) => void;
8
+ disabled?: boolean | ((record: T) => boolean);
9
+ visible?: boolean | ((record: T) => boolean);
10
+ render?: (record: T) => ReactNode;
11
+ };
12
+ export type RowSelectionConfig<T> = {
13
+ selectedRowKeys?: Key[];
14
+ onChange: (keys: Key[], rows: T[]) => void;
15
+ preserveSelectedRowKeys?: boolean;
16
+ };
17
+ /** 列定义;ellipsisExpand / showTitleOnHover 为列级可选能力 */
18
+ export type DataTableColumn<T> = ColumnType<T> & {
19
+ /** 该列参与行点击展开截断(需同时开启 rowTextExpand) */
20
+ ellipsisExpand?: boolean;
21
+ /**
22
+ * hover 时用原生 title 展示单元格文本。
23
+ * 仅对无自定义 render 的列生效;有 render 时由外部自行处理。
24
+ */
25
+ showTitleOnHover?: boolean;
26
+ };
27
+ /** 行文本展开配置;不传或 false 时关闭 */
28
+ export type RowTextExpandConfig = {
29
+ /** 是否允许多行同时展开;默认 true */
30
+ multiple?: boolean;
31
+ /** 展开后最大高度(px);默认 200 */
32
+ expandedMaxHeight?: number;
33
+ };
34
+ export type DataTableProps<T extends object> = {
35
+ rowKey: string | ((record: T) => Key);
36
+ columns: DataTableColumn<T>[];
37
+ actions?: TableRowAction<T>[] | null;
38
+ actionColumnTitle?: string;
39
+ actionColumnWidth?: number;
40
+ dataSource?: T[];
41
+ loading?: boolean;
42
+ pagination?: {
43
+ current: number;
44
+ pageSize: number;
45
+ total: number;
46
+ } | false;
47
+ onChange?: TableProps<T>['onChange'];
48
+ rowSelection?: RowSelectionConfig<T>;
49
+ defaultPageSize?: number;
50
+ showSizeChanger?: boolean;
51
+ showQuickJumper?: boolean;
52
+ className?: string;
53
+ /** 表格最小宽度;小于该宽度时横向滚动。默认 920 */
54
+ minWidth?: number | string;
55
+ /**
56
+ * 点击行展开标记了 ellipsisExpand 的列文本。
57
+ * 默认关闭;传 true 或配置对象开启。
58
+ */
59
+ rowTextExpand?: boolean | RowTextExpandConfig;
60
+ };
@@ -38,6 +38,8 @@ export { default as CorpusCard } from './components/corpus-card';
38
38
  export { default as ModelCard } from './components/model-card';
39
39
  export type { ModelCardProps } from './components/model-card';
40
40
  export type { CorpusCardProps, ProcessTemplateListItem, ProcessTemplateLabel, LabelTypeColor, } from './components/corpus-card';
41
+ export { default as DataTable } from './components/data-table';
42
+ export type { DataTableProps, DataTableColumn, TableRowAction, RowSelectionConfig, RowTextExpandConfig, } from './components/data-table';
41
43
  export { default as SDKModal } from './components/SDK-modal';
42
44
  export { default as TagView } from './components/tag-view';
43
45
  export { default as TagGroupFilter } from './components/tag-group-filter';
@@ -0,0 +1,33 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { Button } from 'antd';
3
+ import { dataTableActionCell, dataTableActionDivider, dataTableActionLink } from './action-cell.module.scss.js';
4
+
5
+ function resolveDisabled(disabled, record) {
6
+ if (disabled === undefined) {
7
+ return false;
8
+ }
9
+ if (typeof disabled === 'boolean') {
10
+ return disabled;
11
+ }
12
+ return disabled(record);
13
+ }
14
+ function resolveVisible(visible, record) {
15
+ if (visible === undefined) {
16
+ return true;
17
+ }
18
+ if (typeof visible === 'boolean') {
19
+ return visible;
20
+ }
21
+ return visible(record);
22
+ }
23
+ function ActionCell({ record, actions }) {
24
+ const visibleActions = actions.filter((action) => resolveVisible(action.visible, record));
25
+ return (jsx("div", { className: dataTableActionCell, onClick: (event) => {
26
+ event.stopPropagation();
27
+ }, children: visibleActions.map((action, index) => (jsxs("span", { children: [index > 0 ? jsx("span", { className: dataTableActionDivider }) : null, action.render ? (action.render(record)) : (jsx(Button, { type: "link", className: dataTableActionLink, disabled: resolveDisabled(action.disabled, record), onClick: (event) => {
28
+ event.stopPropagation();
29
+ action.onClick(record);
30
+ }, children: action.label }))] }, action.key))) }));
31
+ }
32
+
33
+ export { ActionCell as default };
@@ -0,0 +1,29 @@
1
+ var style = document.createElement('style');
2
+ style.textContent = `.action-cell-module__dataTableActionCell___pjPHA {
3
+ display: flex;
4
+ align-items: center;
5
+ white-space: nowrap;
6
+ }
7
+
8
+ .action-cell-module__dataTableActionDivider___WBN1r {
9
+ display: inline-block;
10
+ width: 1px;
11
+ height: 12px;
12
+ margin: 0 8px;
13
+ background: rgba(0, 0, 0, 0.06);
14
+ vertical-align: middle;
15
+ }
16
+
17
+ .action-cell-module__dataTableActionLink___4upQI {
18
+ padding: 0;
19
+ height: 22px;
20
+ line-height: 22px;
21
+ font-size: 14px;
22
+ color: #1775fe;
23
+ }`;
24
+ document.head.appendChild(style);
25
+
26
+ var dataTableActionCell = "action-cell-module__dataTableActionCell___pjPHA";var dataTableActionDivider = "action-cell-module__dataTableActionDivider___WBN1r";var dataTableActionLink = "action-cell-module__dataTableActionLink___4upQI";
27
+ var styles = {"dataTableActionCell":"action-cell-module__dataTableActionCell___pjPHA","dataTableActionDivider":"action-cell-module__dataTableActionDivider___WBN1r","dataTableActionLink":"action-cell-module__dataTableActionLink___4upQI"};
28
+
29
+ export { dataTableActionCell, dataTableActionDivider, dataTableActionLink, styles as default };
@@ -0,0 +1,166 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import React from 'react';
3
+ import { Table, Empty } from 'antd';
4
+ import ActionCell from './action-cell.js';
5
+ import { dataTable, dataTableRowClickable, truncateText, truncateTextExpanded } from './index.module.scss.js';
6
+
7
+ const DEFAULT_MIN_WIDTH = 920;
8
+ const DEFAULT_EXPAND_MAX_HEIGHT = 200;
9
+ function resolveRowKey(rowKey, record) {
10
+ if (typeof rowKey === 'function') {
11
+ return rowKey(record);
12
+ }
13
+ return record[rowKey];
14
+ }
15
+ function formatCssSize(value) {
16
+ return typeof value === 'number' ? `${value}px` : value;
17
+ }
18
+ function isInteractiveRowClickTarget(target) {
19
+ if (!(target instanceof Element)) {
20
+ return false;
21
+ }
22
+ return Boolean(target.closest('.ant-checkbox-wrapper, .ant-table-selection-column, button, a, .ant-btn, input, textarea, select'));
23
+ }
24
+ function isRenderedCell(content) {
25
+ return (Boolean(content) &&
26
+ typeof content === 'object' &&
27
+ !React.isValidElement(content) &&
28
+ ('props' in content || 'children' in content));
29
+ }
30
+ function toTitleText(value) {
31
+ if (value === null || value === undefined) {
32
+ return undefined;
33
+ }
34
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
35
+ return String(value);
36
+ }
37
+ return undefined;
38
+ }
39
+ function TruncateText({ content, expanded, title, }) {
40
+ const textRef = React.useRef(null);
41
+ React.useLayoutEffect(() => {
42
+ if (!expanded && textRef.current) {
43
+ textRef.current.scrollTop = 0;
44
+ }
45
+ }, [expanded]);
46
+ return (jsx("div", { ref: textRef, title: title, className: [truncateText, expanded ? truncateTextExpanded : ''].filter(Boolean).join(' '), children: content }));
47
+ }
48
+ function DataTable(props) {
49
+ var _a, _b;
50
+ const { rowKey, columns, actions, actionColumnTitle = '操作', actionColumnWidth = 188, dataSource, loading = false, pagination: controlledPagination, onChange, rowSelection, defaultPageSize = 10, showSizeChanger = false, showQuickJumper = true, className, minWidth = DEFAULT_MIN_WIDTH, rowTextExpand, } = props;
51
+ const expandEnabled = Boolean(rowTextExpand);
52
+ const expandMultiple = typeof rowTextExpand === 'object' ? ((_a = rowTextExpand.multiple) !== null && _a !== void 0 ? _a : true) : true;
53
+ const expandMaxHeight = typeof rowTextExpand === 'object'
54
+ ? ((_b = rowTextExpand.expandedMaxHeight) !== null && _b !== void 0 ? _b : DEFAULT_EXPAND_MAX_HEIGHT)
55
+ : DEFAULT_EXPAND_MAX_HEIGHT;
56
+ const [expandedRowKeys, setExpandedRowKeys] = React.useState([]);
57
+ const toggleRowExpand = (record) => {
58
+ if (!expandEnabled) {
59
+ return;
60
+ }
61
+ const key = resolveRowKey(rowKey, record);
62
+ setExpandedRowKeys((prev) => {
63
+ const isExpanded = prev.includes(key);
64
+ if (isExpanded) {
65
+ return prev.filter((item) => item !== key);
66
+ }
67
+ if (expandMultiple) {
68
+ return [...prev, key];
69
+ }
70
+ return [key];
71
+ });
72
+ };
73
+ const mergedColumns = React.useMemo(() => {
74
+ const enhancedColumns = columns.map((column) => {
75
+ const needsTruncate = expandEnabled && Boolean(column.ellipsisExpand);
76
+ const needsTitle = Boolean(column.showTitleOnHover) && !column.render;
77
+ if (!needsTruncate && !needsTitle) {
78
+ return column;
79
+ }
80
+ const originalRender = column.render;
81
+ return Object.assign(Object.assign({}, column), { render: (value, record, index) => {
82
+ var _a;
83
+ const rendered = originalRender ? originalRender(value, record, index) : value;
84
+ const titleText = needsTitle ? toTitleText(value) : undefined;
85
+ const wrapContent = (node) => {
86
+ if (needsTruncate) {
87
+ const key = resolveRowKey(rowKey, record);
88
+ const expanded = expandedRowKeys.includes(key);
89
+ return jsx(TruncateText, { content: node, expanded: expanded, title: titleText });
90
+ }
91
+ if (titleText !== undefined) {
92
+ return jsx("span", { title: titleText, children: node });
93
+ }
94
+ return node;
95
+ };
96
+ if (isRenderedCell(rendered)) {
97
+ return Object.assign(Object.assign({}, rendered), { children: wrapContent((_a = rendered.children) !== null && _a !== void 0 ? _a : null) });
98
+ }
99
+ return wrapContent(rendered);
100
+ } });
101
+ });
102
+ if (actions === null || !actions || actions.length === 0) {
103
+ return enhancedColumns;
104
+ }
105
+ return [
106
+ ...enhancedColumns,
107
+ {
108
+ key: '__actions__',
109
+ title: actionColumnTitle,
110
+ width: actionColumnWidth,
111
+ render: (_, record) => jsx(ActionCell, { record: record, actions: actions }),
112
+ },
113
+ ];
114
+ }, [actions, actionColumnTitle, actionColumnWidth, columns, expandEnabled, expandedRowKeys, rowKey]);
115
+ const resolvedRowSelection = React.useMemo(() => {
116
+ var _a;
117
+ if (!rowSelection) {
118
+ return undefined;
119
+ }
120
+ return {
121
+ selectedRowKeys: rowSelection.selectedRowKeys,
122
+ preserveSelectedRowKeys: (_a = rowSelection.preserveSelectedRowKeys) !== null && _a !== void 0 ? _a : true,
123
+ onChange: rowSelection.onChange,
124
+ columnWidth: '40px',
125
+ };
126
+ }, [rowSelection]);
127
+ const paginationConfig = React.useMemo(() => {
128
+ if (controlledPagination === false) {
129
+ return false;
130
+ }
131
+ if (controlledPagination) {
132
+ return Object.assign(Object.assign({}, controlledPagination), { showSizeChanger,
133
+ showQuickJumper });
134
+ }
135
+ return {
136
+ defaultPageSize,
137
+ showSizeChanger,
138
+ showQuickJumper,
139
+ };
140
+ }, [controlledPagination, defaultPageSize, showSizeChanger, showQuickJumper]);
141
+ const handleTableChange = (...args) => {
142
+ onChange === null || onChange === void 0 ? void 0 : onChange(...args);
143
+ };
144
+ const tableClassName = [dataTable, expandEnabled ? dataTableRowClickable : '', className]
145
+ .filter(Boolean)
146
+ .join(' ');
147
+ const tableStyle = Object.assign({ ['--data-table-min-width']: formatCssSize(minWidth) }, (expandEnabled
148
+ ? {
149
+ ['--data-table-expand-max-height']: formatCssSize(expandMaxHeight),
150
+ }
151
+ : {}));
152
+ return (jsx(Table, { className: tableClassName, style: tableStyle, rowKey: rowKey, columns: mergedColumns, dataSource: dataSource !== null && dataSource !== void 0 ? dataSource : [], loading: loading, rowSelection: resolvedRowSelection, bordered: false, pagination: paginationConfig, onChange: handleTableChange, onRow: expandEnabled
153
+ ? (record) => ({
154
+ onClick: (event) => {
155
+ if (isInteractiveRowClickTarget(event.target)) {
156
+ return;
157
+ }
158
+ toggleRowExpand(record);
159
+ },
160
+ })
161
+ : undefined, locale: {
162
+ emptyText: jsx(Empty, { image: Empty.PRESENTED_IMAGE_SIMPLE, description: "\u6682\u65E0\u6570\u636E" }),
163
+ } }));
164
+ }
165
+
166
+ export { DataTable as default };
@@ -0,0 +1,61 @@
1
+ var style = document.createElement('style');
2
+ style.textContent = `.index-module__dataTable___ztDZM {
3
+ --data-table-min-width: 920px;
4
+ --data-table-expand-max-height: 200px;
5
+ }
6
+ .index-module__dataTable___ztDZM .ant-table-content {
7
+ overflow-x: auto;
8
+ }
9
+ .index-module__dataTable___ztDZM .ant-table table {
10
+ min-width: var(--data-table-min-width);
11
+ }
12
+ .index-module__dataTable___ztDZM .ant-table-thead > tr > th,
13
+ .index-module__dataTable___ztDZM .ant-table-tbody > tr > td {
14
+ height: 55px;
15
+ min-height: 55px;
16
+ }
17
+ .index-module__dataTable___ztDZM .ant-pagination-item,
18
+ .index-module__dataTable___ztDZM .ant-pagination-prev,
19
+ .index-module__dataTable___ztDZM .ant-pagination-next,
20
+ .index-module__dataTable___ztDZM .ant-pagination-jump-prev,
21
+ .index-module__dataTable___ztDZM .ant-pagination-jump-next {
22
+ min-width: 32px;
23
+ height: 32px;
24
+ line-height: 30px;
25
+ border-radius: 2px;
26
+ }
27
+ .index-module__dataTable___ztDZM .ant-pagination-prev .ant-pagination-item-link,
28
+ .index-module__dataTable___ztDZM .ant-pagination-next .ant-pagination-item-link {
29
+ border-radius: 2px;
30
+ }
31
+ .index-module__dataTable___ztDZM .ant-table-wrapper .ant-pagination.ant-pagination {
32
+ margin: 16px 0 0;
33
+ }
34
+ .index-module__dataTableRowClickable___hbgb0 .ant-table-tbody > tr {
35
+ cursor: pointer;
36
+ }
37
+ .index-module__truncateText___Suq2y {
38
+ max-height: 48px;
39
+ line-height: 24px;
40
+ overflow: hidden;
41
+ text-overflow: ellipsis;
42
+ transition: max-height 0.3s;
43
+ word-break: break-all;
44
+ display: -webkit-box;
45
+ line-clamp: 2;
46
+ -webkit-line-clamp: 2;
47
+ -webkit-box-orient: vertical;
48
+ }
49
+ .index-module__truncateTextExpanded___ENrxt {
50
+ max-height: var(--data-table-expand-max-height);
51
+ overflow-y: auto;
52
+ display: block;
53
+ line-clamp: unset;
54
+ -webkit-line-clamp: unset;
55
+ }`;
56
+ document.head.appendChild(style);
57
+
58
+ var dataTable = "index-module__dataTable___ztDZM";var dataTableRowClickable = "index-module__dataTableRowClickable___hbgb0";var truncateText = "index-module__truncateText___Suq2y";var truncateTextExpanded = "index-module__truncateTextExpanded___ENrxt";
59
+ var styles = {"dataTable":"index-module__dataTable___ztDZM","dataTableRowClickable":"index-module__dataTableRowClickable___hbgb0","truncateText":"index-module__truncateText___Suq2y","truncateTextExpanded":"index-module__truncateTextExpanded___ENrxt"};
60
+
61
+ export { dataTable, dataTableRowClickable, styles as default, truncateText, truncateTextExpanded };
package/es/index.js CHANGED
@@ -34,6 +34,7 @@ export { default as RadioCard } from './components/radio-card/index.js';
34
34
  export { default as OperatorChain } from './components/operator-chain/index.js';
35
35
  export { default as CorpusCard } from './components/corpus-card/index.js';
36
36
  export { default as ModelCard } from './components/model-card/index.js';
37
+ export { default as DataTable } from './components/data-table/index.js';
37
38
  export { default as SDKModal } from './components/SDK-modal/index.js';
38
39
  export { default as TagView } from './components/tag-view/index.js';
39
40
  export { default as TagGroupFilter } from './components/tag-group-filter/index.js';