diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/common.js b/openmetadata-ui/src/main/resources/ui/cypress/common/common.js index 92edcc2a540..bb86eb699d0 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/common.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/common.js @@ -123,7 +123,8 @@ export const handleIngestionRetry = ( export const scheduleIngestion = () => { // Schedule & Deploy cy.contains('Schedule for Ingestion').should('be.visible'); - cy.get('[data-testid="cron-type"]').should('be.visible').select('hour'); + cy.get('[data-testid="cron-type"]').should('be.visible').click(); + cy.get('.ant-select-item-option-content').contains('Hour').click(); cy.get('[data-testid="deploy-button"]').should('be.visible').click(); // check success diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/kafka.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/kafka.spec.js index 426ead79144..02a7ab85ddf 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/kafka.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/kafka.spec.js @@ -35,7 +35,10 @@ describe('Kafka Ingestion', () => { goToAddNewServicePage(SERVICE_TYPE.Messaging); // Select Dashboard services - cy.get('[data-testid="service-category"]').select('messagingServices'); + cy.get('[data-testid="service-category"]').should('be.visible').click(); + cy.get('.ant-select-item-option-content') + .contains('Messaging Services') + .click(); const connectionInput = () => { cy.get('#root_bootstrapServers').type( diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/metabase.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/metabase.spec.js index 604ccab77c3..6fba4dfcc53 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/metabase.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/metabase.spec.js @@ -35,7 +35,10 @@ describe('Metabase Ingestion', () => { goToAddNewServicePage(SERVICE_TYPE.Dashboard); // Select Dashboard services - cy.get('[data-testid="service-category"]').select('dashboardServices'); + cy.get('[data-testid="service-category"]').should('be.visible').click(); + cy.get('.ant-select-item-option-content') + .contains('Dashboard Services') + .click(); const connectionInput = () => { cy.get('#root_username').type(Cypress.env('metabaseUsername')); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/superset.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/superset.spec.js index 386515bff59..d5d7fd7864a 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/superset.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/superset.spec.js @@ -35,7 +35,10 @@ describe('Superset Ingestion', () => { goToAddNewServicePage(SERVICE_TYPE.Dashboard); // Select Dashboard services - cy.get('[data-testid="service-category"]').select('dashboardServices'); + cy.get('[data-testid="service-category"]').should('be.visible').click(); + cy.get('.ant-select-item-option-content') + .contains('Dashboard Services') + .click(); const connectionInput = () => { cy.get('#root_username').type(Cypress.env('supersetUsername')); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/AddIngestion.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/AddIngestion.component.tsx index 99b1cbba02b..463dc5522cd 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/AddIngestion.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/AddIngestion.component.tsx @@ -11,8 +11,8 @@ * limitations under the License. */ +import { LOADING_STATE } from 'enums/common.enum'; import { isEmpty, isUndefined, omit, trim } from 'lodash'; -import { LoadingState } from 'Models'; import React, { Reducer, useCallback, @@ -92,7 +92,6 @@ const AddIngestion = ({ status, }: AddIngestionProps) => { const { t } = useTranslation(); - console.log('data:', data); const { sourceConfig, sourceConfigType } = useMemo( () => ({ sourceConfig: data?.sourceConfig.config as ConfigClass, @@ -204,7 +203,9 @@ const AddIngestion = ({ Reducer> >(reducerWithoutAction, initialState); - const [saveState, setSaveState] = useState('initial'); + const [saveState, setSaveState] = useState( + LOADING_STATE.INITIAL + ); const [showDeployModal, setShowDeployModal] = useState(false); const handleStateChange = useCallback( @@ -494,6 +495,7 @@ const AddIngestion = ({ }; const createNewIngestion = () => { + setSaveState(LOADING_STATE.WAITING); const { repeatFrequency, enableDebugLog, ingestionName } = state; const ingestionDetails: CreateIngestionPipeline = { airflowConfig: { @@ -534,6 +536,7 @@ const AddIngestion = ({ // ignore since error is displayed in toast in the parent promise }) .finally(() => { + setTimeout(() => setSaveState(LOADING_STATE.INITIAL), 500); setTimeout(() => setShowDeployModal(false), 500); }); } @@ -560,11 +563,11 @@ const AddIngestion = ({ }; if (onUpdateIngestion) { - setSaveState('waiting'); + setSaveState(LOADING_STATE.WAITING); setShowDeployModal(true); onUpdateIngestion(updatedData, data, data.id as string, data.name) .then(() => { - setSaveState('success'); + setSaveState(LOADING_STATE.SUCCESS); if (showSuccessScreen) { handleNext(); } else { @@ -572,7 +575,7 @@ const AddIngestion = ({ } }) .finally(() => { - setTimeout(() => setSaveState('initial'), 500); + setTimeout(() => setSaveState(LOADING_STATE.INITIAL), 500); setTimeout(() => setShowDeployModal(false), 500); }); } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/Steps/ConfigureIngestion.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/Steps/ConfigureIngestion.tsx index b8b038dfa92..20afdafe106 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/Steps/ConfigureIngestion.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/Steps/ConfigureIngestion.tsx @@ -11,7 +11,7 @@ * limitations under the License. */ -import { Form, InputNumber, Select, Typography } from 'antd'; +import { Button, Form, InputNumber, Select, Typography } from 'antd'; import { isNil } from 'lodash'; import React, { Fragment, useMemo, useRef } from 'react'; import { useTranslation } from 'react-i18next'; @@ -22,7 +22,6 @@ import { ServiceCategory } from '../../../enums/service.enum'; import { ProfileSampleType } from '../../../generated/entity/data/table'; import { PipelineType } from '../../../generated/entity/services/ingestionPipelines/ingestionPipeline'; import { getSeparator } from '../../../utils/CommonUtils'; -import { Button } from '../../buttons/Button/Button'; import FilterPattern from '../../common/FilterPattern/FilterPattern'; import RichTextEditor from '../../common/rich-text-editor/RichTextEditor'; import { EditorContentRef } from '../../common/rich-text-editor/RichTextEditor.interface'; @@ -891,22 +890,19 @@ const ConfigureIngestion = ({ layout="vertical"> {getIngestionPipelineFields()} - + diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/Steps/ScheduleInterval.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/Steps/ScheduleInterval.tsx index 8d4893fcdd1..f8aa4561223 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/Steps/ScheduleInterval.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AddIngestion/Steps/ScheduleInterval.tsx @@ -12,12 +12,11 @@ */ import { CheckOutlined } from '@ant-design/icons'; +import { Button, Col, Row } from 'antd'; +import { LOADING_STATE } from 'enums/common.enum'; import React from 'react'; import { useTranslation } from 'react-i18next'; -import { Button } from '../../buttons/Button/Button'; import CronEditor from '../../common/CronEditor/CronEditor'; -import { Field } from '../../Field/Field'; -import Loader from '../../Loader/Loader'; import { ScheduleIntervalProps } from '../addIngestion.interface'; const ScheduleInterval = ({ @@ -36,8 +35,8 @@ const ScheduleInterval = ({ const { t } = useTranslation(); return ( -
- + +
-
- + + - {status === 'waiting' ? ( + {status === 'success' ? ( - ) : status === 'success' ? ( - ) : ( )} - -
+ + ); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AddService/Steps/SelectServiceType.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AddService/Steps/SelectServiceType.tsx index cfc81b6bfab..132e680d34c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AddService/Steps/SelectServiceType.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AddService/Steps/SelectServiceType.tsx @@ -11,22 +11,22 @@ * limitations under the License. */ +import { Button, Col, Row, Select } from 'antd'; import classNames from 'classnames'; -import { t } from 'i18next'; import { startCase } from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { excludedService, serviceTypes, + SERVICE_CATEGORY_OPTIONS, } from '../../../constants/Services.constant'; import { ServiceCategory } from '../../../enums/service.enum'; import { MetadataServiceType } from '../../../generated/entity/services/metadataService'; import { MlModelServiceType } from '../../../generated/entity/services/mlmodelService'; import { errorMsg, getServiceLogo } from '../../../utils/CommonUtils'; import SVGIcons, { Icons } from '../../../utils/SvgUtils'; -import { Button } from '../../buttons/Button/Button'; import Searchbar from '../../common/searchbar/Searchbar'; -import { Field } from '../../Field/Field'; import { SelectServiceTypeProps } from './Steps.interface'; const SelectServiceType = ({ @@ -38,6 +38,7 @@ const SelectServiceType = ({ onCancel, onNext, }: SelectServiceTypeProps) => { + const { t } = useTranslation(); const [category, setCategory] = useState(''); const [connectorSearchTerm, setConnectorSearchTerm] = useState(''); const [selectedConnectors, setSelectedConnectors] = useState([]); @@ -77,96 +78,91 @@ const SelectServiceType = ({ return (
- - - - - - + + + { - e.persist(); - onChangeCB(e); - }}> - {hourOptions.map(getOptionComponent('hour_option'))} - + onChange={onChangeCB} + /> ); }; const getMinuteSelect = ( selectedOption: SelectedHourOption, - onChangeCB: (e: React.ChangeEvent) => void + onChangeCB: (value: number) => void ) => { const { disabled } = props; return ( - + onChange={onChangeCB} + /> ); }; const getMinuteSegmentSelect = ( selectedOption: SelectedHourOption, - onChangeCB: (e: React.ChangeEvent) => void + onChangeCB: (value: number) => void ) => { return ( - + onChange={onChangeCB} + /> ); }; @@ -330,36 +300,30 @@ const CronEditor: FC = (props) => { options: CronOption[], value: number, substrVal: number, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - onClick: (e: any) => void - ) => { - const { disabled } = props; - const optionComps: JSX.Element[] = []; - - options.forEach((o, i) => { - let strVal = o.label; + onClick: (value: number) => void + ) => + options.map(({ label, value: optionValue }, index) => { + let strVal = label; if (substrVal) { strVal = strVal.substr(0, substrVal); } - const comp = ( + + return ( onClick?.(e)}> + className={`cron-badge-option ${ + optionValue === value ? 'active' : '' + } ${props.disabled || !onClick ? 'disabled' : ''}`} + data-value={optionValue} + key={index} + onClick={() => { + onClick?.(Number(optionValue)); + }}> {strVal} ); - - optionComps.push(comp); }); - return optionComps; - }; - const getMinuteComponent = (cronPeriodString: string) => { const { selectedMinOption } = state; @@ -367,11 +331,9 @@ const CronEditor: FC = (props) => { state.selectedPeriod === 'minute' && ( <>
- - {getMinuteSegmentSelect( - selectedMinOption, - (e: React.ChangeEvent) => - onMinOptionSelect(e, 'min') + + {getMinuteSegmentSelect(selectedMinOption, (value: number) => + onMinOptionSelect(value, 'min') )}
@@ -391,11 +353,9 @@ const CronEditor: FC = (props) => { state.selectedPeriod === 'hour' && ( <>
- - {getMinuteSelect( - selectedHourOption, - (e: React.ChangeEvent) => - onHourOptionSelect(e, 'min') + + {getMinuteSelect(selectedHourOption, (value: number) => + onHourOptionSelect(value, 'min') )}
@@ -423,16 +383,12 @@ const CronEditor: FC = (props) => {
- {getHourSelect( - selectedDayOption, - (e: React.ChangeEvent) => - onDayOptionSelect(e, 'hour') + {getHourSelect(selectedDayOption, (value: number) => + onDayOptionSelect(value, 'hour') )} : - {getMinuteSelect( - selectedDayOption, - (e: React.ChangeEvent) => - onDayOptionSelect(e, 'min') + {getMinuteSelect(selectedDayOption, (value: number) => + onDayOptionSelect(value, 'min') )}
@@ -462,16 +418,12 @@ const CronEditor: FC = (props) => {
- {getHourSelect( - selectedWeekOption, - (e: React.ChangeEvent) => - onWeekOptionSelect(e, 'hour') + {getHourSelect(selectedWeekOption, (value: number) => + onWeekOptionSelect(value, 'hour') )} : - {getMinuteSelect( - selectedWeekOption, - (e: React.ChangeEvent) => - onWeekOptionSelect(e, 'min') + {getMinuteSelect(selectedWeekOption, (value: number) => + onWeekOptionSelect(value, 'min') )}
@@ -484,8 +436,7 @@ const CronEditor: FC = (props) => { dayOptions, selectedWeekOption.dow, 1, - (e: React.ChangeEvent) => - onWeekOptionSelect(e, 'dow') + (value: number) => onWeekOptionSelect(value, 'dow') )}
@@ -519,21 +470,18 @@ const CronEditor: FC = (props) => { monthDaysOptions, selectedMonthOption.dom, 0, - (e: React.ChangeEvent) => - onMonthOptionSelect(e, 'dom') + (value: number) => onMonthOptionSelect(value, 'dom') )}
{`${t('label.time')}:`} - {`${getHourSelect( - selectedMonthOption, - (e: React.ChangeEvent) => - onMonthOptionSelect(e, 'hour') - )} : ${getMinuteSelect( - selectedMonthOption, - (e: React.ChangeEvent) => - onMonthOptionSelect(e, 'min') + {`${getHourSelect(selectedMonthOption, (e: number) => + onMonthOptionSelect(e, 'hour') + )} + : + ${getMinuteSelect(selectedMonthOption, (e: number) => + onMonthOptionSelect(e, 'min') )}`}
{getTextComp( @@ -567,8 +515,7 @@ const CronEditor: FC = (props) => { monthOptions, selectedYearOption.mon, 3, - (e: React.ChangeEvent) => - onYearOptionSelect(e, 'mon') + (value: number) => onYearOptionSelect(value, 'mon') )} @@ -579,23 +526,18 @@ const CronEditor: FC = (props) => { monthDaysOptions, selectedYearOption.dom, 0, - (e: React.ChangeEvent) => - onYearOptionSelect(e, 'dom') + (value: number) => onYearOptionSelect(value, 'dom') )}
{`${t('label.time')}:`} - {`${getHourSelect( - selectedYearOption, - (e: React.ChangeEvent) => - onYearOptionSelect(e, 'hour') + {`${getHourSelect(selectedYearOption, (value: number) => + onYearOptionSelect(value, 'hour') )} : - ${getMinuteSelect( - selectedYearOption, - (e: React.ChangeEvent) => - onYearOptionSelect(e, 'min') + ${getMinuteSelect(selectedYearOption, (value: number) => + onYearOptionSelect(value, 'min') )}`}
{getTextComp( @@ -612,25 +554,18 @@ const CronEditor: FC = (props) => {
- + onChange={onPeriodSelect} + />
{getMinuteComponent(startText)} 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 ed4098a0ba9..1c8cea862d6 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 @@ -11,6 +11,7 @@ * limitations under the License. */ +import { map, startCase } from 'lodash'; import { ServiceTypes } from 'Models'; import i18n from 'utils/i18next/LocalUtil'; import addPlaceHolder from '../assets/img/add-placeholder.svg'; @@ -240,3 +241,8 @@ export const COMMON_UI_SCHEMA = { export const OPENMETADATA = 'OpenMetadata'; export const JWT_CONFIG = 'openMetadataJWTClientConfig'; + +export const SERVICE_CATEGORY_OPTIONS = map(ServiceCategory, (value) => ({ + label: startCase(value), + value, +})); 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 d261eb2a2e2..8642a2ece90 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 @@ -455,6 +455,7 @@ "metrics-summary": "Metrics Summary", "min": "Min", "minor": "Minor", + "minute": "Minute", "minute-lowercase": "minute", "minute-plural": "Minutes", "ml-model": "ML Model", @@ -1078,6 +1079,7 @@ "pipeline-description-message": "Description of the pipeline.", "pipeline-trigger-success-message": "Pipeline triggered successfully!", "pipeline-will-trigger-manually": "Pipeline will only be triggered manually.", + "pipeline-will-triggered-manually": "Pipeline will only be triggered manually", "process-pii-sensitive-column-message": "Check column names to auto tag PII Senstive/nonSensitive columns.", "profile-sample-percentage-message": "Set the Profiler value as percentage", "profile-sample-row-count-message": " Set the Profiler value as row count", @@ -1099,6 +1101,7 @@ "result-limit-message": "Configuration to set the limit for query logs.", "run-sample-data-to-ingest-sample-data": "'Run sample data to ingest sample data assets into your OpenMetadata.'", "schedule-for-ingestion-description": "Scheduling can be set up at an hourly, daily, or weekly cadence. The timezone is in UTC.", + "scheduled-run-every": "Scheduled to run every", "scopes-comma-separated": "Add the Scopes value, separated by commas", "search-for-entity-types": "Search for Tables, Topics, Dashboards, Pipelines and ML Models.", "search-for-ingestion": "Search for ingestion",