删除 blueway/数据集管理.jsx
This commit is contained in:
@@ -1,506 +0,0 @@
|
|||||||
// 【重要】必须使用 const Component 作为组件变量名
|
|
||||||
// 数据集管理 - 模仿 GitLab 项目列表风格(纯 React,不依赖 antd,兼容 Axhub)
|
|
||||||
|
|
||||||
const Component = function () {
|
|
||||||
var useState = React.useState;
|
|
||||||
var useCallback = React.useCallback;
|
|
||||||
var useMemo = React.useMemo;
|
|
||||||
|
|
||||||
// GitLab 风格色值(Pajamas 近似)
|
|
||||||
var colors = {
|
|
||||||
pageBg: '#fafafa',
|
|
||||||
cardBg: '#ffffff',
|
|
||||||
border: '#e5e5e5',
|
|
||||||
borderLight: '#ebebeb',
|
|
||||||
text: '#333333',
|
|
||||||
textSecondary: '#666666',
|
|
||||||
textMuted: '#999999',
|
|
||||||
primary: '#1f75cb',
|
|
||||||
primaryHover: '#1068bf',
|
|
||||||
link: '#1f75cb',
|
|
||||||
success: '#108548',
|
|
||||||
warning: '#c17d10',
|
|
||||||
danger: '#dd2b0e',
|
|
||||||
hoverBg: '#f5f5f5',
|
|
||||||
tabActive: '#333333',
|
|
||||||
tabInactive: '#666666'
|
|
||||||
};
|
|
||||||
|
|
||||||
var filterState = useState({
|
|
||||||
keyword: '',
|
|
||||||
datasetType: '',
|
|
||||||
status: ''
|
|
||||||
});
|
|
||||||
var filters = filterState[0];
|
|
||||||
var setFilters = filterState[1];
|
|
||||||
|
|
||||||
var activeTabState = useState('all');
|
|
||||||
var activeTab = activeTabState[0];
|
|
||||||
var setActiveTab = activeTabState[1];
|
|
||||||
|
|
||||||
var sortState = useState('updated_desc');
|
|
||||||
var sortBy = sortState[0];
|
|
||||||
var setSortBy = sortState[1];
|
|
||||||
|
|
||||||
var listState = useState([
|
|
||||||
{ id: '1', name: '销售数据集', type: '表格', recordCount: 12000, createTime: '2025-02-20 10:00', updateTime: '2025-02-24 14:00', status: '已发布', remark: '销售业务数据', isStarred: true, owner: '当前用户' },
|
|
||||||
{ id: '2', name: '客户画像数据集', type: '表格', recordCount: 8500, createTime: '2025-02-19 14:30', updateTime: '2025-02-23 09:00', status: '草稿', remark: '客户标签与画像', isStarred: false, owner: '当前用户' },
|
|
||||||
{ id: '3', name: '订单明细数据集', type: '表格', recordCount: 25600, createTime: '2025-02-18 09:15', updateTime: '2025-02-22 16:30', status: '已发布', remark: '订单明细与物流', isStarred: true, owner: '当前用户' },
|
|
||||||
{ id: '4', name: '库存数据集', type: '文件', recordCount: 5200, createTime: '2025-02-17 11:00', updateTime: '2025-02-21 10:00', status: '已下线', remark: '仓库库存快照', isStarred: false, owner: '其他用户' }
|
|
||||||
]);
|
|
||||||
var dataList = listState[0];
|
|
||||||
var setDataList = listState[1];
|
|
||||||
|
|
||||||
var pageState = useState(1);
|
|
||||||
var page = pageState[0];
|
|
||||||
var setPage = pageState[1];
|
|
||||||
var pageSizeState = useState(20);
|
|
||||||
var pageSize = pageSizeState[0];
|
|
||||||
|
|
||||||
var modalState = useState({ open: false, record: null, mode: 'view' });
|
|
||||||
var modalOpen = modalState[0].open;
|
|
||||||
var modalRecord = modalState[0].record;
|
|
||||||
var modalMode = modalState[0].mode;
|
|
||||||
var setModalState = modalState[1];
|
|
||||||
|
|
||||||
var dropdownOpenIdState = useState(null);
|
|
||||||
var dropdownOpenId = dropdownOpenIdState[0];
|
|
||||||
var setDropdownOpenId = dropdownOpenIdState[1];
|
|
||||||
|
|
||||||
var confirmState = useState({ open: false, record: null });
|
|
||||||
var confirmOpen = confirmState[0].open;
|
|
||||||
var confirmRecord = confirmState[0].record;
|
|
||||||
var setConfirmState = confirmState[1];
|
|
||||||
|
|
||||||
var toastState = useState({ show: false, text: '' });
|
|
||||||
var toastShow = toastState[0].show;
|
|
||||||
var toastText = toastState[0].text;
|
|
||||||
var setToastState = toastState[1];
|
|
||||||
|
|
||||||
var typeOptions = useMemo(function () {
|
|
||||||
return [
|
|
||||||
{ value: '表格', label: '表格' },
|
|
||||||
{ value: '文件', label: '文件' },
|
|
||||||
{ value: 'API', label: 'API' }
|
|
||||||
];
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
var statusOptions = useMemo(function () {
|
|
||||||
return [
|
|
||||||
{ value: '草稿', label: '草稿' },
|
|
||||||
{ value: '已发布', label: '已发布' },
|
|
||||||
{ value: '已下线', label: '已下线' }
|
|
||||||
];
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
var sortOptions = useMemo(function () {
|
|
||||||
return [
|
|
||||||
{ value: 'updated_desc', label: '最近更新' },
|
|
||||||
{ value: 'created_desc', label: '最近创建' },
|
|
||||||
{ value: 'name_asc', label: '名称 A-Z' },
|
|
||||||
{ value: 'name_desc', label: '名称 Z-A' }
|
|
||||||
];
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
var filteredList = useMemo(function () {
|
|
||||||
var list = dataList.slice();
|
|
||||||
if (activeTab === 'mine') list = list.filter(function (r) { return r.owner === '当前用户'; });
|
|
||||||
if (activeTab === 'published') list = list.filter(function (r) { return r.status === '已发布'; });
|
|
||||||
if (activeTab === 'draft') list = list.filter(function (r) { return r.status === '草稿'; });
|
|
||||||
if (activeTab === 'starred') list = list.filter(function (r) { return r.isStarred; });
|
|
||||||
if (filters.keyword) {
|
|
||||||
var kw = filters.keyword.trim().toLowerCase();
|
|
||||||
list = list.filter(function (r) {
|
|
||||||
return (r.name && r.name.toLowerCase().indexOf(kw) !== -1) ||
|
|
||||||
(r.remark && r.remark.toLowerCase().indexOf(kw) !== -1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (filters.datasetType) list = list.filter(function (r) { return r.type === filters.datasetType; });
|
|
||||||
if (filters.status) list = list.filter(function (r) { return r.status === filters.status; });
|
|
||||||
if (sortBy === 'updated_desc') list.sort(function (a, b) { return (b.updateTime || b.createTime || '').localeCompare(a.updateTime || a.createTime || ''); });
|
|
||||||
else if (sortBy === 'created_desc') list.sort(function (a, b) { return (b.createTime || '').localeCompare(a.createTime || ''); });
|
|
||||||
else if (sortBy === 'name_asc') list.sort(function (a, b) { return (a.name || '').localeCompare(b.name || ''); });
|
|
||||||
else if (sortBy === 'name_desc') list.sort(function (a, b) { return (b.name || '').localeCompare(a.name || ''); });
|
|
||||||
return list;
|
|
||||||
}, [dataList, activeTab, filters, sortBy]);
|
|
||||||
|
|
||||||
var displayList = useMemo(function () {
|
|
||||||
var start = (page - 1) * pageSize;
|
|
||||||
return filteredList.slice(start, start + pageSize);
|
|
||||||
}, [filteredList, page, pageSize]);
|
|
||||||
|
|
||||||
var totalCount = filteredList.length;
|
|
||||||
|
|
||||||
var handleQuery = useCallback(function () { setPage(1); }, []);
|
|
||||||
var handleReset = useCallback(function () {
|
|
||||||
setFilters({ keyword: '', datasetType: '', status: '' });
|
|
||||||
setPage(1);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
var openModal = useCallback(function (record, mode) {
|
|
||||||
setModalState({ open: true, record: record || null, mode: mode || 'view' });
|
|
||||||
setDropdownOpenId(null);
|
|
||||||
}, []);
|
|
||||||
var closeModal = useCallback(function () {
|
|
||||||
setModalState({ open: false, record: null, mode: 'view' });
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
var showToast = useCallback(function (text) {
|
|
||||||
setToastState({ show: true, text: text });
|
|
||||||
setTimeout(function () { setToastState({ show: false, text: '' }); }, 2000);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
var toggleStar = useCallback(function (record, e) {
|
|
||||||
if (e) e.stopPropagation();
|
|
||||||
setDataList(dataList.map(function (r) {
|
|
||||||
if (r.id === record.id) return Object.assign({}, r, { isStarred: !r.isStarred });
|
|
||||||
return r;
|
|
||||||
}));
|
|
||||||
}, [dataList]);
|
|
||||||
|
|
||||||
var openConfirm = useCallback(function (record) {
|
|
||||||
setConfirmState({ open: true, record: record });
|
|
||||||
setDropdownOpenId(null);
|
|
||||||
}, []);
|
|
||||||
var closeConfirm = useCallback(function () {
|
|
||||||
setConfirmState({ open: false, record: null });
|
|
||||||
}, []);
|
|
||||||
var handleDelete = useCallback(function (record) {
|
|
||||||
setDataList(dataList.filter(function (r) { return r.id !== record.id; }));
|
|
||||||
closeConfirm();
|
|
||||||
showToast('已删除');
|
|
||||||
}, [dataList]);
|
|
||||||
|
|
||||||
function statusTag(status) {
|
|
||||||
var bg = status === '已发布' ? '#e7f5ec' : (status === '草稿' ? '#f0f0f0' : '#fdf3e6');
|
|
||||||
var color = status === '已发布' ? colors.success : (status === '草稿' ? colors.textSecondary : colors.warning);
|
|
||||||
return React.createElement('span', {
|
|
||||||
style: {
|
|
||||||
display: 'inline-block',
|
|
||||||
padding: '2px 8px',
|
|
||||||
borderRadius: 4,
|
|
||||||
fontSize: 12,
|
|
||||||
background: bg,
|
|
||||||
color: color
|
|
||||||
}
|
|
||||||
}, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
var tabs = [
|
|
||||||
{ key: 'all', label: '全部' },
|
|
||||||
{ key: 'mine', label: '我创建的' },
|
|
||||||
{ key: 'starred', label: '已加星' },
|
|
||||||
{ key: 'published', label: '已发布' },
|
|
||||||
{ key: 'draft', label: '草稿' }
|
|
||||||
];
|
|
||||||
|
|
||||||
return React.createElement('div', {
|
|
||||||
style: { minHeight: '100vh', background: colors.pageBg, padding: '24px 24px 48px', position: 'relative' }
|
|
||||||
},
|
|
||||||
// 标题栏
|
|
||||||
React.createElement('div', {
|
|
||||||
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16, flexWrap: 'wrap', gap: 12 }
|
|
||||||
},
|
|
||||||
React.createElement('h1', { style: { margin: 0, fontSize: 24, fontWeight: 600, color: colors.text } }, '数据集'),
|
|
||||||
React.createElement('button', {
|
|
||||||
type: 'button',
|
|
||||||
onClick: function () { openModal(null, 'add'); },
|
|
||||||
style: {
|
|
||||||
padding: '6px 16px',
|
|
||||||
border: 'none',
|
|
||||||
borderRadius: 6,
|
|
||||||
background: colors.primary,
|
|
||||||
color: '#fff',
|
|
||||||
fontSize: 14,
|
|
||||||
cursor: 'pointer',
|
|
||||||
fontWeight: 500
|
|
||||||
}
|
|
||||||
}, '新建数据集')
|
|
||||||
),
|
|
||||||
|
|
||||||
// 搜索与筛选
|
|
||||||
React.createElement('div', {
|
|
||||||
style: { background: colors.cardBg, border: '1px solid ' + colors.border, borderRadius: 6, padding: '12px 16px', marginBottom: 0 }
|
|
||||||
},
|
|
||||||
React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 12 } },
|
|
||||||
React.createElement('div', { style: { display: 'flex', width: 280 } },
|
|
||||||
React.createElement('input', {
|
|
||||||
type: 'text',
|
|
||||||
placeholder: '搜索数据集…',
|
|
||||||
value: filters.keyword,
|
|
||||||
onChange: function (e) { setFilters(function (f) { var g = {}; for (var k in f) g[k] = f[k]; g.keyword = e.target.value; return g; }); },
|
|
||||||
onKeyDown: function (e) { if (e.key === 'Enter') handleQuery(); },
|
|
||||||
style: {
|
|
||||||
flex: 1,
|
|
||||||
padding: '6px 12px',
|
|
||||||
border: '1px solid ' + colors.border,
|
|
||||||
borderRight: 'none',
|
|
||||||
borderRadius: '6px 0 0 6px',
|
|
||||||
fontSize: 14,
|
|
||||||
outline: 'none'
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
React.createElement('button', {
|
|
||||||
type: 'button',
|
|
||||||
onClick: handleQuery,
|
|
||||||
style: {
|
|
||||||
padding: '6px 12px',
|
|
||||||
border: '1px solid ' + colors.border,
|
|
||||||
borderRadius: '0 6px 6px 0',
|
|
||||||
background: colors.pageBg,
|
|
||||||
cursor: 'pointer',
|
|
||||||
fontSize: 14
|
|
||||||
}
|
|
||||||
}, '搜索')
|
|
||||||
),
|
|
||||||
React.createElement('select', {
|
|
||||||
value: filters.datasetType,
|
|
||||||
onChange: function (e) { setFilters(function (f) { var g = {}; for (var k in f) g[k] = f[k]; g.datasetType = e.target.value; return g; }); },
|
|
||||||
style: { width: 100, padding: '6px 8px', border: '1px solid ' + colors.border, borderRadius: 6, fontSize: 14 }
|
|
||||||
},
|
|
||||||
React.createElement('option', { value: '' }, '类型'),
|
|
||||||
typeOptions.map(function (o) { return React.createElement('option', { key: o.value, value: o.value }, o.label); })
|
|
||||||
),
|
|
||||||
React.createElement('select', {
|
|
||||||
value: filters.status,
|
|
||||||
onChange: function (e) { setFilters(function (f) { var g = {}; for (var k in f) g[k] = f[k]; g.status = e.target.value; return g; }); },
|
|
||||||
style: { width: 100, padding: '6px 8px', border: '1px solid ' + colors.border, borderRadius: 6, fontSize: 14 }
|
|
||||||
},
|
|
||||||
React.createElement('option', { value: '' }, '状态'),
|
|
||||||
statusOptions.map(function (o) { return React.createElement('option', { key: o.value, value: o.value }, o.label); })
|
|
||||||
),
|
|
||||||
React.createElement('button', { type: 'button', onClick: handleQuery, style: { padding: '6px 14px', border: '1px solid ' + colors.border, borderRadius: 6, background: colors.cardBg, cursor: 'pointer', fontSize: 14 } }, '搜索'),
|
|
||||||
React.createElement('button', { type: 'button', onClick: handleReset, style: { padding: '6px 14px', border: '1px solid ' + colors.border, borderRadius: 6, background: colors.cardBg, cursor: 'pointer', fontSize: 14 } }, '重置'),
|
|
||||||
React.createElement('span', { style: { marginLeft: 'auto', color: colors.textMuted, fontSize: 12 } },
|
|
||||||
'排序:',
|
|
||||||
React.createElement('select', {
|
|
||||||
value: sortBy,
|
|
||||||
onChange: function (e) { setSortBy(e.target.value); },
|
|
||||||
style: { width: 120, marginLeft: 4, padding: '4px 8px', border: 'none', background: 'transparent', fontSize: 12, color: colors.textSecondary, cursor: 'pointer' }
|
|
||||||
},
|
|
||||||
sortOptions.map(function (o) { return React.createElement('option', { key: o.value, value: o.value }, o.label); })
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
// Tab
|
|
||||||
React.createElement('div', {
|
|
||||||
style: { background: colors.cardBg, border: '1px solid ' + colors.border, borderTop: 'none', borderRadius: '0 0 6px 6px', padding: '0 16px', marginBottom: 16, display: 'flex', gap: 8 }
|
|
||||||
},
|
|
||||||
tabs.map(function (t) {
|
|
||||||
var isActive = activeTab === t.key;
|
|
||||||
return React.createElement('button', {
|
|
||||||
key: t.key,
|
|
||||||
type: 'button',
|
|
||||||
onClick: function () { setActiveTab(t.key); setPage(1); },
|
|
||||||
style: {
|
|
||||||
padding: '12px 4px',
|
|
||||||
margin: 0,
|
|
||||||
border: 'none',
|
|
||||||
background: 'none',
|
|
||||||
cursor: 'pointer',
|
|
||||||
fontSize: 14,
|
|
||||||
color: isActive ? colors.tabActive : colors.tabInactive,
|
|
||||||
fontWeight: isActive ? 600 : 400,
|
|
||||||
borderBottom: '2px solid ' + (isActive ? colors.primary : 'transparent'),
|
|
||||||
marginBottom: -1
|
|
||||||
}
|
|
||||||
}, t.label);
|
|
||||||
})
|
|
||||||
),
|
|
||||||
|
|
||||||
// 列表
|
|
||||||
React.createElement('div', {
|
|
||||||
style: { background: colors.cardBg, border: '1px solid ' + colors.border, borderRadius: 6, overflow: 'hidden' }
|
|
||||||
},
|
|
||||||
displayList.length === 0
|
|
||||||
? React.createElement('div', { style: { padding: 48, textAlign: 'center', color: colors.textMuted } }, activeTab === 'all' && !filters.keyword ? '暂无数据集,点击「新建数据集」创建' : '没有匹配的数据集')
|
|
||||||
: displayList.map(function (row) {
|
|
||||||
var menuOpen = dropdownOpenId === row.id;
|
|
||||||
return React.createElement('div', {
|
|
||||||
key: row.id,
|
|
||||||
style: {
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'flex-start',
|
|
||||||
padding: '12px 16px',
|
|
||||||
borderBottom: '1px solid ' + colors.borderLight,
|
|
||||||
cursor: 'pointer',
|
|
||||||
transition: 'background 0.15s'
|
|
||||||
},
|
|
||||||
onMouseEnter: function (e) { e.currentTarget.style.background = colors.hoverBg; },
|
|
||||||
onMouseLeave: function (e) { e.currentTarget.style.background = 'transparent'; },
|
|
||||||
onClick: function (e) {
|
|
||||||
if (e.target.closest('button') || e.target.closest('[data-dropdown]')) return;
|
|
||||||
openModal(row, 'view');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
React.createElement('div', {
|
|
||||||
style: {
|
|
||||||
width: 40, height: 40, borderRadius: 6, background: colors.pageBg, border: '1px solid ' + colors.border,
|
|
||||||
marginRight: 12, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 18, color: colors.primary
|
|
||||||
}
|
|
||||||
}, '\uD83D\uDCCA'),
|
|
||||||
React.createElement('div', { style: { flex: 1, minWidth: 0 } },
|
|
||||||
React.createElement('div', { style: { display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 8, marginBottom: 4 } },
|
|
||||||
React.createElement('span', { style: { fontSize: 14, fontWeight: 600, color: colors.link } }, row.name),
|
|
||||||
statusTag(row.status),
|
|
||||||
React.createElement('span', { style: { fontSize: 12, color: colors.textMuted } }, row.type + ' · ' + (row.recordCount != null ? row.recordCount.toLocaleString() + ' 条' : '-'))
|
|
||||||
),
|
|
||||||
row.remark ? React.createElement('div', { style: { fontSize: 13, color: colors.textSecondary, marginBottom: 4, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, row.remark) : null,
|
|
||||||
React.createElement('div', { style: { fontSize: 12, color: colors.textMuted } }, '更新于 ' + (row.updateTime || row.createTime || '-'))
|
|
||||||
),
|
|
||||||
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0 }, onClick: function (e) { e.stopPropagation(); } },
|
|
||||||
React.createElement('button', {
|
|
||||||
type: 'button',
|
|
||||||
title: row.isStarred ? '取消加星' : '加星',
|
|
||||||
onClick: function (e) { toggleStar(row, e); },
|
|
||||||
style: { border: 'none', background: 'none', cursor: 'pointer', padding: 4, fontSize: 16, color: row.isStarred ? '#c17d10' : colors.textMuted }
|
|
||||||
}, '\u2605'),
|
|
||||||
React.createElement('div', { style: { position: 'relative' }, 'data-dropdown': true },
|
|
||||||
React.createElement('button', {
|
|
||||||
type: 'button',
|
|
||||||
onClick: function (e) { e.stopPropagation(); setDropdownOpenId(menuOpen ? null : row.id); },
|
|
||||||
style: { border: 'none', background: 'none', cursor: 'pointer', padding: '2px 8px', fontSize: 16, color: colors.textSecondary }
|
|
||||||
}, '\u22EE'),
|
|
||||||
menuOpen ? React.createElement('div', {
|
|
||||||
style: {
|
|
||||||
position: 'absolute',
|
|
||||||
right: 0,
|
|
||||||
top: '100%',
|
|
||||||
marginTop: 4,
|
|
||||||
background: colors.cardBg,
|
|
||||||
border: '1px solid ' + colors.border,
|
|
||||||
borderRadius: 6,
|
|
||||||
boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
|
|
||||||
minWidth: 100,
|
|
||||||
zIndex: 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
React.createElement('div', { style: { padding: '6px 12px', cursor: 'pointer', fontSize: 13 }, onClick: function () { openModal(row, 'view'); setDropdownOpenId(null); } }, '查看'),
|
|
||||||
React.createElement('div', { style: { padding: '6px 12px', cursor: 'pointer', fontSize: 13 }, onClick: function () { openModal(row, 'edit'); setDropdownOpenId(null); } }, '编辑'),
|
|
||||||
React.createElement('div', { style: { borderTop: '1px solid ' + colors.borderLight } }),
|
|
||||||
React.createElement('div', { style: { padding: '6px 12px', cursor: 'pointer', fontSize: 13, color: colors.danger }, onClick: function () { openConfirm(row); } }, '删除')
|
|
||||||
) : null
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
})
|
|
||||||
),
|
|
||||||
|
|
||||||
// 分页
|
|
||||||
totalCount > 0 ? React.createElement('div', {
|
|
||||||
style: { display: 'flex', justifyContent: 'flex-end', alignItems: 'center', padding: '16px 0', gap: 16, fontSize: 13, color: colors.textSecondary }
|
|
||||||
},
|
|
||||||
React.createElement('span', null, '共 ' + totalCount + ' 项'),
|
|
||||||
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8 } },
|
|
||||||
React.createElement('button', {
|
|
||||||
type: 'button',
|
|
||||||
disabled: page <= 1,
|
|
||||||
onClick: function () { setPage(page - 1); },
|
|
||||||
style: { padding: '4px 10px', border: '1px solid ' + colors.border, borderRadius: 4, background: colors.cardBg, cursor: page <= 1 ? 'not-allowed' : 'pointer', opacity: page <= 1 ? 0.6 : 1 }
|
|
||||||
}, '上一页'),
|
|
||||||
React.createElement('span', null, page + ' / ' + Math.max(1, Math.ceil(totalCount / pageSize))),
|
|
||||||
React.createElement('button', {
|
|
||||||
type: 'button',
|
|
||||||
disabled: page >= Math.ceil(totalCount / pageSize),
|
|
||||||
onClick: function () { setPage(page + 1); },
|
|
||||||
style: { padding: '4px 10px', border: '1px solid ' + colors.border, borderRadius: 4, background: colors.cardBg, cursor: page >= Math.ceil(totalCount / pageSize) ? 'not-allowed' : 'pointer', opacity: page >= Math.ceil(totalCount / pageSize) ? 0.6 : 1 }
|
|
||||||
}, '下一页')
|
|
||||||
)
|
|
||||||
) : null,
|
|
||||||
|
|
||||||
// 弹窗(查看/编辑/新增)
|
|
||||||
modalOpen && React.createElement('div', {
|
|
||||||
style: { position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.45)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center' },
|
|
||||||
onClick: function (e) { if (e.target === e.currentTarget) closeModal(); }
|
|
||||||
},
|
|
||||||
React.createElement('div', {
|
|
||||||
style: { background: colors.cardBg, borderRadius: 8, width: 520, maxWidth: '90vw', maxHeight: '90vh', overflow: 'auto', boxShadow: '0 6px 16px rgba(0,0,0,0.2)' },
|
|
||||||
onClick: function (e) { e.stopPropagation(); }
|
|
||||||
},
|
|
||||||
React.createElement('div', { style: { padding: '16px 24px', borderBottom: '1px solid ' + colors.border, fontSize: 16, fontWeight: 600 } },
|
|
||||||
modalMode === 'view' ? '查看数据集' : (modalMode === 'edit' ? '编辑数据集' : '新建数据集')
|
|
||||||
),
|
|
||||||
(modalRecord || modalMode === 'add') && React.createElement('div', { style: { padding: 24 } },
|
|
||||||
React.createElement('div', { style: { marginBottom: 16 } },
|
|
||||||
React.createElement('div', { style: { marginBottom: 4, color: colors.textSecondary, fontSize: 13 } }, '数据集名称'),
|
|
||||||
modalMode === 'view' ? (modalRecord && modalRecord.name) : React.createElement('input', {
|
|
||||||
type: 'text',
|
|
||||||
placeholder: '请输入名称',
|
|
||||||
defaultValue: modalRecord && modalRecord.name,
|
|
||||||
style: { width: '100%', padding: '8px 12px', border: '1px solid ' + colors.border, borderRadius: 6, fontSize: 14, boxSizing: 'border-box' }
|
|
||||||
})
|
|
||||||
),
|
|
||||||
React.createElement('div', { style: { marginBottom: 16 } },
|
|
||||||
React.createElement('div', { style: { marginBottom: 4, color: colors.textSecondary, fontSize: 13 } }, '类型'),
|
|
||||||
modalMode === 'view' ? (modalRecord && modalRecord.type) : React.createElement('select', {
|
|
||||||
defaultValue: modalRecord && modalRecord.type,
|
|
||||||
style: { width: '100%', padding: '8px 12px', border: '1px solid ' + colors.border, borderRadius: 6, fontSize: 14, boxSizing: 'border-box' }
|
|
||||||
}, typeOptions.map(function (o) { return React.createElement('option', { key: o.value, value: o.value }, o.label); }))
|
|
||||||
),
|
|
||||||
React.createElement('div', { style: { marginBottom: 16 } },
|
|
||||||
React.createElement('div', { style: { marginBottom: 4, color: colors.textSecondary, fontSize: 13 } }, '备注'),
|
|
||||||
modalMode === 'view' ? (modalRecord && modalRecord.remark) || '-' : React.createElement('textarea', {
|
|
||||||
placeholder: '选填',
|
|
||||||
defaultValue: modalRecord && modalRecord.remark,
|
|
||||||
rows: 3,
|
|
||||||
style: { width: '100%', padding: '8px 12px', border: '1px solid ' + colors.border, borderRadius: 6, fontSize: 14, boxSizing: 'border-box', resize: 'vertical' }
|
|
||||||
})
|
|
||||||
)
|
|
||||||
),
|
|
||||||
React.createElement('div', { style: { padding: '12px 24px', borderTop: '1px solid ' + colors.border, display: 'flex', justifyContent: 'flex-end', gap: 8 } },
|
|
||||||
modalMode === 'view'
|
|
||||||
? React.createElement('button', { type: 'button', onClick: closeModal, style: { padding: '6px 16px', border: '1px solid ' + colors.border, borderRadius: 6, background: colors.cardBg, cursor: 'pointer', fontSize: 14 } }, '关闭')
|
|
||||||
: [
|
|
||||||
React.createElement('button', { key: 'cancel', type: 'button', onClick: closeModal, style: { padding: '6px 16px', border: '1px solid ' + colors.border, borderRadius: 6, background: colors.cardBg, cursor: 'pointer', fontSize: 14 } }, '取消'),
|
|
||||||
React.createElement('button', {
|
|
||||||
key: 'save',
|
|
||||||
type: 'button',
|
|
||||||
onClick: function () { showToast(modalMode === 'add' ? '创建成功' : '已保存'); closeModal(); },
|
|
||||||
style: { padding: '6px 16px', border: 'none', borderRadius: 6, background: colors.primary, color: '#fff', cursor: 'pointer', fontSize: 14 }
|
|
||||||
}, modalMode === 'add' ? '创建' : '保存')
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
// 删除确认弹窗
|
|
||||||
confirmOpen && confirmRecord && React.createElement('div', {
|
|
||||||
style: { position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.45)', zIndex: 1001, display: 'flex', alignItems: 'center', justifyContent: 'center' },
|
|
||||||
onClick: function (e) { if (e.target === e.currentTarget) closeConfirm(); }
|
|
||||||
},
|
|
||||||
React.createElement('div', {
|
|
||||||
style: { background: colors.cardBg, borderRadius: 8, padding: 24, width: 400, maxWidth: '90vw', boxShadow: '0 6px 16px rgba(0,0,0,0.2)' },
|
|
||||||
onClick: function (e) { e.stopPropagation(); }
|
|
||||||
},
|
|
||||||
React.createElement('div', { style: { fontSize: 16, fontWeight: 600, marginBottom: 8 } }, '删除数据集'),
|
|
||||||
React.createElement('div', { style: { color: colors.textSecondary, marginBottom: 24 } }, '确定要删除「' + (confirmRecord.name || '') + '」吗?此操作不可恢复。'),
|
|
||||||
React.createElement('div', { style: { display: 'flex', justifyContent: 'flex-end', gap: 8 } },
|
|
||||||
React.createElement('button', { type: 'button', onClick: closeConfirm, style: { padding: '6px 16px', border: '1px solid ' + colors.border, borderRadius: 6, background: colors.cardBg, cursor: 'pointer', fontSize: 14 } }, '取消'),
|
|
||||||
React.createElement('button', {
|
|
||||||
type: 'button',
|
|
||||||
onClick: function () { handleDelete(confirmRecord); },
|
|
||||||
style: { padding: '6px 16px', border: 'none', borderRadius: 6, background: colors.danger, color: '#fff', cursor: 'pointer', fontSize: 14 }
|
|
||||||
}, '删除')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
// 轻提示
|
|
||||||
toastShow && React.createElement('div', {
|
|
||||||
style: {
|
|
||||||
position: 'fixed',
|
|
||||||
left: '50%',
|
|
||||||
bottom: 48,
|
|
||||||
transform: 'translateX(-50%)',
|
|
||||||
padding: '8px 16px',
|
|
||||||
background: 'rgba(0,0,0,0.75)',
|
|
||||||
color: '#fff',
|
|
||||||
borderRadius: 6,
|
|
||||||
fontSize: 14,
|
|
||||||
zIndex: 1002
|
|
||||||
}
|
|
||||||
}, toastText)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user