mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-31 12:32:26 +00:00
MINOR: supported full fqn based breadcrumb in bulk import/edit page (#20358)
* supported full fqn based breadcrumb in bulk import/edit page * fix the loading infinite * revert unwanted code * fix bulk edit playwright test
This commit is contained in:
parent
f8d87185f3
commit
2e1cf3a734
@ -13,23 +13,20 @@
|
||||
import ReactDataGrid from '@inovua/reactdatagrid-community';
|
||||
import { Button, Col, Row } from 'antd';
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { readString } from 'react-papaparse';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { ENTITY_BULK_EDIT_STEPS } from '../../constants/BulkEdit.constants';
|
||||
import { ExportTypes } from '../../constants/Export.constants';
|
||||
import { EntityType } from '../../enums/entity.enum';
|
||||
import { useFqn } from '../../hooks/useFqn';
|
||||
import {
|
||||
getBulkEditCSVExportEntityApi,
|
||||
getBulkEntityEditBreadcrumbList,
|
||||
} from '../../utils/EntityBulkEdit/EntityBulkEditUtils';
|
||||
import { getBulkEditCSVExportEntityApi } from '../../utils/EntityBulkEdit/EntityBulkEditUtils';
|
||||
import entityUtilClassBase from '../../utils/EntityUtilClassBase';
|
||||
import Banner from '../common/Banner/Banner';
|
||||
import { ImportStatus } from '../common/EntityImport/ImportStatus/ImportStatus.component';
|
||||
import Loader from '../common/Loader/Loader';
|
||||
import TitleBreadcrumb from '../common/TitleBreadcrumb/TitleBreadcrumb.component';
|
||||
import { TitleBreadcrumbProps } from '../common/TitleBreadcrumb/TitleBreadcrumb.interface';
|
||||
import { useEntityExportModalProvider } from '../Entity/EntityExportModalProvider/EntityExportModalProvider.component';
|
||||
import Stepper from '../Settings/Services/Ingestion/IngestionStepper/IngestionStepper.component';
|
||||
import { BulkEditEntityProps } from './BulkEditEntity.interface';
|
||||
@ -41,6 +38,7 @@ const BulkEditEntity = ({
|
||||
onEditComplete,
|
||||
dataSource,
|
||||
columns,
|
||||
breadcrumbList,
|
||||
setGridRef,
|
||||
activeStep,
|
||||
handleBack,
|
||||
@ -52,15 +50,16 @@ const BulkEditEntity = ({
|
||||
onCSVReadComplete,
|
||||
}: BulkEditEntityProps) => {
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
const { fqn } = useFqn();
|
||||
const { entityType } = useParams<{ entityType: EntityType }>();
|
||||
const { triggerExportForBulkEdit, csvExportData, clearCSVExportData } =
|
||||
useEntityExportModalProvider();
|
||||
|
||||
const breadcrumbList: TitleBreadcrumbProps['titleLinks'] = useMemo(
|
||||
() => getBulkEntityEditBreadcrumbList(entityType, fqn),
|
||||
[entityType, fqn]
|
||||
);
|
||||
const handleCancel = () => {
|
||||
clearCSVExportData();
|
||||
history.push(entityUtilClassBase.getEntityLink(entityType, fqn));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
triggerExportForBulkEdit({
|
||||
@ -159,6 +158,12 @@ const BulkEditEntity = ({
|
||||
{activeStep > 0 && (
|
||||
<Col span={24}>
|
||||
<div className="float-right import-footer">
|
||||
{activeStep === 1 && (
|
||||
<Button disabled={isValidating} onClick={handleCancel}>
|
||||
{t('label.cancel')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{activeStep > 1 && (
|
||||
<Button disabled={isValidating} onClick={handleBack}>
|
||||
{t('label.previous')}
|
||||
|
@ -17,10 +17,12 @@ import {
|
||||
import { VALIDATION_STEP } from '../../constants/BulkImport.constant';
|
||||
import { CSVImportResult } from '../../generated/type/csvImportResult';
|
||||
import { CSVImportJobType } from '../BulkImport/BulkEntityImport.interface';
|
||||
import { TitleBreadcrumbProps } from '../common/TitleBreadcrumb/TitleBreadcrumb.interface';
|
||||
|
||||
export interface BulkEditEntityProps {
|
||||
dataSource: Record<string, string>[];
|
||||
columns: TypeColumn[];
|
||||
breadcrumbList: TitleBreadcrumbProps['titleLinks'];
|
||||
activeStep: VALIDATION_STEP;
|
||||
activeAsyncImportJob?: CSVImportJobType;
|
||||
isValidating: boolean;
|
||||
|
@ -81,6 +81,9 @@ export const EntityExportModalProvider = ({
|
||||
|
||||
const handleCancel = () => {
|
||||
setExportData(null);
|
||||
setCSVExportData(undefined);
|
||||
setCSVExportJob(undefined);
|
||||
csvExportJobRef.current = undefined;
|
||||
};
|
||||
|
||||
const showModal = (data: ExportData) => {
|
||||
@ -167,11 +170,9 @@ export const EntityExportModalProvider = ({
|
||||
data,
|
||||
fileName ?? `${exportData?.name}_${getCurrentISODate()}`
|
||||
);
|
||||
handleCancel();
|
||||
}
|
||||
setDownloading(false);
|
||||
handleCancel();
|
||||
setCSVExportJob(undefined);
|
||||
csvExportJobRef.current = undefined;
|
||||
},
|
||||
[isBulkEdit]
|
||||
);
|
||||
@ -222,7 +223,7 @@ export const EntityExportModalProvider = ({
|
||||
const providerValue = useMemo(
|
||||
() => ({
|
||||
csvExportData,
|
||||
clearCSVExportData: () => setCSVExportData(undefined),
|
||||
clearCSVExportData: handleCancel,
|
||||
showModal,
|
||||
triggerExportForBulkEdit: (exportData: ExportData) => {
|
||||
setExportData(exportData);
|
||||
|
@ -39,6 +39,7 @@ import Banner from '../../../components/common/Banner/Banner';
|
||||
import { ImportStatus } from '../../../components/common/EntityImport/ImportStatus/ImportStatus.component';
|
||||
import TitleBreadcrumb from '../../../components/common/TitleBreadcrumb/TitleBreadcrumb.component';
|
||||
import { TitleBreadcrumbProps } from '../../../components/common/TitleBreadcrumb/TitleBreadcrumb.interface';
|
||||
import { DataAssetsHeaderProps } from '../../../components/DataAssets/DataAssetsHeader/DataAssetsHeader.interface';
|
||||
import PageLayoutV1 from '../../../components/PageLayoutV1/PageLayoutV1';
|
||||
import Stepper from '../../../components/Settings/Services/Ingestion/IngestionStepper/IngestionStepper.component';
|
||||
import { UploadFile } from '../../../components/UploadFile/UploadFile';
|
||||
@ -61,7 +62,7 @@ import {
|
||||
} from '../../../utils/CSV/CSV.utils';
|
||||
import { isBulkEditRoute } from '../../../utils/EntityBulkEdit/EntityBulkEditUtils';
|
||||
import {
|
||||
getBulkEntityImportBreadcrumbList,
|
||||
getBulkEntityBreadcrumbList,
|
||||
getImportedEntityType,
|
||||
validateCsvString,
|
||||
} from '../../../utils/EntityImport/EntityImportUtils';
|
||||
@ -97,12 +98,31 @@ const BulkEntityImportPage = () => {
|
||||
const [gridRef, setGridRef] = useState<
|
||||
MutableRefObject<TypeComputedProps | null>
|
||||
>({ current: null });
|
||||
const [entity, setEntity] = useState<DataAssetsHeaderProps['dataAsset']>();
|
||||
|
||||
const fetchEntityData = useCallback(async () => {
|
||||
try {
|
||||
const response = await entityUtilClassBase.getEntityByFqn(
|
||||
entityType,
|
||||
fqn
|
||||
);
|
||||
setEntity(response);
|
||||
} catch (error) {
|
||||
// not show error here
|
||||
}
|
||||
}, [entityType, fqn]);
|
||||
|
||||
const isBulkEdit = useMemo(
|
||||
() => isBulkEditRoute(location.pathname),
|
||||
[location]
|
||||
);
|
||||
|
||||
const breadcrumbList: TitleBreadcrumbProps['titleLinks'] = useMemo(
|
||||
() =>
|
||||
entity ? getBulkEntityBreadcrumbList(entityType, entity, isBulkEdit) : [],
|
||||
[entityType, entity, isBulkEdit]
|
||||
);
|
||||
|
||||
const importedEntityType = useMemo(
|
||||
() => getImportedEntityType(entityType),
|
||||
[entityType]
|
||||
@ -181,11 +201,6 @@ const BulkEntityImportPage = () => {
|
||||
[dataSource]
|
||||
);
|
||||
|
||||
const breadcrumbList: TitleBreadcrumbProps['titleLinks'] = useMemo(
|
||||
() => getBulkEntityImportBreadcrumbList(entityType, fqn),
|
||||
[entityType, fqn]
|
||||
);
|
||||
|
||||
const handleBack = () => {
|
||||
if (activeStep === VALIDATION_STEP.UPDATE) {
|
||||
handleActiveStepChange(VALIDATION_STEP.EDIT_VALIDATE);
|
||||
@ -446,6 +461,10 @@ const BulkEntityImportPage = () => {
|
||||
]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchEntityData();
|
||||
}, [fetchEntityData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (socket) {
|
||||
socket.on(SOCKET_EVENTS.CSV_IMPORT_CHANNEL, (importResponse) => {
|
||||
@ -474,6 +493,7 @@ const BulkEntityImportPage = () => {
|
||||
<BulkEditEntity
|
||||
activeAsyncImportJob={activeAsyncImportJob}
|
||||
activeStep={activeStep}
|
||||
breadcrumbList={breadcrumbList}
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
handleBack={handleBack}
|
||||
|
@ -14,7 +14,6 @@ import Icon from '@ant-design/icons';
|
||||
import { Button } from 'antd';
|
||||
import React from 'react';
|
||||
import { ReactComponent as IconEdit } from '../../assets/svg/edit-new.svg';
|
||||
import { TitleBreadcrumbProps } from '../../components/common/TitleBreadcrumb/TitleBreadcrumb.interface';
|
||||
import { ROUTES } from '../../constants/constants';
|
||||
import { EntityType } from '../../enums/entity.enum';
|
||||
import {
|
||||
@ -23,29 +22,12 @@ import {
|
||||
} from '../../rest/databaseAPI';
|
||||
import { exportDatabaseServiceDetailsInCSV } from '../../rest/serviceAPI';
|
||||
import { exportTableDetailsInCSV } from '../../rest/tableAPI';
|
||||
import entityUtilClassBase from '../EntityUtilClassBase';
|
||||
import Fqn from '../Fqn';
|
||||
import i18n from '../i18next/LocalUtil';
|
||||
|
||||
export const isBulkEditRoute = (pathname: string) => {
|
||||
return pathname.includes(ROUTES.BULK_EDIT_ENTITY);
|
||||
};
|
||||
|
||||
export const getBulkEntityEditBreadcrumbList = (
|
||||
entityType: EntityType,
|
||||
fqn: string
|
||||
): TitleBreadcrumbProps['titleLinks'] => [
|
||||
{
|
||||
name: Fqn.split(fqn).pop(),
|
||||
url: entityUtilClassBase.getEntityLink(entityType, fqn),
|
||||
},
|
||||
{
|
||||
name: i18n.t('label.bulk-edit'),
|
||||
url: '',
|
||||
activeTitle: true,
|
||||
},
|
||||
];
|
||||
|
||||
export const getBulkEditCSVExportEntityApi = (entityType: EntityType) => {
|
||||
switch (entityType) {
|
||||
case EntityType.DATABASE_SERVICE:
|
||||
|
@ -10,16 +10,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import i18next from 'i18next';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { TitleBreadcrumbProps } from '../../components/common/TitleBreadcrumb/TitleBreadcrumb.interface';
|
||||
import { DataAssetsHeaderProps } from '../../components/DataAssets/DataAssetsHeader/DataAssetsHeader.interface';
|
||||
import { EntityType } from '../../enums/entity.enum';
|
||||
import {
|
||||
importEntityInCSVFormat,
|
||||
importServiceInCSVFormat,
|
||||
} from '../../rest/importExportAPI';
|
||||
import entityUtilClassBase from '../EntityUtilClassBase';
|
||||
import Fqn from '../Fqn';
|
||||
import { getEntityBreadcrumbs } from '../EntityUtils';
|
||||
import i18n from '../i18next/LocalUtil';
|
||||
|
||||
type ParsedDataType<T> = Array<T>;
|
||||
|
||||
@ -61,20 +61,20 @@ export const getImportedEntityType = (entityType: EntityType) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getBulkEntityImportBreadcrumbList = (
|
||||
export const getBulkEntityBreadcrumbList = (
|
||||
entityType: EntityType,
|
||||
fqn: string
|
||||
): TitleBreadcrumbProps['titleLinks'] => [
|
||||
{
|
||||
name: Fqn.split(fqn).pop(),
|
||||
url: entityUtilClassBase.getEntityLink(entityType, fqn),
|
||||
},
|
||||
{
|
||||
name: i18next.t('label.import'),
|
||||
url: '',
|
||||
activeTitle: true,
|
||||
},
|
||||
];
|
||||
entity: DataAssetsHeaderProps['dataAsset'],
|
||||
isBulkEdit: boolean
|
||||
): TitleBreadcrumbProps['titleLinks'] => {
|
||||
return [
|
||||
...getEntityBreadcrumbs(entity, entityType, true),
|
||||
{
|
||||
name: i18n.t(`label.${isBulkEdit ? 'bulk-edit' : 'import'}`),
|
||||
url: '',
|
||||
activeTitle: true,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export const validateCsvString = async (
|
||||
csvData: string,
|
||||
|
@ -36,6 +36,12 @@ import SearchIndexDetailsPage from '../pages/SearchIndexDetailsPage/SearchIndexD
|
||||
import StoredProcedurePage from '../pages/StoredProcedure/StoredProcedurePage';
|
||||
import TableDetailsPageV1 from '../pages/TableDetailsPageV1/TableDetailsPageV1';
|
||||
import TopicDetailsPage from '../pages/TopicDetails/TopicDetailsPage.component';
|
||||
import {
|
||||
getDatabaseDetailsByFQN,
|
||||
getDatabaseSchemaDetailsByFQN,
|
||||
} from '../rest/databaseAPI';
|
||||
import { getServiceByFQN } from '../rest/serviceAPI';
|
||||
import { getTableDetailsByFQN } from '../rest/tableAPI';
|
||||
import { ExtraDatabaseDropdownOptions } from './Database/Database.util';
|
||||
import { ExtraDatabaseSchemaDropdownOptions } from './DatabaseSchemaDetailsUtils';
|
||||
import { ExtraDatabaseServiceDropdownOptions } from './DatabaseServiceUtils';
|
||||
@ -273,6 +279,19 @@ class EntityUtilClassBase {
|
||||
}
|
||||
}
|
||||
|
||||
public getEntityByFqn(entityType: string, fqn: string, fields?: string[]) {
|
||||
switch (entityType) {
|
||||
case EntityType.DATABASE_SERVICE:
|
||||
return getServiceByFQN('databaseServices', fqn, { fields });
|
||||
case EntityType.DATABASE:
|
||||
return getDatabaseDetailsByFQN(fqn, { fields });
|
||||
case EntityType.DATABASE_SCHEMA:
|
||||
return getDatabaseSchemaDetailsByFQN(fqn, { fields });
|
||||
default:
|
||||
return getTableDetailsByFQN(fqn, { fields });
|
||||
}
|
||||
}
|
||||
|
||||
public getEntityDetailComponent(entityType: string) {
|
||||
switch (entityType) {
|
||||
case EntityType.DATABASE:
|
||||
|
@ -1651,7 +1651,8 @@ export const getBreadcrumbForTable = (
|
||||
name: entity.name,
|
||||
url: getEntityLinkFromType(
|
||||
entity.fullyQualifiedName ?? '',
|
||||
(entity as SourceType).entityType as EntityType
|
||||
((entity as SourceType).entityType as EntityType) ??
|
||||
EntityType.TABLE
|
||||
),
|
||||
},
|
||||
]
|
||||
@ -1938,7 +1939,8 @@ export const getEntityBreadcrumbs = (
|
||||
name: entity.name,
|
||||
url: getEntityLinkFromType(
|
||||
entity.fullyQualifiedName ?? '',
|
||||
(entity as SourceType).entityType as EntityType
|
||||
((entity as SourceType).entityType as EntityType) ??
|
||||
EntityType.DATABASE
|
||||
),
|
||||
},
|
||||
];
|
||||
@ -1975,7 +1977,8 @@ export const getEntityBreadcrumbs = (
|
||||
name: entity.name,
|
||||
url: getEntityLinkFromType(
|
||||
entity.fullyQualifiedName ?? '',
|
||||
(entity as SourceType).entityType as EntityType
|
||||
((entity as SourceType).entityType as EntityType) ??
|
||||
EntityType.DATABASE_SCHEMA
|
||||
),
|
||||
},
|
||||
];
|
||||
@ -1989,6 +1992,17 @@ export const getEntityBreadcrumbs = (
|
||||
getServiceRouteFromServiceType(ServiceCategory.DATABASE_SERVICES)
|
||||
),
|
||||
},
|
||||
...(includeCurrent
|
||||
? [
|
||||
{
|
||||
name: entity.name,
|
||||
url: getServiceDetailsPath(
|
||||
entity?.name,
|
||||
ServiceCategory.DATABASE_SERVICES
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
|
||||
case EntityType.DASHBOARD_SERVICE:
|
||||
|
Loading…
x
Reference in New Issue
Block a user