|
@@ -39,6 +39,8 @@ const AuditLogExportModalSubstance = ({
|
|
|
),
|
|
),
|
|
|
);
|
|
);
|
|
|
const [isExporting, setIsExporting] = useState<boolean>(false);
|
|
const [isExporting, setIsExporting] = useState<boolean>(false);
|
|
|
|
|
+ const [isDuplicateConfirmOpen, setIsDuplicateConfirmOpen] =
|
|
|
|
|
+ useState<boolean>(false);
|
|
|
|
|
|
|
|
const datePickerChangedHandler = useCallback((dateList: Date[] | null[]) => {
|
|
const datePickerChangedHandler = useCallback((dateList: Date[] | null[]) => {
|
|
|
setStartDate(dateList[0]);
|
|
setStartDate(dateList[0]);
|
|
@@ -73,31 +75,61 @@ const AuditLogExportModalSubstance = ({
|
|
|
setSelectedUsernames(usernames);
|
|
setSelectedUsernames(usernames);
|
|
|
}, []);
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
+ const buildFilters = useCallback(() => {
|
|
|
|
|
+ const selectedActionList = Array.from(actionMap.entries())
|
|
|
|
|
+ .filter((v) => v[1])
|
|
|
|
|
+ .map((v) => v[0]);
|
|
|
|
|
+
|
|
|
|
|
+ const filters: {
|
|
|
|
|
+ actions?: SupportedActionType[];
|
|
|
|
|
+ dateFrom?: Date;
|
|
|
|
|
+ dateTo?: Date;
|
|
|
|
|
+ // TODO: Add users filter after implementing username-to-userId conversion
|
|
|
|
|
+ } = {};
|
|
|
|
|
+
|
|
|
|
|
+ if (selectedActionList.length > 0) {
|
|
|
|
|
+ filters.actions = selectedActionList;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (startDate != null) {
|
|
|
|
|
+ filters.dateFrom = startDate;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (endDate != null) {
|
|
|
|
|
+ filters.dateTo = endDate;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return filters;
|
|
|
|
|
+ }, [actionMap, startDate, endDate]);
|
|
|
|
|
+
|
|
|
const exportHandler = useCallback(async () => {
|
|
const exportHandler = useCallback(async () => {
|
|
|
setIsExporting(true);
|
|
setIsExporting(true);
|
|
|
try {
|
|
try {
|
|
|
- const selectedActionList = Array.from(actionMap.entries())
|
|
|
|
|
- .filter((v) => v[1])
|
|
|
|
|
- .map((v) => v[0]);
|
|
|
|
|
-
|
|
|
|
|
- const filters: {
|
|
|
|
|
- actions?: SupportedActionType[];
|
|
|
|
|
- dateFrom?: Date;
|
|
|
|
|
- dateTo?: Date;
|
|
|
|
|
- // TODO: Add users filter after implementing username-to-userId conversion
|
|
|
|
|
- } = {};
|
|
|
|
|
-
|
|
|
|
|
- if (selectedActionList.length > 0) {
|
|
|
|
|
- filters.actions = selectedActionList;
|
|
|
|
|
- }
|
|
|
|
|
- if (startDate != null) {
|
|
|
|
|
- filters.dateFrom = startDate;
|
|
|
|
|
- }
|
|
|
|
|
- if (endDate != null) {
|
|
|
|
|
- filters.dateTo = endDate;
|
|
|
|
|
|
|
+ const filters = buildFilters();
|
|
|
|
|
+ await apiv3Post('/audit-log-bulk-export', { filters });
|
|
|
|
|
+ toastSuccess(t('audit_log_management.export_requested'));
|
|
|
|
|
+ onClose();
|
|
|
|
|
+ } catch (errs) {
|
|
|
|
|
+ const isDuplicate =
|
|
|
|
|
+ Array.isArray(errs) &&
|
|
|
|
|
+ errs.some(
|
|
|
|
|
+ (e) => e.code === 'audit_log_bulk_export.duplicate_export_job_error',
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ if (isDuplicate) {
|
|
|
|
|
+ setIsDuplicateConfirmOpen(true);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ toastError(t('audit_log_management.export_failed'));
|
|
|
}
|
|
}
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ setIsExporting(false);
|
|
|
|
|
+ }
|
|
|
|
|
+ }, [buildFilters, t, onClose]);
|
|
|
|
|
|
|
|
- await apiv3Post('/audit-log-bulk-export', { filters });
|
|
|
|
|
|
|
+ const restartExportHandler = useCallback(async () => {
|
|
|
|
|
+ setIsDuplicateConfirmOpen(false);
|
|
|
|
|
+ setIsExporting(true);
|
|
|
|
|
+ try {
|
|
|
|
|
+ const filters = buildFilters();
|
|
|
|
|
+ await apiv3Post('/audit-log-bulk-export', { filters, restartJob: true });
|
|
|
toastSuccess(t('audit_log_management.export_requested'));
|
|
toastSuccess(t('audit_log_management.export_requested'));
|
|
|
onClose();
|
|
onClose();
|
|
|
} catch {
|
|
} catch {
|
|
@@ -105,7 +137,7 @@ const AuditLogExportModalSubstance = ({
|
|
|
} finally {
|
|
} finally {
|
|
|
setIsExporting(false);
|
|
setIsExporting(false);
|
|
|
}
|
|
}
|
|
|
- }, [actionMap, startDate, endDate, t, onClose]);
|
|
|
|
|
|
|
+ }, [buildFilters, t, onClose]);
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<>
|
|
<>
|
|
@@ -161,6 +193,34 @@ const AuditLogExportModalSubstance = ({
|
|
|
{t('audit_log_management.export')}
|
|
{t('audit_log_management.export')}
|
|
|
</button>
|
|
</button>
|
|
|
</ModalFooter>
|
|
</ModalFooter>
|
|
|
|
|
+
|
|
|
|
|
+ <Modal
|
|
|
|
|
+ isOpen={isDuplicateConfirmOpen}
|
|
|
|
|
+ toggle={() => setIsDuplicateConfirmOpen(false)}
|
|
|
|
|
+ >
|
|
|
|
|
+ <ModalHeader tag="h4" toggle={() => setIsDuplicateConfirmOpen(false)}>
|
|
|
|
|
+ {t('audit_log_management.confirm_export')}
|
|
|
|
|
+ </ModalHeader>
|
|
|
|
|
+ <ModalBody>
|
|
|
|
|
+ {t('audit_log_management.duplicate_export_confirm')}
|
|
|
|
|
+ </ModalBody>
|
|
|
|
|
+ <ModalFooter>
|
|
|
|
|
+ <button
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ className="btn btn-outline-secondary"
|
|
|
|
|
+ onClick={() => setIsDuplicateConfirmOpen(false)}
|
|
|
|
|
+ >
|
|
|
|
|
+ {t('export_management.cancel')}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ className="btn btn-primary"
|
|
|
|
|
+ onClick={restartExportHandler}
|
|
|
|
|
+ >
|
|
|
|
|
+ {t('audit_log_management.restart_export')}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </ModalFooter>
|
|
|
|
|
+ </Modal>
|
|
|
</>
|
|
</>
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|