mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-07-22 08:50:27 +00:00
UI - feedback bug fixes and improvements (#12592)
* fixed loading issue in KPI widget on landing page * fixed redirection links for the notification box tabs * Fixed redirection issue after soft and hard deleting data assets * fixed version page layout issue * Fixed data model restore issue * Added loader to summary panel while fetching permissions * Fixed alerts settings page error placeholder alignment issue * changed the dashboard and pipeline url display method * fixed cypress test * updated the logic to perform the after delete action in DeleteWidgetModal * changed the logic to update the history object through util functions * added `experimentalMemoryManagement` to the cypress config * reverted the cypress config changes * fixed flaky test * worked on comments * removed unnecessary code
This commit is contained in:
parent
cb9e5d8b6f
commit
fe3766e106
@ -706,10 +706,12 @@ export const deleteSoftDeletedUser = (username) => {
|
||||
cy.get('[data-testid="search-error-placeholder"]').should('be.visible');
|
||||
};
|
||||
|
||||
export const toastNotification = (msg) => {
|
||||
export const toastNotification = (msg, closeToast = true) => {
|
||||
cy.get('.Toastify__toast-body').should('be.visible').contains(msg);
|
||||
cy.wait(200);
|
||||
cy.get('.Toastify__close-button').should('be.visible').click();
|
||||
if (closeToast) {
|
||||
cy.get('.Toastify__close-button').should('be.visible').click();
|
||||
}
|
||||
};
|
||||
|
||||
export const addCustomPropertiesForEntity = (
|
||||
|
@ -66,7 +66,7 @@ describe('Restore entity functionality should work properly', () => {
|
||||
cy.get('[data-testid="confirm-button"]').click();
|
||||
verifyResponseStatusCode('@softDeleteTable', 200);
|
||||
|
||||
toastNotification('Table deleted successfully!');
|
||||
toastNotification('Table deleted successfully!', false);
|
||||
});
|
||||
|
||||
it('Check Soft Deleted entity table', () => {
|
||||
|
@ -25,16 +25,17 @@ import { TOAST_OPTIONS } from 'constants/Toasts.constants';
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { HelmetProvider } from 'react-helmet-async';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { ToastContainer } from 'react-toastify';
|
||||
import 'react-toastify/dist/ReactToastify.min.css';
|
||||
import { history } from 'utils/HistoryUtils';
|
||||
import i18n from 'utils/i18next/LocalUtil';
|
||||
|
||||
const App: FunctionComponent = () => {
|
||||
return (
|
||||
<div className="main-container">
|
||||
<div className="content-wrapper" data-testid="content-wrapper">
|
||||
<Router>
|
||||
<Router history={history}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<ErrorBoundary>
|
||||
<ApplicationConfigProvider>
|
||||
|
@ -67,6 +67,7 @@ import {
|
||||
import { withActivityFeed } from 'components/router/withActivityFeed';
|
||||
import TableDescription from 'components/TableDescription/TableDescription.component';
|
||||
import { DisplayType } from 'components/Tag/TagsViewer/TagsViewer.interface';
|
||||
import { handleDataAssetAfterDeleteAction } from 'utils/Assets/AssetsUtils';
|
||||
|
||||
const DashboardDetails = ({
|
||||
charts,
|
||||
@ -723,6 +724,7 @@ const DashboardDetails = ({
|
||||
<Row gutter={[0, 12]}>
|
||||
<Col className="p-x-lg" span={24}>
|
||||
<DataAssetsHeader
|
||||
afterDeleteAction={handleDataAssetAfterDeleteAction}
|
||||
dataAsset={dashboardDetails}
|
||||
entityType={EntityType.DASHBOARD}
|
||||
permissions={dashboardPermissions}
|
||||
|
@ -104,6 +104,7 @@ export const ExtraInfoLink = ({
|
||||
|
||||
export const DataAssetsHeader = ({
|
||||
allowSoftDelete = true,
|
||||
afterDeleteAction,
|
||||
dataAsset,
|
||||
onOwnerUpdate,
|
||||
onTierUpdate,
|
||||
@ -403,6 +404,7 @@ export const DataAssetsHeader = ({
|
||||
/>
|
||||
</Tooltip>
|
||||
<ManageButton
|
||||
afterDeleteAction={afterDeleteAction}
|
||||
allowSoftDelete={!dataAsset.deleted && allowSoftDelete}
|
||||
canDelete={permissions.Delete}
|
||||
deleted={dataAsset.deleted}
|
||||
|
@ -75,6 +75,7 @@ export type DataAssetsHeaderProps = {
|
||||
permissions: OperationPermission;
|
||||
allowSoftDelete?: boolean;
|
||||
isRecursiveDelete?: boolean;
|
||||
afterDeleteAction?: (isSoftDelete?: boolean) => void;
|
||||
onTierUpdate: (tier?: string) => Promise<void>;
|
||||
onOwnerUpdate: (owner?: EntityReference) => Promise<void>;
|
||||
onVersionClick?: () => void;
|
||||
|
@ -37,7 +37,7 @@ function DataAssetsVersionHeader({
|
||||
|
||||
return (
|
||||
<Row className="p-x-lg" gutter={[8, 12]} justify="space-between">
|
||||
<Col className="self-center">
|
||||
<Col className="self-center" span={21}>
|
||||
<Row gutter={[16, 12]}>
|
||||
<Col span={24}>
|
||||
<TitleBreadcrumb titleLinks={breadcrumbLinks} />
|
||||
@ -83,14 +83,18 @@ function DataAssetsVersionHeader({
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col>
|
||||
<Button
|
||||
className="w-16 p-0"
|
||||
data-testid="version-button"
|
||||
icon={<Icon component={VersionIcon} />}
|
||||
onClick={onVersionClick}>
|
||||
<Typography.Text>{version}</Typography.Text>
|
||||
</Button>
|
||||
<Col span={3}>
|
||||
<Row justify="end">
|
||||
<Col>
|
||||
<Button
|
||||
className="w-16 p-0"
|
||||
data-testid="version-button"
|
||||
icon={<Icon component={VersionIcon} />}
|
||||
onClick={onVersionClick}>
|
||||
<Typography.Text>{version}</Typography.Text>
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
|
@ -43,6 +43,7 @@ import KPILatestResultsV1 from './KPILatestResultsV1';
|
||||
interface Props {
|
||||
kpiList: Array<Kpi>;
|
||||
selectedDays: number;
|
||||
isKPIListLoading: boolean;
|
||||
}
|
||||
|
||||
const EmptyPlaceholder = () => {
|
||||
@ -78,13 +79,13 @@ const EmptyPlaceholder = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const KPIChartV1: FC<Props> = ({ kpiList, selectedDays }) => {
|
||||
const KPIChartV1: FC<Props> = ({ isKPIListLoading, kpiList, selectedDays }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [kpiResults, setKpiResults] = useState<KpiResult[]>([]);
|
||||
const [kpiLatestResults, setKpiLatestResults] =
|
||||
useState<Record<string, UIKpiResult>>();
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const fetchKpiResults = useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
@ -180,7 +181,7 @@ const KPIChartV1: FC<Props> = ({ kpiList, selectedDays }) => {
|
||||
className="kpi-widget-card h-full"
|
||||
data-testid="kpi-card"
|
||||
id="kpi-charts"
|
||||
loading={isLoading}>
|
||||
loading={isKPIListLoading || isLoading}>
|
||||
<Row>
|
||||
<Col span={24}>
|
||||
<Typography.Text className="font-medium">
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
import { Card, Col, Row, Space, Tabs } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import { useActivityFeedProvider } from 'components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider';
|
||||
import { ActivityFeedTab } from 'components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component';
|
||||
import ActivityThreadPanel from 'components/ActivityFeed/ActivityThreadPanel/ActivityThreadPanel';
|
||||
@ -37,10 +38,13 @@ import { EntityTags } from 'Models';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { getFeedCounts } from 'utils/CommonUtils';
|
||||
import { restoreDataModel } from 'rest/dataModelsAPI';
|
||||
import { handleDataAssetAfterDeleteAction } from 'utils/Assets/AssetsUtils';
|
||||
import { getFeedCounts, refreshPage } from 'utils/CommonUtils';
|
||||
import { getEntityName, getEntityThreadLink } from 'utils/EntityUtils';
|
||||
import { getEntityFieldThreadCounts } from 'utils/FeedUtils';
|
||||
import { getTagsWithoutTier } from 'utils/TableUtils';
|
||||
import { showErrorToast, showSuccessToast } from 'utils/ToastUtils';
|
||||
import { DataModelDetailsProps } from './DataModelDetails.interface';
|
||||
import ModelTab from './ModelTab/ModelTab.component';
|
||||
|
||||
@ -159,6 +163,26 @@ const DataModelDetails = ({
|
||||
handleUpdateTags(updatedTags);
|
||||
};
|
||||
|
||||
const handleRestoreDataModel = async () => {
|
||||
try {
|
||||
await restoreDataModel(dataModelData.id ?? '');
|
||||
showSuccessToast(
|
||||
t('message.restore-entities-success', {
|
||||
entity: t('label.data-model'),
|
||||
}),
|
||||
2000
|
||||
);
|
||||
refreshPage();
|
||||
} catch (error) {
|
||||
showErrorToast(
|
||||
error as AxiosError,
|
||||
t('message.restore-entities-error', {
|
||||
entity: t('label.data-model'),
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const modelComponent = useMemo(() => {
|
||||
return (
|
||||
<Row gutter={[0, 16]} wrap={false}>
|
||||
@ -335,13 +359,14 @@ const DataModelDetails = ({
|
||||
<Row gutter={[0, 12]}>
|
||||
<Col className="p-x-lg" span={24}>
|
||||
<DataAssetsHeader
|
||||
afterDeleteAction={handleDataAssetAfterDeleteAction}
|
||||
dataAsset={dataModelData}
|
||||
entityType={EntityType.DASHBOARD_DATA_MODEL}
|
||||
permissions={dataModelPermissions}
|
||||
onDisplayNameUpdate={handleUpdateDisplayName}
|
||||
onFollowClick={handleFollowDataModel}
|
||||
onOwnerUpdate={handleUpdateOwner}
|
||||
onRestoreDataAsset={() => Promise.resolve()}
|
||||
onRestoreDataAsset={handleRestoreDataModel}
|
||||
onTierUpdate={handleUpdateTier}
|
||||
onVersionClick={versionHandler}
|
||||
/>
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
import { Drawer, Typography } from 'antd';
|
||||
import ErrorPlaceHolder from 'components/common/error-with-placeholder/ErrorPlaceHolder';
|
||||
import Loader from 'components/Loader/Loader';
|
||||
import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider';
|
||||
import {
|
||||
OperationPermission,
|
||||
@ -51,18 +52,22 @@ export default function EntitySummaryPanel({
|
||||
const { tab } = useParams<{ tab: string }>();
|
||||
|
||||
const { getEntityPermission } = usePermissionProvider();
|
||||
|
||||
const [isPermissionLoading, setIsPermissionLoading] =
|
||||
useState<boolean>(false);
|
||||
const [entityPermissions, setEntityPermissions] =
|
||||
useState<OperationPermission>(DEFAULT_ENTITY_PERMISSION);
|
||||
|
||||
const fetchResourcePermission = async (entityFqn: string) => {
|
||||
try {
|
||||
setIsPermissionLoading(true);
|
||||
const type =
|
||||
get(entityDetails, 'details.entityType') ?? ResourceEntity.TABLE;
|
||||
const permissions = await getEntityPermission(type, entityFqn);
|
||||
setEntityPermissions(permissions);
|
||||
} catch (error) {
|
||||
// Error
|
||||
} finally {
|
||||
setIsPermissionLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -78,6 +83,9 @@ export default function EntitySummaryPanel({
|
||||
);
|
||||
|
||||
const summaryComponent = useMemo(() => {
|
||||
if (isPermissionLoading) {
|
||||
return <Loader />;
|
||||
}
|
||||
if (!viewPermission) {
|
||||
return (
|
||||
<ErrorPlaceHolder
|
||||
@ -117,7 +125,7 @@ export default function EntitySummaryPanel({
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}, [tab, entityDetails, viewPermission]);
|
||||
}, [tab, entityDetails, viewPermission, isPermissionLoading]);
|
||||
|
||||
const entityLink = useMemo(
|
||||
() =>
|
||||
|
@ -22,14 +22,18 @@ import './kpi-widget.less';
|
||||
|
||||
const KPIWidget = () => {
|
||||
const [kpiList, setKpiList] = useState<Array<Kpi>>([]);
|
||||
const [isKPIListLoading, setIsKPIListLoading] = useState<boolean>(false);
|
||||
|
||||
const fetchKpiList = async () => {
|
||||
try {
|
||||
setIsKPIListLoading(true);
|
||||
const response = await getListKPIs({ fields: 'dataInsightChart' });
|
||||
setKpiList(response.data);
|
||||
} catch (_err) {
|
||||
setKpiList([]);
|
||||
showErrorToast(_err as AxiosError);
|
||||
} finally {
|
||||
setIsKPIListLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -41,7 +45,11 @@ const KPIWidget = () => {
|
||||
|
||||
return (
|
||||
<div className="kpi-widget-container h-full">
|
||||
<KPIChartV1 kpiList={kpiList} selectedDays={CHART_WIDGET_DAYS_DURATION} />
|
||||
<KPIChartV1
|
||||
isKPIListLoading={isKPIListLoading}
|
||||
kpiList={kpiList}
|
||||
selectedDays={CHART_WIDGET_DAYS_DURATION}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -34,6 +34,7 @@ import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { restoreMlmodel } from 'rest/mlModelAPI';
|
||||
import { handleDataAssetAfterDeleteAction } from 'utils/Assets/AssetsUtils';
|
||||
import { getEntityName, getEntityThreadLink } from 'utils/EntityUtils';
|
||||
import AppState from '../../AppState';
|
||||
import { getMlModelDetailsPath } from '../../constants/constants';
|
||||
@ -555,6 +556,7 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
|
||||
<Row gutter={[0, 12]}>
|
||||
<Col className="p-x-lg" span={24}>
|
||||
<DataAssetsHeader
|
||||
afterDeleteAction={handleDataAssetAfterDeleteAction}
|
||||
dataAsset={mlModelDetail}
|
||||
entityType={EntityType.MLMODEL}
|
||||
permissions={mlModelPermissions}
|
||||
|
@ -15,7 +15,6 @@ import { Badge, Button, List, Tabs, Typography } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ActivityFeedTabs } from 'components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.interface';
|
||||
import { EntityTabs } from 'enums/entity.enum';
|
||||
import { UserProfileTab } from 'enums/user.enum';
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -62,7 +61,7 @@ const NotificationBox = ({
|
||||
);
|
||||
|
||||
const notificationDropDownList = useMemo(() => {
|
||||
return notifications.slice(0, 5).map((feed, idx) => {
|
||||
return notifications.slice(0, 5).map((feed) => {
|
||||
const mainFeed = {
|
||||
message: feed.message,
|
||||
postTs: feed.threadTs,
|
||||
@ -79,7 +78,7 @@ const NotificationBox = ({
|
||||
entityFQN={entityFQN as string}
|
||||
entityType={entityType as string}
|
||||
feedType={feed.type || ThreadType.Conversation}
|
||||
key={`${mainFeed.from} ${idx}`}
|
||||
key={`${mainFeed.from} ${mainFeed.id}`}
|
||||
task={feed}
|
||||
timestamp={mainFeed.postTs}
|
||||
/>
|
||||
@ -117,11 +116,13 @@ const NotificationBox = ({
|
||||
getNotificationData(threadType, feedFilter);
|
||||
|
||||
setViewAllPath(
|
||||
`${getUserPath(currentUser?.name as string)}/${(threadType ===
|
||||
ThreadType.Conversation
|
||||
? UserProfileTab.ACTIVITY
|
||||
: threadType
|
||||
).toLowerCase()}?feedFilter=${feedFilter}`
|
||||
getUserPath(
|
||||
currentUser?.name as string,
|
||||
EntityTabs.ACTIVITY_FEED,
|
||||
key === NotificationTabsKey.TASK
|
||||
? ActivityFeedTabs.TASKS
|
||||
: ActivityFeedTabs.MENTIONS
|
||||
)
|
||||
);
|
||||
|
||||
if (hasTaskNotification || hasMentionNotification) {
|
||||
@ -132,7 +133,7 @@ const NotificationBox = ({
|
||||
}, NOTIFICATION_READ_TIMER);
|
||||
}
|
||||
},
|
||||
[currentUser, hasTaskNotification, hasMentionNotification]
|
||||
[onTabChange, currentUser, hasTaskNotification, hasMentionNotification]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -187,7 +188,7 @@ const NotificationBox = ({
|
||||
size="small"
|
||||
/>
|
||||
),
|
||||
[notifications]
|
||||
[notifications, notificationDropDownList, viewAllPath]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -43,6 +43,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Link, useHistory, useParams } from 'react-router-dom';
|
||||
import { postThread } from 'rest/feedsAPI';
|
||||
import { restorePipeline } from 'rest/pipelineAPI';
|
||||
import { handleDataAssetAfterDeleteAction } from 'utils/Assets/AssetsUtils';
|
||||
import { ReactComponent as ExternalLinkIcon } from '../../assets/svg/external-links.svg';
|
||||
import {
|
||||
getPipelineDetailsPath,
|
||||
@ -746,6 +747,7 @@ const PipelineDetails = ({
|
||||
<Row gutter={[0, 12]}>
|
||||
<Col className="p-x-lg" span={24}>
|
||||
<DataAssetsHeader
|
||||
afterDeleteAction={handleDataAssetAfterDeleteAction}
|
||||
dataAsset={pipelineDetails}
|
||||
entityType={EntityType.PIPELINE}
|
||||
permissions={pipelinePermissions}
|
||||
|
@ -36,6 +36,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { restoreTopic } from 'rest/topicsAPI';
|
||||
import { handleDataAssetAfterDeleteAction } from 'utils/Assets/AssetsUtils';
|
||||
import { getEntityName, getEntityThreadLink } from 'utils/EntityUtils';
|
||||
import { EntityField } from '../../constants/Feeds.constants';
|
||||
import { EntityTabs, EntityType } from '../../enums/entity.enum';
|
||||
@ -450,6 +451,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
|
||||
<Row gutter={[0, 12]}>
|
||||
<Col className="p-x-lg" span={24}>
|
||||
<DataAssetsHeader
|
||||
afterDeleteAction={handleDataAssetAfterDeleteAction}
|
||||
dataAsset={topicDetails}
|
||||
entityType={EntityType.TOPIC}
|
||||
permissions={topicPermissions}
|
||||
|
@ -24,7 +24,7 @@ export interface DeleteWidgetModalProps {
|
||||
entityId?: string;
|
||||
prepareType?: boolean;
|
||||
isRecursiveDelete?: boolean;
|
||||
afterDeleteAction?: () => void;
|
||||
afterDeleteAction?: (isSoftDelete?: boolean) => void;
|
||||
}
|
||||
|
||||
export interface DeleteSectionProps {
|
||||
|
@ -22,15 +22,13 @@ import React, {
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { deleteEntity } from 'rest/miscAPI';
|
||||
import { ENTITY_DELETE_STATE } from '../../../constants/entity.constants';
|
||||
import { EntityType } from '../../../enums/entity.enum';
|
||||
import {
|
||||
getEntityDeleteMessage,
|
||||
Transi18next,
|
||||
} from '../../../utils/CommonUtils';
|
||||
import { getTitleCase } from '../../../utils/EntityUtils';
|
||||
getDeleteMessage,
|
||||
prepareEntityType,
|
||||
} from 'utils/DeleteWidgetModalUtils';
|
||||
import { ENTITY_DELETE_STATE } from '../../../constants/entity.constants';
|
||||
import { Transi18next } from '../../../utils/CommonUtils';
|
||||
import { showErrorToast, showSuccessToast } from '../../../utils/ToastUtils';
|
||||
import { DeleteType, DeleteWidgetModalProps } from './DeleteWidget.interface';
|
||||
|
||||
@ -49,7 +47,6 @@ const DeleteWidgetModal = ({
|
||||
afterDeleteAction,
|
||||
}: DeleteWidgetModalProps) => {
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
const [entityDeleteState, setEntityDeleteState] =
|
||||
useState<typeof ENTITY_DELETE_STATE>(ENTITY_DELETE_STATE);
|
||||
const [name, setName] = useState<string>('');
|
||||
@ -58,123 +55,95 @@ const DeleteWidgetModal = ({
|
||||
);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const prepareDeleteMessage = (softDelete = false) => {
|
||||
const softDeleteText = t('message.soft-delete-message-for-entity', {
|
||||
entity: entityName,
|
||||
});
|
||||
const hardDeleteText = getEntityDeleteMessage(getTitleCase(entityType), '');
|
||||
const DELETE_OPTION = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: `${t('label.delete')} ${entityType} “${entityName}”`,
|
||||
description: `${getDeleteMessage(
|
||||
entityName,
|
||||
entityType,
|
||||
true
|
||||
)} ${softDeleteMessagePostFix}`,
|
||||
type: DeleteType.SOFT_DELETE,
|
||||
isAllowed: allowSoftDelete,
|
||||
},
|
||||
{
|
||||
title: `${t('label.permanently-delete')} ${entityType} “${entityName}”`,
|
||||
description: `${
|
||||
deleteMessage || getDeleteMessage(entityName, entityType)
|
||||
} ${hardDeleteMessagePostFix}`,
|
||||
type: DeleteType.HARD_DELETE,
|
||||
isAllowed: true,
|
||||
},
|
||||
],
|
||||
[
|
||||
entityType,
|
||||
entityName,
|
||||
softDeleteMessagePostFix,
|
||||
allowSoftDelete,
|
||||
deleteMessage,
|
||||
hardDeleteMessagePostFix,
|
||||
]
|
||||
);
|
||||
|
||||
return softDelete ? softDeleteText : hardDeleteText;
|
||||
};
|
||||
|
||||
const DELETE_OPTION = [
|
||||
{
|
||||
title: `${t('label.delete')} ${entityType} “${entityName}”`,
|
||||
description: `${prepareDeleteMessage(true)} ${softDeleteMessagePostFix}`,
|
||||
type: DeleteType.SOFT_DELETE,
|
||||
isAllowd: allowSoftDelete,
|
||||
},
|
||||
{
|
||||
title: `${t('label.permanently-delete')} ${entityType} “${entityName}”`,
|
||||
description: `${
|
||||
deleteMessage || prepareDeleteMessage()
|
||||
} ${hardDeleteMessagePostFix}`,
|
||||
type: DeleteType.HARD_DELETE,
|
||||
isAllowd: true,
|
||||
},
|
||||
];
|
||||
|
||||
const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const handleOnChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
||||
setName(e.target.value);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleOnEntityDelete = (softDelete = true) => {
|
||||
const handleOnEntityDelete = useCallback((softDelete = true) => {
|
||||
setEntityDeleteState((prev) => ({ ...prev, state: true, softDelete }));
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleOnEntityDeleteCancel = () => {
|
||||
const handleOnEntityDeleteCancel = useCallback(() => {
|
||||
setEntityDeleteState(ENTITY_DELETE_STATE);
|
||||
setName('');
|
||||
setValue(DeleteType.SOFT_DELETE);
|
||||
onCancel();
|
||||
};
|
||||
}, [onCancel]);
|
||||
|
||||
const prepareEntityType = () => {
|
||||
const services = [
|
||||
EntityType.DASHBOARD_SERVICE,
|
||||
EntityType.DATABASE_SERVICE,
|
||||
EntityType.MESSAGING_SERVICE,
|
||||
EntityType.PIPELINE_SERVICE,
|
||||
EntityType.METADATA_SERVICE,
|
||||
EntityType.STORAGE_SERVICE,
|
||||
EntityType.MLMODEL_SERVICE,
|
||||
];
|
||||
const handleOnEntityDeleteConfirm = useCallback(async () => {
|
||||
try {
|
||||
setIsLoading(false);
|
||||
setEntityDeleteState((prev) => ({ ...prev, loading: 'waiting' }));
|
||||
const response = await deleteEntity(
|
||||
prepareType ? prepareEntityType(entityType) : entityType,
|
||||
entityId ?? '',
|
||||
Boolean(isRecursiveDelete),
|
||||
!entityDeleteState.softDelete
|
||||
);
|
||||
|
||||
const dataQuality = [EntityType.TEST_SUITE, EntityType.TEST_CASE];
|
||||
|
||||
if (services.includes((entityType || '') as EntityType)) {
|
||||
return `services/${entityType}s`;
|
||||
} else if (entityType === EntityType.GLOSSARY) {
|
||||
return `glossaries`;
|
||||
} else if (entityType === EntityType.POLICY) {
|
||||
return 'policies';
|
||||
} else if (entityType === EntityType.KPI) {
|
||||
return entityType;
|
||||
} else if (entityType === EntityType.DASHBOARD_DATA_MODEL) {
|
||||
return `dashboard/datamodels`;
|
||||
} else if (dataQuality.includes(entityType as EntityType)) {
|
||||
return `dataQuality/${entityType}s`;
|
||||
} else if (entityType === EntityType.SUBSCRIPTION) {
|
||||
return `events/${entityType}s`;
|
||||
} else {
|
||||
return `${entityType}s`;
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnEntityDeleteConfirm = () => {
|
||||
setIsLoading(false);
|
||||
setEntityDeleteState((prev) => ({ ...prev, loading: 'waiting' }));
|
||||
deleteEntity(
|
||||
prepareType ? prepareEntityType() : entityType,
|
||||
entityId ?? '',
|
||||
Boolean(isRecursiveDelete),
|
||||
!entityDeleteState.softDelete
|
||||
)
|
||||
.then((res) => {
|
||||
if (res.status === 200) {
|
||||
setTimeout(() => {
|
||||
handleOnEntityDeleteCancel();
|
||||
showSuccessToast(
|
||||
t('server.entity-deleted-successfully', {
|
||||
entity: startCase(entityType),
|
||||
})
|
||||
);
|
||||
|
||||
if (afterDeleteAction) {
|
||||
afterDeleteAction();
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
history.push('/');
|
||||
}, 500);
|
||||
}
|
||||
}, 1000);
|
||||
} else {
|
||||
showErrorToast(t('server.unexpected-response'));
|
||||
}
|
||||
})
|
||||
.catch((error: AxiosError) => {
|
||||
showErrorToast(
|
||||
error,
|
||||
t('server.delete-entity-error', {
|
||||
entity: entityName,
|
||||
if (response.status === 200) {
|
||||
showSuccessToast(
|
||||
t('server.entity-deleted-successfully', {
|
||||
entity: startCase(entityType),
|
||||
})
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
handleOnEntityDeleteCancel();
|
||||
setIsLoading(false);
|
||||
});
|
||||
};
|
||||
if (afterDeleteAction) {
|
||||
afterDeleteAction(entityDeleteState.softDelete);
|
||||
}
|
||||
} else {
|
||||
showErrorToast(t('server.unexpected-response'));
|
||||
}
|
||||
} catch (error) {
|
||||
showErrorToast(
|
||||
error as AxiosError,
|
||||
t('server.delete-entity-error', {
|
||||
entity: entityName,
|
||||
})
|
||||
);
|
||||
} finally {
|
||||
handleOnEntityDeleteCancel();
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [
|
||||
entityType,
|
||||
entityId,
|
||||
isRecursiveDelete,
|
||||
entityDeleteState,
|
||||
afterDeleteAction,
|
||||
entityName,
|
||||
handleOnEntityDeleteCancel,
|
||||
]);
|
||||
|
||||
const isNameMatching = useCallback(() => {
|
||||
return (
|
||||
@ -183,11 +152,14 @@ const DeleteWidgetModal = ({
|
||||
);
|
||||
}, [name]);
|
||||
|
||||
const onChange = (e: RadioChangeEvent) => {
|
||||
const value = e.target.value;
|
||||
setValue(value);
|
||||
handleOnEntityDelete(value === DeleteType.SOFT_DELETE);
|
||||
};
|
||||
const onChange = useCallback(
|
||||
(e: RadioChangeEvent) => {
|
||||
const value = e.target.value;
|
||||
setValue(value);
|
||||
handleOnEntityDelete(value === DeleteType.SOFT_DELETE);
|
||||
},
|
||||
[handleOnEntityDelete]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setValue(allowSoftDelete ? DeleteType.SOFT_DELETE : DeleteType.HARD_DELETE);
|
||||
@ -217,7 +189,12 @@ const DeleteWidgetModal = ({
|
||||
</Button>
|
||||
</Space>
|
||||
);
|
||||
}, [entityDeleteState, isNameMatching]);
|
||||
}, [
|
||||
entityDeleteState,
|
||||
handleOnEntityDeleteCancel,
|
||||
handleOnEntityDeleteConfirm,
|
||||
isNameMatching,
|
||||
]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@ -233,7 +210,7 @@ const DeleteWidgetModal = ({
|
||||
<Radio.Group value={value} onChange={onChange}>
|
||||
{DELETE_OPTION.map(
|
||||
(option) =>
|
||||
option.isAllowd && (
|
||||
option.isAllowed && (
|
||||
<Radio
|
||||
data-testid={option.type}
|
||||
key={option.type}
|
||||
|
@ -33,7 +33,7 @@ import './ManageButton.less';
|
||||
|
||||
interface Props {
|
||||
allowSoftDelete?: boolean;
|
||||
afterDeleteAction?: () => void;
|
||||
afterDeleteAction?: (isSoftDelete?: boolean) => void;
|
||||
buttonClassName?: string;
|
||||
entityName: string;
|
||||
entityId?: string;
|
||||
|
@ -167,29 +167,6 @@ const AlertsPage = () => {
|
||||
[]
|
||||
);
|
||||
|
||||
if (loading) {
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
if (isEmpty(alerts)) {
|
||||
return (
|
||||
<ErrorPlaceHolder
|
||||
permission
|
||||
doc={ALERTS_DOCS}
|
||||
heading={t('label.alert')}
|
||||
type={ERROR_PLACEHOLDER_TYPE.CREATE}
|
||||
onClick={() =>
|
||||
history.push(
|
||||
getSettingPath(
|
||||
GlobalSettingsMenuCategory.NOTIFICATIONS,
|
||||
GlobalSettingOptions.ADD_ALERTS
|
||||
)
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Row gutter={[16, 16]}>
|
||||
@ -212,6 +189,29 @@ const AlertsPage = () => {
|
||||
bordered
|
||||
columns={columns}
|
||||
dataSource={alerts}
|
||||
loading={{
|
||||
spinning: loading,
|
||||
indicator: <Loader size="small" />,
|
||||
}}
|
||||
locale={{
|
||||
emptyText: !loading && (
|
||||
<ErrorPlaceHolder
|
||||
permission
|
||||
className="p-y-md"
|
||||
doc={ALERTS_DOCS}
|
||||
heading={t('label.alert')}
|
||||
type={ERROR_PLACEHOLDER_TYPE.CREATE}
|
||||
onClick={() =>
|
||||
history.push(
|
||||
getSettingPath(
|
||||
GlobalSettingsMenuCategory.NOTIFICATIONS,
|
||||
GlobalSettingOptions.ADD_ALERTS
|
||||
)
|
||||
)
|
||||
}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
pagination={false}
|
||||
rowKey="id"
|
||||
size="middle"
|
||||
|
@ -60,6 +60,7 @@ import {
|
||||
removeContainerFollower,
|
||||
restoreContainer,
|
||||
} from 'rest/storageAPI';
|
||||
import { handleDataAssetAfterDeleteAction } from 'utils/Assets/AssetsUtils';
|
||||
import {
|
||||
addToRecentViewed,
|
||||
getCurrentUserId,
|
||||
@ -690,6 +691,7 @@ const ContainerPage = () => {
|
||||
<Row gutter={[0, 12]}>
|
||||
<Col className="p-x-lg" span={24}>
|
||||
<DataAssetsHeader
|
||||
afterDeleteAction={handleDataAssetAfterDeleteAction}
|
||||
dataAsset={containerData}
|
||||
entityType={EntityType.CONTAINER}
|
||||
permissions={containerPermissions}
|
||||
|
@ -22,7 +22,7 @@ import { EmptyGraphPlaceholder } from 'components/DataInsightDetail/EmptyGraphPl
|
||||
import Loader from 'components/Loader/Loader';
|
||||
import { ERROR_PLACEHOLDER_TYPE } from 'enums/common.enum';
|
||||
import { isUndefined } from 'lodash';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
import { getListKPIs } from 'rest/KpiAPI';
|
||||
@ -184,6 +184,10 @@ const KPIList = ({ viewKPIPermission }: { viewKPIPermission: boolean }) => {
|
||||
fetchKpiList();
|
||||
}, []);
|
||||
|
||||
const handleAfterDeleteAction = useCallback(() => {
|
||||
fetchKpiList();
|
||||
}, [fetchKpiList]);
|
||||
|
||||
const noDataPlaceHolder = useMemo(
|
||||
() =>
|
||||
viewKPIPermission ? (
|
||||
@ -225,7 +229,7 @@ const KPIList = ({ viewKPIPermission }: { viewKPIPermission: boolean }) => {
|
||||
|
||||
{selectedKpi && (
|
||||
<DeleteWidgetModal
|
||||
afterDeleteAction={fetchKpiList}
|
||||
afterDeleteAction={handleAfterDeleteAction}
|
||||
allowSoftDelete={false}
|
||||
deleteMessage={`Are you sure you want to delete ${getEntityName(
|
||||
selectedKpi
|
||||
|
@ -60,6 +60,7 @@ import {
|
||||
restoreDatabase,
|
||||
} from 'rest/databaseAPI';
|
||||
import { getFeedCount, postThread } from 'rest/feedsAPI';
|
||||
import { handleDataAssetAfterDeleteAction } from 'utils/Assets/AssetsUtils';
|
||||
import { default as appState } from '../../AppState';
|
||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||
import {
|
||||
@ -748,8 +749,8 @@ const DatabaseDetails: FunctionComponent = () => {
|
||||
<Row gutter={[0, 12]}>
|
||||
<Col className="p-x-lg" span={24}>
|
||||
<DataAssetsHeader
|
||||
allowSoftDelete
|
||||
isRecursiveDelete
|
||||
afterDeleteAction={handleDataAssetAfterDeleteAction}
|
||||
dataAsset={database}
|
||||
entityType={EntityType.DATABASE}
|
||||
permissions={databasePermission}
|
||||
|
@ -55,6 +55,7 @@ import {
|
||||
} from 'rest/databaseAPI';
|
||||
import { getFeedCount, postThread } from 'rest/feedsAPI';
|
||||
import { getTableList, TableListParams } from 'rest/tableAPI';
|
||||
import { handleDataAssetAfterDeleteAction } from 'utils/Assets/AssetsUtils';
|
||||
import { default as appState } from '../../AppState';
|
||||
import { getDatabaseSchemaDetailsPath } from '../../constants/constants';
|
||||
import { EntityTabs, EntityType } from '../../enums/entity.enum';
|
||||
@ -557,8 +558,8 @@ const DatabaseSchemaPage: FunctionComponent = () => {
|
||||
/>
|
||||
) : (
|
||||
<DataAssetsHeader
|
||||
allowSoftDelete
|
||||
isRecursiveDelete
|
||||
afterDeleteAction={handleDataAssetAfterDeleteAction}
|
||||
dataAsset={databaseSchema}
|
||||
entityType={EntityType.DATABASE_SCHEMA}
|
||||
permissions={databaseSchemaPermission}
|
||||
|
@ -18,7 +18,7 @@ import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichText
|
||||
import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider';
|
||||
import { ResourceEntity } from 'components/PermissionProvider/PermissionProvider.interface';
|
||||
import { isEmpty, isUndefined, uniqueId } from 'lodash';
|
||||
import React, { FC, useMemo, useState } from 'react';
|
||||
import React, { FC, useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getEntityName } from 'utils/EntityUtils';
|
||||
@ -181,6 +181,10 @@ const PoliciesList: FC<PolicyListProps> = ({ policies, fetchPolicies }) => {
|
||||
];
|
||||
}, []);
|
||||
|
||||
const handleAfterDeleteAction = useCallback(() => {
|
||||
fetchPolicies();
|
||||
}, [fetchPolicies]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Table
|
||||
@ -195,7 +199,7 @@ const PoliciesList: FC<PolicyListProps> = ({ policies, fetchPolicies }) => {
|
||||
/>
|
||||
{selectedPolicy && deletePolicyPermission && (
|
||||
<DeleteWidgetModal
|
||||
afterDeleteAction={fetchPolicies}
|
||||
afterDeleteAction={handleAfterDeleteAction}
|
||||
allowSoftDelete={false}
|
||||
deleteMessage={t('message.are-you-sure-delete-entity', {
|
||||
entity: getEntityName(selectedPolicy),
|
||||
|
@ -18,7 +18,7 @@ import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichText
|
||||
import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider';
|
||||
import { ResourceEntity } from 'components/PermissionProvider/PermissionProvider.interface';
|
||||
import { isEmpty, isUndefined, uniqueId } from 'lodash';
|
||||
import React, { FC, useMemo, useState } from 'react';
|
||||
import React, { FC, useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getEntityName } from 'utils/EntityUtils';
|
||||
@ -178,6 +178,10 @@ const RolesList: FC<RolesListProps> = ({ roles, fetchRoles }) => {
|
||||
];
|
||||
}, []);
|
||||
|
||||
const handleAfterDeleteAction = useCallback(() => {
|
||||
fetchRoles();
|
||||
}, [fetchRoles]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Table
|
||||
@ -192,7 +196,7 @@ const RolesList: FC<RolesListProps> = ({ roles, fetchRoles }) => {
|
||||
/>
|
||||
{selectedRole && (
|
||||
<DeleteWidgetModal
|
||||
afterDeleteAction={fetchRoles}
|
||||
afterDeleteAction={handleAfterDeleteAction}
|
||||
allowSoftDelete={false}
|
||||
deleteMessage={t('message.are-you-sure-delete-entity', {
|
||||
entity: getEntityName(selectedRole),
|
||||
|
@ -72,6 +72,7 @@ import {
|
||||
removeFollower,
|
||||
restoreTable,
|
||||
} from 'rest/tableAPI';
|
||||
import { handleDataAssetAfterDeleteAction } from 'utils/Assets/AssetsUtils';
|
||||
import {
|
||||
addToRecentViewed,
|
||||
getCurrentUserId,
|
||||
@ -887,6 +888,7 @@ const TableDetailsPageV1 = () => {
|
||||
{/* Entity Heading */}
|
||||
<Col className="p-x-lg" data-testid="entity-page-header" span={24}>
|
||||
<DataAssetsHeader
|
||||
afterDeleteAction={handleDataAssetAfterDeleteAction}
|
||||
dataAsset={tableDetails}
|
||||
entityType={EntityType.TABLE}
|
||||
permissions={tablePermissions}
|
||||
|
@ -16,6 +16,7 @@ import { DashboardDataModel } from 'generated/entity/data/dashboardDataModel';
|
||||
import { EntityHistory } from 'generated/type/entityHistory';
|
||||
import { EntityReference } from 'generated/type/entityReference';
|
||||
import { Include } from 'generated/type/include';
|
||||
import { RestoreRequestType } from 'Models';
|
||||
import { getURLWithQueryFields } from 'utils/APIUtils';
|
||||
import APIClient from './index';
|
||||
|
||||
@ -117,3 +118,12 @@ export const getDataModelVersion = async (id: string, version: string) => {
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const restoreDataModel = async (id: string) => {
|
||||
const response = await APIClient.put<
|
||||
RestoreRequestType,
|
||||
AxiosResponse<DashboardDataModel>
|
||||
>('/dashboard/datamodels/restore', { id });
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
@ -22,6 +22,7 @@ import { getPipelineByFqn, patchPipelineDetails } from 'rest/pipelineAPI';
|
||||
import { getContainerByName, patchContainerDetails } from 'rest/storageAPI';
|
||||
import { getTableDetailsByFQN, patchTableDetails } from 'rest/tableAPI';
|
||||
import { getTopicByFqn, patchTopicDetails } from 'rest/topicsAPI';
|
||||
import { history } from 'utils/HistoryUtils';
|
||||
|
||||
export const getAPIfromSource = (
|
||||
source: AssetsUnion
|
||||
@ -66,3 +67,13 @@ export const getEntityAPIfromSource = (
|
||||
return getContainerByName;
|
||||
}
|
||||
};
|
||||
|
||||
export const handleDataAssetAfterDeleteAction = (isSoftDelete?: boolean) => {
|
||||
if (isSoftDelete) {
|
||||
setTimeout(() => {
|
||||
history.go(0);
|
||||
}, 1000);
|
||||
} else {
|
||||
history.push('/');
|
||||
}
|
||||
};
|
||||
|
@ -76,6 +76,7 @@ import { TagLabel } from '../generated/type/tagLabel';
|
||||
import { EntityFieldThreadCount } from '../interface/feed.interface';
|
||||
import { getEntityFeedLink, getTitleCase } from './EntityUtils';
|
||||
import Fqn from './Fqn';
|
||||
import { history } from './HistoryUtils';
|
||||
import { serviceTypeLogo } from './ServiceUtils';
|
||||
import { TASK_ENTITIES } from './TasksUtils';
|
||||
import { showErrorToast } from './ToastUtils';
|
||||
@ -701,7 +702,9 @@ export const getLoadingStatus = (
|
||||
);
|
||||
};
|
||||
|
||||
export const refreshPage = () => window.location.reload();
|
||||
export const refreshPage = () => {
|
||||
history.go(0);
|
||||
};
|
||||
// return array of id as strings
|
||||
export const getEntityIdArray = (entities: EntityReference[]): string[] =>
|
||||
entities.map((item) => item.id);
|
||||
|
@ -46,6 +46,7 @@ import {
|
||||
getBreadcrumbForEntitiesWithServiceOnly,
|
||||
getBreadcrumbForTable,
|
||||
getEntityBreadcrumbs,
|
||||
getEntityName,
|
||||
} from './EntityUtils';
|
||||
import { bytesToSize } from './StringsUtils';
|
||||
import { getUsagePercentile } from './TableUtils';
|
||||
@ -92,8 +93,8 @@ export const getDataAssetsHeaderInfo = (
|
||||
{dashboardDetails.sourceUrl && (
|
||||
<ExtraInfoLink
|
||||
href={dashboardDetails.sourceUrl}
|
||||
label={entityName}
|
||||
value={dashboardDetails.sourceUrl}
|
||||
label=""
|
||||
value={getEntityName(dashboardDetails)}
|
||||
/>
|
||||
)}
|
||||
{dashboardDetails.dashboardType && (
|
||||
@ -126,7 +127,7 @@ export const getDataAssetsHeaderInfo = (
|
||||
<ExtraInfoLink
|
||||
href={pipelineDetails.sourceUrl}
|
||||
label=""
|
||||
value={pipelineDetails.sourceUrl}
|
||||
value={getEntityName(pipelineDetails)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EntityType } from 'enums/entity.enum';
|
||||
import { t } from 'i18next';
|
||||
import { getEntityDeleteMessage } from './CommonUtils';
|
||||
import { getTitleCase } from './EntityUtils';
|
||||
|
||||
export const prepareEntityType = (entityType: string) => {
|
||||
const services = [
|
||||
EntityType.DASHBOARD_SERVICE,
|
||||
EntityType.DATABASE_SERVICE,
|
||||
EntityType.MESSAGING_SERVICE,
|
||||
EntityType.PIPELINE_SERVICE,
|
||||
EntityType.METADATA_SERVICE,
|
||||
EntityType.STORAGE_SERVICE,
|
||||
EntityType.MLMODEL_SERVICE,
|
||||
];
|
||||
|
||||
const dataQuality = [EntityType.TEST_SUITE, EntityType.TEST_CASE];
|
||||
|
||||
if (services.includes((entityType || '') as EntityType)) {
|
||||
return `services/${entityType}s`;
|
||||
} else if (entityType === EntityType.GLOSSARY) {
|
||||
return `glossaries`;
|
||||
} else if (entityType === EntityType.POLICY) {
|
||||
return 'policies';
|
||||
} else if (entityType === EntityType.KPI) {
|
||||
return entityType;
|
||||
} else if (entityType === EntityType.DASHBOARD_DATA_MODEL) {
|
||||
return `dashboard/datamodels`;
|
||||
} else if (dataQuality.includes(entityType as EntityType)) {
|
||||
return `dataQuality/${entityType}s`;
|
||||
} else if (entityType === EntityType.SUBSCRIPTION) {
|
||||
return `events/${entityType}s`;
|
||||
} else {
|
||||
return `${entityType}s`;
|
||||
}
|
||||
};
|
||||
|
||||
export const getDeleteMessage = (
|
||||
entityName: string,
|
||||
entityType: string,
|
||||
softDelete = false
|
||||
) => {
|
||||
const softDeleteText = t('message.soft-delete-message-for-entity', {
|
||||
entity: entityName,
|
||||
});
|
||||
const hardDeleteText = getEntityDeleteMessage(getTitleCase(entityType), '');
|
||||
|
||||
return softDelete ? softDeleteText : hardDeleteText;
|
||||
};
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createBrowserHistory } from 'history';
|
||||
|
||||
export const history = createBrowserHistory();
|
Loading…
x
Reference in New Issue
Block a user