diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx index 5cf223d5748..f5b2bfc4a47 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx @@ -25,6 +25,7 @@ import React, { Fragment, useEffect, useMemo, useState } from 'react'; import { useHistory } from 'react-router-dom'; import { PAGE_SIZE } from '../../constants/constants'; import { WORKFLOWS_METADATA_DOCS } from '../../constants/docs.constants'; +import { PIPELINE_TYPE_LOCALISATION } from '../../constants/Ingestions.constant'; import { MetadataServiceType } from '../../generated/api/services/createMetadataService'; import { Connection } from '../../generated/entity/services/databaseService'; import { @@ -276,6 +277,32 @@ const Ingestion: React.FC = ({ ); }; + const getAddIngestionName = (type: PipelineType): string => { + let name; + switch (type) { + case PipelineType.ElasticSearchReindex: + name = t('label.add-entity', { + entity: t('labe.elastic-search-re-index'), + }); + + break; + + case PipelineType.Dbt: + name = t('label.add-workflow-ingestion', { + workflow: t('label.dbt-uppercase'), + }); + + break; + + default: + name = t('label.add-workflow-ingestion', { + workflow: t(`label.${PIPELINE_TYPE_LOCALISATION[type]}`), + }); + } + + return name; + }; + const getAddIngestionDropdown = (types: PipelineType[]) => { return ( @@ -308,15 +335,11 @@ const Ingestion: React.FC = ({ ({ + name: getAddIngestionName(type), disabled: type === PipelineType.DataInsight ? isDataSightIngestionExists : false, - name: `${t('label.add')} ${startCase(type)} ${ - type === PipelineType.ElasticSearchReindex - ? '' - : t('label.ingestion') - }`, value: type, }))} onSelect={(_e, value) => diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTFormConstants.ts b/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTFormConstants.ts index e1033d02024..875184c6502 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTFormConstants.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTFormConstants.ts @@ -23,10 +23,6 @@ import { import { DBT_SOURCES, GCS_CONFIG } from './DBTFormEnum'; export const DBTSources: Array = [ - { - name: 'No Config Source', - value: '', - }, { name: 'Local Config Source', value: DBT_SOURCES.local, @@ -66,12 +62,10 @@ export const reqDBTCloudFields: Record = { }; export const reqDBTLocalFields: Record = { - dbtCatalogFilePath: 'DBT Catalog File Path', dbtManifestFilePath: 'DBT Manifest File Path', }; export const reqDBTHttpFields: Record = { - dbtCatalogHttpPath: 'DBT Catalog Http Path', dbtManifestHttpPath: 'DBT Manifest Http Path', }; @@ -79,19 +73,6 @@ export const reqDBTS3Fields: Record = { awsRegion: 'AWS Region', }; -export const reqDBTGCSCredsFields: Record = { - authProviderX509CertUrl: 'Authentication Provider x509 Certificate URL', - authUri: 'Authentication URI', - clientEmail: 'Client Email', - clientId: 'Client ID', - clientX509CertUrl: 'Client x509 Certificate URL', - privateKey: 'Private Key', - privateKeyId: 'Private Key ID', - projectId: 'Project ID', - tokenUri: 'Token URI', - type: 'Credentials Type', -}; - export const rulesDBTS3CredsFields: Record< keyof Pick, Array diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTGCSConfig.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTGCSConfig.test.tsx index fed49a034f2..c15fae3dae9 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTGCSConfig.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTGCSConfig.test.tsx @@ -416,15 +416,6 @@ describe('Test DBT GCS Config Form', () => { expect(mockPrefixConfigChange).toBeCalledTimes(2); }); - it('should show errors on submit', async () => { - const { container } = render(); - const submitBtn = getByTestId(container, 'submit-btn'); - - fireEvent.click(submitBtn); - - expect(mockSubmit).not.toBeCalled(); - }); - it('should submit', async () => { const { container } = render( = ({ const validate = (data: DbtConfig) => { let valid = true; const gcsConfig = data.dbtSecurityConfig?.gcsConfig; - if (gcsType === GCS_CONFIG.GCSValues) { - const { isValid: reqValid, errors: reqErr } = validateDbtGCSCredsConfig( - (gcsConfig || {}) as GCSCredentialsValues - ); - const { isValid: fieldValid, errors: fieldErr } = - checkDbtGCSCredsConfigRules((gcsConfig || {}) as GCSCredentialsValues); - - setErrors({ - ...fieldErr, - ...reqErr, - }); - - valid = reqValid && fieldValid; - } else { + if (gcsType !== GCS_CONFIG.GCSValues) { if (isEmpty(gcsConfig)) { setErrors({ gcsConfig: `GCS Config ${jsonData['form-error-messages']['is-required']}`, @@ -150,7 +129,7 @@ export const DBTGCSConfig: FunctionComponent = ({

Google Cloud service account type. @@ -170,7 +149,7 @@ export const DBTGCSConfig: FunctionComponent = ({

Google Cloud project id. @@ -190,7 +169,7 @@ export const DBTGCSConfig: FunctionComponent = ({

Google Cloud Private key id. @@ -211,7 +190,7 @@ export const DBTGCSConfig: FunctionComponent = ({

Google Cloud private key. @@ -231,7 +210,7 @@ export const DBTGCSConfig: FunctionComponent = ({

Google Cloud email. @@ -251,7 +230,7 @@ export const DBTGCSConfig: FunctionComponent = ({

Google Cloud Client ID. @@ -269,7 +248,7 @@ export const DBTGCSConfig: FunctionComponent = ({

Google Cloud auth uri. @@ -287,7 +266,7 @@ export const DBTGCSConfig: FunctionComponent = ({

Google Cloud token uri. @@ -307,7 +286,7 @@ export const DBTGCSConfig: FunctionComponent = ({

Google Cloud auth provider certificate. @@ -330,7 +309,7 @@ export const DBTGCSConfig: FunctionComponent = ({

Google Cloud client certificate uri. @@ -358,7 +337,7 @@ export const DBTGCSConfig: FunctionComponent = ({

GCS Credentials Path. diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTHttpConfig.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTHttpConfig.tsx index 67794a8c4f3..612e3ac7b76 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTHttpConfig.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/DBTConfigFormBuilder/DBTHttpConfig.tsx @@ -74,7 +74,7 @@ export const DBTHttpConfig: FunctionComponent = ({

DBT catalog file to extract dbt models with their column schemas. @@ -94,7 +94,7 @@ export const DBTHttpConfig: FunctionComponent = ({

DBT manifest file path to extract dbt models and associate with @@ -109,6 +109,7 @@ export const DBTHttpConfig: FunctionComponent = ({ value={dbtManifestHttpPath} onChange={(e) => handleManifestHttpPathChange(e.target.value)} /> + {errors?.dbtManifestHttpPath && errorMsg(errors.dbtManifestHttpPath)}

DBT catalog file to extract dbt models with their column schemas. diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/Ingestions.constant.ts b/openmetadata-ui/src/main/resources/ui/src/constants/Ingestions.constant.ts index 9ee508e2aee..c85a7e2bdaf 100644 --- a/openmetadata-ui/src/main/resources/ui/src/constants/Ingestions.constant.ts +++ b/openmetadata-ui/src/main/resources/ui/src/constants/Ingestions.constant.ts @@ -51,3 +51,19 @@ export const STEPS_FOR_ADD_SERVICE: Array = [ }, { name: i18next.t('label.connection-details'), step: 3 }, ]; + +export const INGESTION_ACTION_TYPE = { + ADD: 'add', + EDIT: 'edit', +}; + +export const PIPELINE_TYPE_LOCALISATION = { + dataInsight: 'data-insight', + dbt: 'dbt', + elasticSearchReindex: 'elastic-search-re-index', + lineage: 'lineage', + metadata: 'metadata', + profiler: 'profiler', + TestSuite: 'test-suite', + usage: 'usage', +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/Services.constant.ts b/openmetadata-ui/src/main/resources/ui/src/constants/Services.constant.ts index 2e3694cd779..38e661ce730 100644 --- a/openmetadata-ui/src/main/resources/ui/src/constants/Services.constant.ts +++ b/openmetadata-ui/src/main/resources/ui/src/constants/Services.constant.ts @@ -190,6 +190,15 @@ export const SERVICE_CATEGORY: { [key: string]: ServiceCategory } = { metadata: ServiceCategory.METADATA_SERVICES, }; +export const SERVICE_CATEGORY_TYPE = { + databaseServices: 'databases', + messagingServices: 'messaging', + dashboardServices: 'dashboards', + pipelineServices: 'pipelines', + mlmodelServices: 'mlModels', + metadataServices: 'metadata', +}; + export const servicesDisplayName: { [key: string]: string } = { databaseServices: i18next.t('label.entity-service', { entity: i18next.t('label.database'), diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json index c0209263d21..0722c1c5094 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json @@ -309,6 +309,7 @@ "detail-plural": "Details", "ingestion": "Ingestion", "add-workflow-ingestion": "Add {{workflow}} Ingestion", + "edit-workflow-ingestion": "Edit {{workflow}} Ingestion", "clear-all": "Clear All", "view-less": "View less", "view-more": "View more", @@ -584,6 +585,7 @@ "assigned-entity": "Assigned {{entity}}", "total-assets-view": "Total Assets View", "total-active-user": "Total Active User", + "elastic-search-re-index": "ElasticSearchReindex", "alert-actions": "Alert Actions", "test-results": "Test Results", "send-to": "Send to", diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/AddIngestionPage/AddIngestionPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/AddIngestionPage/AddIngestionPage.component.tsx index 942ec022d75..484e42af159 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/AddIngestionPage/AddIngestionPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/AddIngestionPage/AddIngestionPage.component.tsx @@ -13,7 +13,7 @@ import { Space } from 'antd'; import { AxiosError } from 'axios'; -import { capitalize, startCase } from 'lodash'; +import { startCase } from 'lodash'; import { ServiceTypes } from 'Models'; import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -39,6 +39,7 @@ import { INGESTION_PROGRESS_START_VAL, } from '../../constants/constants'; import { GlobalSettingsMenuCategory } from '../../constants/GlobalSettings.constants'; +import { INGESTION_ACTION_TYPE } from '../../constants/Ingestions.constant'; import { FormSubmitType } from '../../enums/form.enum'; import { IngestionActionMessage } from '../../enums/ingestion.enum'; import { ServiceCategory } from '../../enums/service.enum'; @@ -47,6 +48,7 @@ import { PipelineType } from '../../generated/entity/services/ingestionPipelines import { DataObj } from '../../interface/service.interface'; import jsonData from '../../jsons/en'; import { getEntityMissingError } from '../../utils/CommonUtils'; +import { getIngestionHeadingName } from '../../utils/IngestionUtils'; import { getSettingPath } from '../../utils/RouterUtils'; import { getServiceIngestionStepGuide, @@ -266,7 +268,10 @@ const AddIngestionPage = () => { activeIngestionStep={activeIngestionStep} handleCancelClick={goToService} handleViewServiceClick={goToService} - heading={`Add ${capitalize(ingestionType)} Ingestion`} + heading={getIngestionHeadingName( + ingestionType, + INGESTION_ACTION_TYPE.ADD + )} ingestionAction={ingestionAction} ingestionProgress={ingestionProgress} isAirflowSetup={isAirflowRunning} diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/EditIngestionPage/EditIngestionPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/EditIngestionPage/EditIngestionPage.component.tsx index f6caa44fc40..98fd58cabce 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/EditIngestionPage/EditIngestionPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/EditIngestionPage/EditIngestionPage.component.tsx @@ -38,6 +38,7 @@ import { INGESTION_PROGRESS_START_VAL, } from '../../constants/constants'; import { GlobalSettingsMenuCategory } from '../../constants/GlobalSettings.constants'; +import { INGESTION_ACTION_TYPE } from '../../constants/Ingestions.constant'; import { FormSubmitType } from '../../enums/form.enum'; import { IngestionActionMessage } from '../../enums/ingestion.enum'; import { ServiceCategory } from '../../enums/service.enum'; @@ -49,6 +50,7 @@ import { import { DataObj } from '../../interface/service.interface'; import jsonData from '../../jsons/en'; import { getEntityMissingError } from '../../utils/CommonUtils'; +import { getIngestionHeadingName } from '../../utils/IngestionUtils'; import { getSettingPath } from '../../utils/RouterUtils'; import { getServiceIngestionStepGuide, @@ -297,7 +299,10 @@ const EditIngestionPage = () => { data={ingestionData} handleCancelClick={goToService} handleViewServiceClick={goToService} - heading={`Edit ${capitalize(ingestionType)} Ingestion`} + heading={getIngestionHeadingName( + ingestionType, + INGESTION_ACTION_TYPE.EDIT + )} ingestionAction={ingestionAction} ingestionProgress={ingestionProgress} isAirflowSetup={isAirflowRunning} diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/service/index.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/service/index.tsx index b9d8cf7ba57..e67c3edf34b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/service/index.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/service/index.tsx @@ -68,6 +68,7 @@ import { GlobalSettingsMenuCategory } from '../../constants/GlobalSettings.const import { OPENMETADATA, servicesDisplayName, + SERVICE_CATEGORY_TYPE, } from '../../constants/Services.constant'; import { SearchIndex } from '../../enums/search.enum'; import { ServiceCategory } from '../../enums/service.enum'; @@ -1014,6 +1015,15 @@ const ServicePage: FunctionComponent = () => { )} + history.push( + `/settings/services/${ + SERVICE_CATEGORY_TYPE[ + serviceCategory as keyof typeof SERVICE_CATEGORY_TYPE + ] + }` + ) + } allowSoftDelete={false} deleteMessage={getDeleteEntityMessage( serviceName || '', diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/DBTConfigFormUtil.ts b/openmetadata-ui/src/main/resources/ui/src/utils/DBTConfigFormUtil.ts index 2cf8bcb25ff..1ffb677f72c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/DBTConfigFormUtil.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/DBTConfigFormUtil.ts @@ -17,7 +17,6 @@ import { DbtConfigCloudReq, DbtConfigHttp, DbtConfigLocal, - DbtGCSCreds, DbtS3CredsReq, DbtSourceTypes, ErrorDbtCloud, @@ -28,7 +27,6 @@ import { } from '../components/common/DBTConfigFormBuilder/DBTConfigForm.interface'; import { reqDBTCloudFields, - reqDBTGCSCredsFields, reqDBTHttpFields, reqDBTLocalFields, reqDBTS3Fields, @@ -129,24 +127,6 @@ export const validateDbtS3Config = ( return { isValid, errors }; }; -export const validateDbtGCSCredsConfig = ( - data: GCSCredentialsValues, - requiredFields = reqDBTGCSCredsFields -) => { - let isValid = true; - const errors = {} as ErrorDbtGCS; - for (const field of Object.keys(requiredFields) as Array) { - if (isEmpty(data[field])) { - isValid = false; - errors[ - field - ] = `${requiredFields[field]} ${jsonData['form-error-messages']['is-required']}`; - } - } - - return { isValid, errors }; -}; - function getInvalidEmailErrors< Type, Keys extends Array, @@ -250,7 +230,7 @@ export const checkDbtGCSCredsConfigRules = ( export const getSourceTypeFromConfig = ( data?: DbtConfig, - defaultSource = '' as DBT_SOURCES + defaultSource = DBT_SOURCES.local ): DbtSourceTypes => { let sourceType = defaultSource; let gcsType = undefined; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/IngestionUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/IngestionUtils.ts new file mode 100644 index 00000000000..7a43bfac4c2 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/utils/IngestionUtils.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2022 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 { t } from 'i18next'; + +import { capitalize, upperCase } from 'lodash'; +import { INGESTION_ACTION_TYPE } from '../constants/Ingestions.constant'; +import { PipelineType } from '../generated/api/services/ingestionPipelines/createIngestionPipeline'; + +export const getIngestionHeadingName = ( + ingestionType: string, + type: string +) => { + let ingestionName = capitalize(ingestionType); + if (ingestionType === PipelineType.Dbt) { + ingestionName = upperCase(ingestionType); + } + + return type === INGESTION_ACTION_TYPE.ADD + ? t('label.add-workflow-ingestion', { + workflow: ingestionName, + }) + : t('label.edit-workflow-ingestion', { + workflow: ingestionName, + }); +};