mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-26 09:55:52 +00:00
Minor: improve the entity export modal feedback message (#18526)
(cherry picked from commit 305f02c62a86a380f65e6ada7e9e2f1d22052aca)
This commit is contained in:
parent
1995b17a8d
commit
7d3a1b0a9e
@ -12,12 +12,13 @@
|
||||
*/
|
||||
import { Form, Input, Modal } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import classNames from 'classnames';
|
||||
import { isString } from 'lodash';
|
||||
import React, { ReactNode, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getCurrentISODate } from '../../../utils/date-time/DateTimeUtils';
|
||||
import { showErrorToast } from '../../../utils/ToastUtils';
|
||||
import Banner, { BannerProps } from '../../common/Banner/Banner';
|
||||
import Banner from '../../common/Banner/Banner';
|
||||
import {
|
||||
CSVExportJob,
|
||||
CSVExportWebsocketResponse,
|
||||
@ -149,16 +150,6 @@ export const EntityExportModalProvider = ({
|
||||
[]
|
||||
);
|
||||
|
||||
const bannerConfig = useMemo(() => {
|
||||
const isCompleted = csvExportJob?.status === 'COMPLETED';
|
||||
|
||||
return {
|
||||
type: isCompleted ? 'success' : 'error',
|
||||
message: isCompleted ? csvExportJob?.message : csvExportJob?.error,
|
||||
hasJobId: !!csvExportJob?.jobId,
|
||||
};
|
||||
}, [csvExportJob]);
|
||||
|
||||
return (
|
||||
<EntityExportModalContext.Provider value={providerValue}>
|
||||
<>
|
||||
@ -169,13 +160,13 @@ export const EntityExportModalProvider = ({
|
||||
open
|
||||
cancelText={t('label.cancel')}
|
||||
closable={false}
|
||||
confirmLoading={downloading}
|
||||
data-testid="export-entity-modal"
|
||||
maskClosable={false}
|
||||
okButtonProps={{
|
||||
form: 'export-form',
|
||||
htmlType: 'submit',
|
||||
id: 'submit-button',
|
||||
disabled: downloading,
|
||||
}}
|
||||
okText={t('label.export')}
|
||||
title={exportData.title ?? t('label.export')}
|
||||
@ -186,6 +177,7 @@ export const EntityExportModalProvider = ({
|
||||
layout="vertical"
|
||||
onFinish={handleExport}>
|
||||
<Form.Item
|
||||
className={classNames({ 'mb-0': !csvExportJob?.jobId })}
|
||||
label={`${t('label.entity-name', {
|
||||
entity: t('label.file'),
|
||||
})}:`}
|
||||
@ -194,11 +186,12 @@ export const EntityExportModalProvider = ({
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
{bannerConfig.hasJobId && bannerConfig.message && (
|
||||
{csvExportJob?.jobId && (
|
||||
<Banner
|
||||
className="border-radius"
|
||||
message={bannerConfig.message}
|
||||
type={bannerConfig.type as BannerProps['type']}
|
||||
isLoading={downloading}
|
||||
message={csvExportJob.error ?? csvExportJob.message ?? ''}
|
||||
type={csvExportJob.error ? 'error' : 'success'}
|
||||
/>
|
||||
)}
|
||||
</Modal>
|
||||
|
@ -18,17 +18,14 @@ import {
|
||||
} from './EntityExportModalProvider.component';
|
||||
import { ExportData } from './EntityExportModalProvider.interface';
|
||||
|
||||
const dummyTeamsCSV = `name*,displayName,description,teamType*,parents*,Owner,isJoinable,defaultRoles,policies
|
||||
access table only,access table only,,Group,Organization,,true,Only table,
|
||||
Engineering,,,BusinessUnit,Organization,,true,,
|
||||
Finance,,,BusinessUnit,Organization,,true,,
|
||||
Legal,,,BusinessUnit,Organization,,true,,
|
||||
Applications,,,Group,Engineering,,true,,
|
||||
`;
|
||||
const mockExportJob = {
|
||||
jobId: '123456',
|
||||
message: 'Export initiated successfyully',
|
||||
};
|
||||
|
||||
const mockShowModal: ExportData = {
|
||||
name: 'test',
|
||||
onExport: jest.fn().mockImplementation(() => Promise.resolve(dummyTeamsCSV)),
|
||||
onExport: jest.fn().mockImplementation(() => Promise.resolve(mockExportJob)),
|
||||
};
|
||||
|
||||
const ConsumerComponent = () => {
|
||||
@ -140,6 +137,7 @@ describe('EntityExportModalProvider component', () => {
|
||||
});
|
||||
|
||||
expect(mockShowModal.onExport).toHaveBeenCalledWith(mockShowModal.name);
|
||||
expect(screen.queryByTestId('export-entity-modal')).not.toBeInTheDocument();
|
||||
|
||||
expect(await screen.findByText(mockExportJob.message)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React, { FC } from 'react';
|
||||
import './banner.less';
|
||||
|
||||
import { LoadingOutlined } from '@ant-design/icons';
|
||||
import { Spin } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { ReactComponent as ErrorIcon } from '../../../assets/svg/banner/ic-banner-error.svg';
|
||||
import { ReactComponent as SuccessIcon } from '../../../assets/svg/banner/ic-banner-success.svg';
|
||||
@ -8,12 +10,23 @@ import { ReactComponent as SuccessIcon } from '../../../assets/svg/banner/ic-ban
|
||||
export interface BannerProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
type: 'success' | 'error';
|
||||
message: string;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const Banner: FC<BannerProps> = ({ type, message, className }) => {
|
||||
const Banner: FC<BannerProps> = ({ type, message, className, isLoading }) => {
|
||||
const icon = type === 'success' ? <SuccessIcon /> : <ErrorIcon />;
|
||||
|
||||
return (
|
||||
<div className={classNames('message-banner-wrapper', type, className)}>
|
||||
{type === 'success' ? <SuccessIcon /> : <ErrorIcon />}
|
||||
{isLoading ? (
|
||||
<Spin
|
||||
className={`loading-spinner-${type}`}
|
||||
indicator={<LoadingOutlined spin />}
|
||||
size="small"
|
||||
/>
|
||||
) : (
|
||||
icon
|
||||
)}
|
||||
<span className="message-banner-text">{message}</span>
|
||||
</div>
|
||||
);
|
||||
|
@ -20,4 +20,8 @@
|
||||
background-color: @error-bg-color;
|
||||
color: @error-color;
|
||||
}
|
||||
|
||||
.loading-spinner-success {
|
||||
color: @success-color;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user