删除 blueway/数据集管理.jsx

This commit is contained in:
2026-02-27 10:14:31 +00:00
parent 09cc45db36
commit f893517fa1

View File

@@ -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)
);
};