mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
chore: import action
This commit is contained in:
parent
25f764c15f
commit
f6df25eef9
@ -11,7 +11,7 @@ import { ExclamationCircleFilled, LoadingOutlined } from '@ant-design/icons';
|
|||||||
import { css } from '@nocobase/client';
|
import { css } from '@nocobase/client';
|
||||||
import { Button, Modal, Space, Spin } from 'antd';
|
import { Button, Modal, Space, Spin } from 'antd';
|
||||||
import { saveAs } from 'file-saver';
|
import { saveAs } from 'file-saver';
|
||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { NAMESPACE } from './constants';
|
import { NAMESPACE } from './constants';
|
||||||
import { useImportContext } from './context';
|
import { useImportContext } from './context';
|
||||||
@ -25,6 +25,7 @@ export const ImportModal = (props: any) => {
|
|||||||
const { t } = useTranslation(NAMESPACE);
|
const { t } = useTranslation(NAMESPACE);
|
||||||
const { importModalVisible, importStatus, importResult, setImportModalVisible } = useImportContext();
|
const { importModalVisible, importStatus, importResult, setImportModalVisible } = useImportContext();
|
||||||
const { data: fileData, meta } = importResult ?? {};
|
const { data: fileData, meta } = importResult ?? {};
|
||||||
|
|
||||||
const doneHandler = () => {
|
const doneHandler = () => {
|
||||||
setImportModalVisible(false);
|
setImportModalVisible(false);
|
||||||
};
|
};
|
||||||
@ -33,6 +34,34 @@ export const ImportModal = (props: any) => {
|
|||||||
const blob = new Blob([arrayBuffer], { type: 'application/x-xls' });
|
const blob = new Blob([arrayBuffer], { type: 'application/x-xls' });
|
||||||
saveAs(blob, `fail.xlsx`);
|
saveAs(blob, `fail.xlsx`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const renderResult = (importResult) => {
|
||||||
|
if (!importResult) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data, meta } = importResult;
|
||||||
|
if (meta) {
|
||||||
|
return t('{{successCount}} records have been successfully imported', {
|
||||||
|
...(meta ?? {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const stats = data;
|
||||||
|
const parts = [
|
||||||
|
`${t('Total records')}: ${stats.total || 0}`,
|
||||||
|
`${t('Successfully imported')}: ${stats.success || 0}`,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (stats.skipped > 0) {
|
||||||
|
parts.push(`${t('Skipped')}: ${stats.skipped}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.updated > 0) {
|
||||||
|
parts.push(`${t('Updated')}: ${stats.updated}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts.join(', ');
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={t('Import Data')}
|
title={t('Import Data')}
|
||||||
@ -57,11 +86,8 @@ export const ImportModal = (props: any) => {
|
|||||||
{importStatus === ImportStatus.IMPORTED && (
|
{importStatus === ImportStatus.IMPORTED && (
|
||||||
<Space direction="vertical" align="center">
|
<Space direction="vertical" align="center">
|
||||||
<ExclamationCircleFilled style={{ fontSize: 72, color: '#1890ff' }} />
|
<ExclamationCircleFilled style={{ fontSize: 72, color: '#1890ff' }} />
|
||||||
<p>
|
|
||||||
{t('{{successCount}} records have been successfully imported', {
|
<p>{renderResult(importResult)}</p>
|
||||||
...(meta ?? {}),
|
|
||||||
})}
|
|
||||||
</p>
|
|
||||||
<Space>
|
<Space>
|
||||||
{meta?.failureCount > 0 && (
|
{meta?.failureCount > 0 && (
|
||||||
<Button onClick={downloadFailureDataHandler}>{t('To download the failure data')}</Button>
|
<Button onClick={downloadFailureDataHandler}>{t('To download the failure data')}</Button>
|
||||||
|
@ -173,6 +173,8 @@ export const useImportStartAction = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const importMode = importSchema?.['x-action-settings']?.importMode || 'auto';
|
||||||
|
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
setImportModalVisible(true);
|
setImportModalVisible(true);
|
||||||
setImportStatus(ImportStatus.IMPORTING);
|
setImportStatus(ImportStatus.IMPORTING);
|
||||||
@ -181,13 +183,13 @@ export const useImportStartAction = () => {
|
|||||||
const { data } = await (newResource as any).importXlsx(
|
const { data } = await (newResource as any).importXlsx(
|
||||||
{
|
{
|
||||||
values: formData,
|
values: formData,
|
||||||
|
mode: importMode,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
timeout: 10 * 60 * 1000,
|
timeout: 10 * 60 * 1000,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
setImportResult(data);
|
|
||||||
form.reset();
|
form.reset();
|
||||||
|
|
||||||
if (!data.data.taskId) {
|
if (!data.data.taskId) {
|
||||||
|
@ -39,5 +39,13 @@
|
|||||||
"Header mismatch at column {{column}}: expected \"{{expected}}\", but got \"{{actual}}\"": "第 {{column}} 列的表头不匹配:预期 \"{{expected}}\",实际是 \"{{actual}}\"",
|
"Header mismatch at column {{column}}: expected \"{{expected}}\", but got \"{{actual}}\"": "第 {{column}} 列的表头不匹配:预期 \"{{expected}}\",实际是 \"{{actual}}\"",
|
||||||
"No data to import": "没有数据可导入",
|
"No data to import": "没有数据可导入",
|
||||||
"Failed to import row {{row}}, {{message}}, row data: {{data}}": "导入第 {{row}} 行失败,{{message}},行数据:{{data}}",
|
"Failed to import row {{row}}, {{message}}, row data: {{data}}": "导入第 {{row}} 行失败,{{message}},行数据:{{data}}",
|
||||||
"import-error": "导入第 {{rowIndex}} 行失败,行数据:{{rowData}}, 原因:{{causeMessage}}"
|
"import-error": "导入第 {{rowIndex}} 行失败,行数据:{{rowData}}, 原因:{{causeMessage}}",
|
||||||
|
"Import completed": "导入完成:{{success}} 条记录已导入,{{updated}} 条记录已更新,{{skipped}} 条记录已跳过,共 {{total}} 条记录",
|
||||||
|
"Successfully imported": "成功导入",
|
||||||
|
"Updated records": "已更新记录",
|
||||||
|
"Skipped records": "已跳过记录",
|
||||||
|
"Total records": "总记录数",
|
||||||
|
"View result": "查看结果",
|
||||||
|
"ImportResult": "已导入 {{success}} 条,更新 {{updated}} 条,跳过 {{skipped}} 条,共 {{total}} 条",
|
||||||
|
"Task result": "任务结果"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user