From 38f9e0555d0f93c3f5d977b5e457a36d35ccadf6 Mon Sep 17 00:00:00 2001 From: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com> Date: Tue, 13 Dec 2022 16:14:48 +0530 Subject: [PATCH] fix(ui): add description around filter pattern (#9133) * fix(ui): add description around filter pattern * update localization text * cleanup common utils * add docs link to description * doc : change pattern helper text as per comments * fix : filter pattern checkbox opacity * Fix cy tests * Revert : filter pattern styling * Fix : cypress test * text updated as per comment * fix cypress failure * fix cypress for checkboxes * address comments Co-authored-by: Sachin Chaurasiya --- .../resources/ui/cypress/common/common.js | 2 +- .../e2e/AddNewService/bigquery.spec.js | 5 +- .../ui/cypress/e2e/AddNewService/glue.spec.js | 3 +- .../cypress/e2e/AddNewService/kafka.spec.js | 2 +- .../e2e/AddNewService/metabase.spec.js | 2 +- .../cypress/e2e/AddNewService/mysql.spec.js | 3 +- .../e2e/AddNewService/postgres.spec.js | 3 +- .../e2e/AddNewService/redshiftWithDBT.spec.js | 2 +- .../e2e/AddNewService/snowflake.spec.js | 2 +- .../e2e/AddNewService/superset.spec.js | 2 +- .../e2e/Pages/DataQualityAndProfiler.js | 6 +- .../src/components/Users/Users.component.tsx | 8 +- .../FilterPattern/FilterPattern.test.tsx | 39 +++++ .../common/FilterPattern/FilterPattern.tsx | 94 +++++++---- .../ui/src/locale/languages/en-us.json | 11 +- .../src/main/resources/ui/src/setupTests.js | 1 + .../resources/ui/src/utils/CommonUtils.tsx | 146 ++++-------------- 17 files changed, 170 insertions(+), 161 deletions(-) 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 292f124fb52..2547cbe49f8 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/common.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/common.js @@ -186,7 +186,7 @@ export const testServiceCreationAndIngestion = ( cy.get('[data-testid="add-ingestion-container"]').should('be.visible'); if (isDatabaseService(type)) { - cy.get('[data-testid="schema-filter-pattern-checkbox"]').should( + cy.get('[data-testid="configure-ingestion-container"]').should( 'be.visible' ); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/bigquery.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/bigquery.spec.js index cb40230a770..5273dc059e2 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/bigquery.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/bigquery.spec.js @@ -71,9 +71,10 @@ describe('BigQuery Ingestion', () => { }; const addIngestionInput = () => { + cy.get('[data-testid="schema-filter-pattern-checkbox"]') - .scrollIntoView() - .should('be.visible') + .invoke('show') + .trigger('mouseover') .check(); cy.get('[data-testid="filter-pattern-includes-schema"]') .scrollIntoView() diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/glue.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/glue.spec.js index 1c4735574e2..9fbae064c39 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/glue.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/glue.spec.js @@ -47,8 +47,7 @@ describe('Glue Ingestion', () => { const addIngestionInput = () => { cy.get('[data-testid="schema-filter-pattern-checkbox"]') - .scrollIntoView() - .should('be.visible') + .invoke('show').trigger('mouseover') .check(); cy.get('[data-testid="filter-pattern-includes-schema"]') .scrollIntoView() 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 1b0d9a8e2b9..892ad3575c6 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 @@ -40,7 +40,7 @@ describe('Kafka Ingestion', () => { const addIngestionInput = () => { cy.get('[data-testid="topic-filter-pattern-checkbox"]') - .should('be.visible') + .invoke('show').trigger('mouseover') .check(); cy.get('[data-testid="filter-pattern-includes-topic"]') .should('be.visible') 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 9ad559b455a..1e905a82d4c 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 @@ -41,7 +41,7 @@ describe('Metabase Ingestion', () => { const addIngestionInput = () => { cy.get('[data-testid="dashboard-filter-pattern-checkbox"]') - .should('be.visible') + .invoke('show').trigger('mouseover') .check(); cy.get('[data-testid="filter-pattern-includes-dashboard"]') .should('be.visible') diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/mysql.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/mysql.spec.js index f05a2034602..a72b8053ad4 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/mysql.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/mysql.spec.js @@ -27,7 +27,8 @@ describe('MySQL Ingestion', () => { goToAddNewServicePage(SERVICE_TYPE.Database); const addIngestionInput = () => { - cy.get('[data-testid="schema-filter-pattern-checkbox"]').check(); + // cy.get('[data-testid="filter-pattern-container"]').first().scrollIntoView().should('be.visible'); + cy.get('[data-testid="schema-filter-pattern-checkbox"]').invoke('show').trigger('mouseover').check(); cy.get('[data-testid="filter-pattern-includes-schema"]') .should('be.visible') .type(Cypress.env('mysqlDatabaseSchema')); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/postgres.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/postgres.spec.js index afb859dc9cc..9688688e57b 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/postgres.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/postgres.spec.js @@ -53,8 +53,7 @@ it('add and ingest data', () => { const addIngestionInput = () => { cy.get('[data-testid="schema-filter-pattern-checkbox"]') - .scrollIntoView() - .should('be.visible') + .invoke('show').trigger('mouseover') .check(); cy.get('[data-testid="filter-pattern-includes-schema"]') .scrollIntoView() diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/redshiftWithDBT.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/redshiftWithDBT.spec.js index e4677451f6e..d2f464b8a09 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/redshiftWithDBT.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/redshiftWithDBT.spec.js @@ -48,7 +48,7 @@ describe('RedShift Ingestion', () => { const addIngestionInput = () => { // no schema or database filters - cy.get('[data-testid="schema-filter-pattern-checkbox"]').check(); + cy.get('[data-testid="schema-filter-pattern-checkbox"]').invoke('show').trigger('mouseover').check(); cy.get('[data-testid="filter-pattern-includes-schema"]') .should('be.visible') .type('dbt_jaffle'); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/snowflake.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/snowflake.spec.js index ed3e9a16b5e..8e87c7915d3 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/snowflake.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/AddNewService/snowflake.spec.js @@ -35,7 +35,7 @@ describe('Snowflake Ingestion', () => { }; const addIngestionInput = () => { - cy.get('[data-testid="schema-filter-pattern-checkbox"]').check(); + cy.get('[data-testid="schema-filter-pattern-checkbox"]').invoke('show').trigger('mouseover').check(); cy.get('[data-testid="filter-pattern-includes-schema"]') .should('be.visible') .type(schema); 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 25f5af6227f..b3fb41fbac7 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 @@ -50,7 +50,7 @@ describe('Superset Ingestion', () => { const addIngestionInput = () => { cy.get('[data-testid="dashboard-filter-pattern-checkbox"]') - .should('be.visible') + .invoke('show').trigger('mouseover') .check(); cy.get('[data-testid="filter-pattern-includes-dashboard"]') .should('be.visible') diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.js index 28aa7f1ba67..69d7e31d7f0 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.js @@ -104,7 +104,11 @@ describe('Data Quality and Profiler should work properly', () => { .scrollIntoView() .contains('Profiler Ingestion') .click(); - cy.get('[data-testid="profileSample"]').should('be.visible').and('not.be.disabled').type(10); + cy.get('[data-testid="profileSample"]') + .scrollIntoView() + .should('be.visible') + .and('not.be.disabled') + .type(10); cy.get('[data-testid="next-button"]') .scrollIntoView() .should('be.visible') diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx index 41305866458..916b94d5c7e 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx @@ -942,11 +942,11 @@ const Users = ({ ) : ( {tabNumber === 3 - ? t('server.no-user-entities', { - type: 'owned', + ? t('server.you-have-not-action-anything-yet', { + action: t('label.owned-lowercase'), }) - : t('server.no-user-entities', { - type: 'followed', + : t('server.you-have-not-action-anything-yet', { + action: t('label.followed-lowercase'), })} )} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/FilterPattern/FilterPattern.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/FilterPattern/FilterPattern.test.tsx index ec4234018c1..1092446381a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/FilterPattern/FilterPattern.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/FilterPattern/FilterPattern.test.tsx @@ -55,4 +55,43 @@ describe('Test FilterPattern component', () => { expect(includeFilterInput).toBeInTheDocument(); expect(excludeFilterInput).toBeInTheDocument(); }); + + it('FilterPattern component should render with filter pattern description', async () => { + const { container } = render(); + + const filterPatternContainer = await findByTestId( + container, + 'filter-pattern-container' + ); + const fieldContainer = await findByTestId(container, 'field-container'); + const checkbox = await findByTestId( + container, + `${mockFilterPatternProps.type}-filter-pattern-checkbox` + ); + + const includeFilterInfo = await findByTestId( + container, + 'filter-pattern-include-info' + ); + const excludeFilterInfo = await findByTestId( + container, + 'filter-pattern-exclude-info' + ); + const includeFilterInput = await findByTestId( + container, + 'filter-pattern-includes-table' + ); + const excludeFilterInput = await findByTestId( + container, + 'filter-pattern-excludes-table' + ); + + expect(includeFilterInfo).toBeInTheDocument(); + expect(excludeFilterInfo).toBeInTheDocument(); + expect(filterPatternContainer).toBeInTheDocument(); + expect(checkbox).toBeInTheDocument(); + expect(fieldContainer).toBeInTheDocument(); + expect(includeFilterInput).toBeInTheDocument(); + expect(excludeFilterInput).toBeInTheDocument(); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/FilterPattern/FilterPattern.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/FilterPattern/FilterPattern.tsx index 6e96e6a0640..f96c896bd2d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/FilterPattern/FilterPattern.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/FilterPattern/FilterPattern.tsx @@ -11,9 +11,15 @@ * limitations under the License. */ -import { capitalize } from 'lodash'; +import { Checkbox, Col, Input, Row, Typography } from 'antd'; +import { t } from 'i18next'; +import { capitalize, toLower } from 'lodash'; import React from 'react'; -import { getSeparator } from '../../../utils/CommonUtils'; +import { + getFilterPatternDocsLinks, + getSeparator, +} from '../../../utils/CommonUtils'; +import SVGIcons, { Icons } from '../../../utils/SvgUtils'; import { Field } from '../../Field/Field'; import { FilterPatternProps } from './filterPattern.interface'; @@ -42,41 +48,77 @@ const FilterPattern = ({ }; return ( -
-
- handleChecked(e.target.checked)} - /> - - -
+
+ + + handleChecked(e.target.checked)} + /> + + + + + {t('message.filter-pattern-info', { + filterPattern: type, + })}{' '} + + {t('label.read-more')}{' '} + + + + + {checked && (
- - {t('label.include')}: + + {t('message.filter-pattern-include-exclude-info', { + activity: toLower(t('label.include')), + filterPattern: type, + })} + + - - {t('label.exclude')}: + + {t('message.filter-pattern-include-exclude-info', { + activity: toLower(t('label.exclude')), + filterPattern: type, + })} + + ({ useTranslation: jest.fn().mockReturnValue({ t: (key) => key, }), + t: (key) => key, })); diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx index d09ba589da2..468abd9b5db 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx @@ -19,9 +19,7 @@ import classNames from 'classnames'; import i18n from 'i18next'; import { capitalize, - differenceWith, isEmpty, - isEqual, isNil, isNull, isString, @@ -38,12 +36,11 @@ import { RecentlyViewed, RecentlyViewedData, } from 'Models'; -import React, { FormEvent } from 'react'; +import React from 'react'; import { Link } from 'react-router-dom'; import { reactLocalStorage } from 'reactjs-localstorage'; import AppState from '../AppState'; import { getFeedCount } from '../axiosAPIs/feedsAPI'; -import { Button } from '../components/buttons/Button/Button'; import { getDayCron, getHourCron, @@ -57,7 +54,6 @@ import { imageTypes, LOCALSTORAGE_RECENTLY_SEARCHED, LOCALSTORAGE_RECENTLY_VIEWED, - TITLE_FOR_NON_OWNER_ACTION, } from '../constants/constants'; import { UrlEntityCharRegEx, @@ -65,7 +61,7 @@ import { } from '../constants/regex.constants'; import { SIZE } from '../enums/common.enum'; import { EntityType, FqnPart, TabSpecificField } from '../enums/entity.enum'; -import { Ownership } from '../enums/mydata.enum'; +import { FilterPatternEnum } from '../enums/filterPattern.enum'; import { Kpi } from '../generated/dataInsight/kpi/kpi'; import { Bot } from '../generated/entity/bot'; import { Dashboard } from '../generated/entity/data/dashboard'; @@ -91,7 +87,6 @@ import Fqn from './Fqn'; import { LIST_CAP } from './PermissionsUtils'; import { getRoleWithFqnPath, getTeamsWithFqnPath } from './RouterUtils'; import { serviceTypeLogo } from './ServiceUtils'; -import SVGIcons, { Icons } from './SvgUtils'; import { getTierFromSearchTableTags } from './TableUtils'; import { TASK_ENTITIES } from './TasksUtils'; import { showErrorToast } from './ToastUtils'; @@ -362,41 +357,6 @@ export const addToRecentViewed = (eData: RecentlyViewedData): void => { setRecentlyViewedData(recentlyViewed.data); }; -export const getHtmlForNonAdminAction = (isClaimOwner: boolean) => { - return ( - <> -

{TITLE_FOR_NON_OWNER_ACTION}

- {!isClaimOwner ?

Claim ownership in Manage

: null} - - ); -}; - -export const getOwnerIds = ( - filter: Ownership, - userDetails: User, - nonSecureUserDetails: User -): Array => { - if (filter === Ownership.OWNER) { - if (!isEmpty(userDetails)) { - return [ - ...(userDetails.teams?.map((team) => team.id) || []), - userDetails.id, - ]; - } else { - if (!isEmpty(nonSecureUserDetails)) { - return [ - ...(nonSecureUserDetails.teams?.map((team) => team.id) || []), - nonSecureUserDetails.id, - ]; - } else { - return []; - } - } - } else { - return [userDetails.id || nonSecureUserDetails.id]; - } -}; - export const getActiveCatClass = (name: string, activeName = '') => { return activeName === name ? 'activeCategory' : ''; }; @@ -413,18 +373,6 @@ export const errorMsg = (value: string) => { ); }; -export const validMsg = (value: string) => { - return ( -
- - {value} - -
- ); -}; - export const requiredField = (label: string, excludeSpace = false) => ( <> {label}{' '} @@ -470,14 +418,6 @@ export const getServiceLogo = ( return null; }; -export const getSvgArrow = (isActive: boolean) => { - return isActive ? ( - - ) : ( - - ); -}; - export const isValidUrl = (href?: string) => { if (!href) { return false; @@ -522,10 +462,6 @@ export const getFields = (defaultFields: string, tabSpecificField: string) => { return `${defaultFields}, ${tabSpecificField}`; }; -export const restrictFormSubmit = (e: FormEvent) => { - e.preventDefault(); -}; - export const getEntityMissingError = (entityType: string, fqn: string) => { return (

@@ -534,47 +470,6 @@ export const getEntityMissingError = (entityType: string, fqn: string) => { ); }; -export const getDocButton = (label: string, url: string, dataTestId = '') => { - return ( - - ); -}; - export const getNameFromFQN = (fqn: string): string => { const arr = fqn.split(FQN_SEPARATOR_CHAR); @@ -824,13 +719,6 @@ export const getTeamsUser = ( return; }; -export const getDiffArray = ( - compareWith: string[], - toCompare: string[] -): string[] => { - return differenceWith(compareWith, toCompare, isEqual); -}; - export const getHostNameFromURL = (url: string) => { if (isValidUrl(url)) { const domain = new URL(url); @@ -1063,3 +951,33 @@ export const sortTagsCaseInsensitive = (tags: TagLabel[]) => { tag1.tagFQN.toLowerCase() < tag2.tagFQN.toLowerCase() ? -1 : 1 ); }; + +/** + * It returns a link to the documentation for the given filter pattern type + * @param {FilterPatternEnum} type - The type of filter pattern. + * @returns A string + */ +export const getFilterPatternDocsLinks = (type: FilterPatternEnum) => { + switch (type) { + case FilterPatternEnum.DATABASE: + case FilterPatternEnum.SCHEMA: + case FilterPatternEnum.TABLE: + return `https://docs.open-metadata.org/connectors/ingestion/workflows/metadata/filter-patterns/${FilterPatternEnum.DATABASE}#${type}-filter-pattern`; + + case FilterPatternEnum.DASHBOARD: + case FilterPatternEnum.CHART: + return 'https://docs.open-metadata.org/connectors/dashboard/metabase#6-configure-metadata-ingestion'; + + case FilterPatternEnum.TOPIC: + return 'https://docs.open-metadata.org/connectors/messaging/kafka#6-configure-metadata-ingestion'; + + case FilterPatternEnum.PIPELINE: + return 'https://docs.open-metadata.org/connectors/pipeline/airflow#6-configure-metadata-ingestion'; + + case FilterPatternEnum.MLMODEL: + return 'https://docs.open-metadata.org/connectors/ml-model/mlflow'; + + default: + return 'https://docs.open-metadata.org/connectors/ingestion/workflows/metadata/filter-patterns'; + } +};