chore(ui): advance search spec refactoring (#10167)

* chore(ui): advance search spec refactoring

* fix tier select button test id

* fix cypress json

* fixed single search with condition test cases

* cypress setting update

* fix tests

* fix failures

* revert cypress config

* fix flaky tests

* fix flakyness

---------

Co-authored-by: Shailesh Parmar <shailesh.parmar.webdev@gmail.com>
Co-authored-by: Sachin Chaurasiya <sachinchaurasiyachotey87@gmail.com>
This commit is contained in:
Chirag Madlani 2023-03-03 18:50:35 +05:30 committed by GitHub
parent 1ff76f5e65
commit f12e2c32e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 213 additions and 168 deletions

View File

@ -116,6 +116,7 @@ export const OPERATOR = {
}; };
export const searchForField = (condition, fieldid, searchCriteria, index) => { export const searchForField = (condition, fieldid, searchCriteria, index) => {
interceptURL('GET', '/api/v1/search/suggest?q=*', 'suggestApi');
// Click on field dropdown // Click on field dropdown
cy.get('.rule--field > .ant-select > .ant-select-selector') cy.get('.rule--field > .ant-select > .ant-select-selector')
.eq(index) .eq(index)
@ -134,7 +135,6 @@ export const searchForField = (condition, fieldid, searchCriteria, index) => {
cy.get('.rule--operator .ant-select-selection-item') cy.get('.rule--operator .ant-select-selection-item')
.should('be.visible') .should('be.visible')
.should('contain', `${condition}`); .should('contain', `${condition}`);
cy.wait(500);
// Verify the search criteria for the condition // Verify the search criteria for the condition
cy.get('body').then(($body) => { cy.get('body').then(($body) => {
@ -148,14 +148,9 @@ export const searchForField = (condition, fieldid, searchCriteria, index) => {
.eq(index) .eq(index)
.should('be.visible') .should('be.visible')
.type(searchCriteria); .type(searchCriteria);
} // select value from dropdown
}); verifyResponseStatusCode('@suggestApi', 200);
cy.get(`.ant-select-dropdown [title = '${searchCriteria}']`)
cy.wait(1000);
// if condition has a dropdown then select value from dropdown
cy.get('body').then(($body) => {
if ($body.find(`.ant-select-dropdown [title="${searchCriteria}"]`).length) {
cy.get(`[title = '${searchCriteria}']`)
.should('be.visible') .should('be.visible')
.trigger('mouseover') .trigger('mouseover')
.trigger('click'); .trigger('click');
@ -179,11 +174,19 @@ export const goToAdvanceSearch = () => {
.scrollIntoView() .scrollIntoView()
.should('exist') .should('exist')
.and('be.visible'); .and('be.visible');
cy.wait(1000);
// Click on advance search button
cy.get('[data-testid="advance-search-button"]').should('be.visible').click();
cy.wait(1000); cy.wait('@explorePage').then(() => {
// Click on advance search button
cy.get('[data-testid="advance-search-button"]')
.should('be.visible')
.click();
cy.get('.ant-btn')
.contains('Reset')
.scrollIntoView()
.should('be.visible')
.click();
});
}; };
export const checkmustPaths = ( export const checkmustPaths = (
@ -316,16 +319,15 @@ export const addOwner = (searchTerm, ownerName) => {
verifyResponseStatusCode('@searchOwner', 200); verifyResponseStatusCode('@searchOwner', 200);
interceptURL('PATCH', '/api/v1/tables/*', 'validateOwner'); interceptURL('PATCH', '/api/v1/tables/*', 'tablePatch');
// Selecting the user // Selecting the user
cy.get('[data-testid="user-tag"]') cy.get(`[data-testid="user-tag"]`)
.contains(ownerName) .contains(ownerName)
.should('exist') .should('exist')
.scrollIntoView()
.and('be.visible') .and('be.visible')
.click(); .click();
verifyResponseStatusCode('@validateOwner', 200);
cy.get('[data-testid="owner-link"]') cy.get('[data-testid="owner-link"]')
.scrollIntoView() .scrollIntoView()
.invoke('text') .invoke('text')
@ -336,6 +338,7 @@ export const addOwner = (searchTerm, ownerName) => {
export const addTier = (tier) => { export const addTier = (tier) => {
cy.get('[data-testid="appbar-item-explore"]') cy.get('[data-testid="appbar-item-explore"]')
.scrollIntoView()
.should('exist') .should('exist')
.and('be.visible') .and('be.visible')
.click(); .click();
@ -352,14 +355,12 @@ export const addTier = (tier) => {
.should('be.visible') .should('be.visible')
.click(); .click();
cy.get('[data-testid="select-tier-buuton"]') cy.get('[data-testid="select-tier-button"]')
.first() .first()
.should('exist') .should('exist')
.should('be.visible') .should('be.visible')
.click(); .click();
cy.wait(1000);
cy.get('[data-testid="tags"] > [data-testid="add-tag"]').should( cy.get('[data-testid="tags"] > [data-testid="add-tag"]').should(
'contain', 'contain',
'Tier1' 'Tier1'
@ -367,6 +368,9 @@ export const addTier = (tier) => {
}; };
export const addTag = (tag) => { export const addTag = (tag) => {
cy.intercept('/api/v1/testCase?fields=testCaseResult*').as('testCaseResults');
cy.intercept('/api/v1/feed?entityLink=*').as('entityLink');
cy.get('[data-testid="appbar-item-explore"]') cy.get('[data-testid="appbar-item-explore"]')
.should('exist') .should('exist')
.and('be.visible') .and('be.visible')
@ -377,15 +381,19 @@ export const addTag = (tag) => {
.scrollIntoView() .scrollIntoView()
.should('be.visible') .should('be.visible')
.click(); .click();
cy.wait(['@testCaseResults', '@entityLink']).then(() => {
cy.get('[data-testid="tags"] > [data-testid="add-tag"]') cy.get('[data-testid="tags"] > [data-testid="add-tag"]')
.eq(0) .eq(0)
.should('be.visible') .should('be.visible')
.scrollIntoView() .scrollIntoView()
.click(); .click();
cy.wait(500); cy.get('[data-testid="tag-selector"]')
cy.get('[data-testid="tag-selector"]').should('be.visible').click().type(tag); .should('be.visible')
cy.wait(500); .click()
.type(tag);
cy.get('.ant-select-item-option-content').should('be.visible').click(); cy.get('.ant-select-item-option-content').should('be.visible').click();
cy.get( cy.get(
'[data-testid="tags-wrapper"] > [data-testid="tag-container"]' '[data-testid="tags-wrapper"] > [data-testid="tag-container"]'
@ -395,6 +403,7 @@ export const addTag = (tag) => {
.scrollIntoView() .scrollIntoView()
.should('be.visible') .should('be.visible')
.contains(tag); .contains(tag);
});
}; };
export const checkAddGroupWithOperator = ( export const checkAddGroupWithOperator = (
@ -430,7 +439,6 @@ export const checkAddGroupWithOperator = (
cy.get('.rule--operator .ant-select-selection-item') cy.get('.rule--operator .ant-select-selection-item')
.should('be.visible') .should('be.visible')
.should('contain', `${condition_1}`); .should('contain', `${condition_1}`);
cy.wait(500);
// Verify the search criteria for the condition // Verify the search criteria for the condition
cy.get('body').then(($body) => { cy.get('body').then(($body) => {
@ -440,30 +448,31 @@ export const checkAddGroupWithOperator = (
.should('be.visible') .should('be.visible')
.type(searchCriteria_1); .type(searchCriteria_1);
} else { } else {
interceptURL('GET', '/api/v1/search/suggest?q=*', 'suggestApi');
cy.get('.widget--widget > .ant-select > .ant-select-selector') cy.get('.widget--widget > .ant-select > .ant-select-selector')
.eq(index_1) .eq(index_1)
.should('be.visible') .should('be.visible')
.type(searchCriteria_1); .type(searchCriteria_1);
}
});
cy.wait(1000); verifyResponseStatusCode('@suggestApi', 200);
// if condition has a dropdown then select value from dropdown cy.get('.ant-select-dropdown')
cy.get('body').then(($body) => { .not('.ant-select-dropdown-hidden')
if ( .find(`[title="${searchCriteria_1}"]`)
$body.find(`.ant-select-dropdown [title="${searchCriteria_1}"]`).length
) {
cy.get(`[title = '${searchCriteria_1}']`)
.should('be.visible') .should('be.visible')
.trigger('mouseover') .trigger('mouseover')
.trigger('click'); .trigger('click');
} }
}); });
// To close the dropdown for anyin and notin condition // To close the dropdown for anyin and notin condition
cy.get('.ant-modal-header').click(); cy.get('.ant-modal-header').click();
// Select add-group button // Select add-group button
cy.get('.action--ADD-GROUP').eq(0).should('be.visible').click(); cy.get('.action--ADD-GROUP')
.eq(0)
.scrollIntoView()
.should('be.visible')
.click();
// Select the AND/OR condition // Select the AND/OR condition
cy.get( cy.get(
@ -483,7 +492,6 @@ export const checkAddGroupWithOperator = (
cy.get('.rule--operator .ant-select-selection-item') cy.get('.rule--operator .ant-select-selection-item')
.should('be.visible') .should('be.visible')
.should('contain', `${condition_2}`); .should('contain', `${condition_2}`);
cy.wait(500);
// Verify the search criteria for the condition // Verify the search criteria for the condition
cy.get('body').then(($body) => { cy.get('body').then(($body) => {
@ -493,38 +501,25 @@ export const checkAddGroupWithOperator = (
.should('be.visible') .should('be.visible')
.type(searchCriteria_2); .type(searchCriteria_2);
} else { } else {
interceptURL('GET', '/api/v1/search/suggest?q=*', 'suggestApi');
cy.get('.widget--widget > .ant-select > .ant-select-selector') cy.get('.widget--widget > .ant-select > .ant-select-selector')
.eq(index_2) .eq(index_2)
.should('be.visible') .should('be.visible')
.type(searchCriteria_2); .type(searchCriteria_2);
} verifyResponseStatusCode('@suggestApi', 200);
});
cy.wait(1000); cy.get('.ant-select-dropdown')
// if condition has a dropdown then select value from dropdown .not('.ant-select-dropdown-hidden')
cy.get('body').then(($body) => { .find(`[title="${searchCriteria_2}"]`)
if ( .should('be.visible')
$body.find(`.ant-select-dropdown [title="${searchCriteria_2}"]`).length && .trigger('mouseover')
searchCriteria_2 === 'Tier.Tier2' .trigger('click');
) {
cy.get(`[title = "${searchCriteria_2}"]`)
.eq(1)
.contains(searchCriteria_2)
.click({ force: true });
} else if (
$body.find(`.ant-select-dropdown [title="${searchCriteria_2}"]`).length
) {
cy.get(`[title = "${searchCriteria_2}"]`)
.contains(searchCriteria_2)
.click();
} }
}); });
interceptURL( interceptURL(
'GET', 'GET',
`/api/v1/search/query?q=&index=*&from=0&size=10&deleted=false&query_filter=*${filter_1}*${encodeURI( `/api/v1/search/query?q=&index=*&from=0&size=10&deleted=false&query_filter=*${searchCriteria_1}*&sort_field=_score&sort_order=desc`,
searchCriteria_1
)}*${filter_2}*${encodeURI(response_2)}*&sort_field=_score&sort_order=desc`,
'search' 'search'
); );
@ -566,7 +561,6 @@ export const checkAddRuleWithOperator = (
cy.get('.rule--operator .ant-select-selection-item') cy.get('.rule--operator .ant-select-selection-item')
.should('be.visible') .should('be.visible')
.should('contain', `${condition_1}`); .should('contain', `${condition_1}`);
cy.wait(500);
// Verify the search criteria for the condition // Verify the search criteria for the condition
cy.get('body').then(($body) => { cy.get('body').then(($body) => {
@ -576,25 +570,22 @@ export const checkAddRuleWithOperator = (
.should('be.visible') .should('be.visible')
.type(searchCriteria_1); .type(searchCriteria_1);
} else { } else {
interceptURL('GET', '/api/v1/search/suggest?q=*', 'suggestApi');
cy.get('.widget--widget > .ant-select > .ant-select-selector') cy.get('.widget--widget > .ant-select > .ant-select-selector')
.eq(index_1) .eq(index_1)
.should('be.visible') .should('be.visible')
.type(searchCriteria_1); .type(searchCriteria_1);
}
});
cy.wait(1000); verifyResponseStatusCode('@suggestApi', 200);
// if condition has a dropdown then select value from dropdown
cy.get('body').then(($body) => {
if (
$body.find(`.ant-select-dropdown [title="${searchCriteria_1}"]`).length
) {
cy.get(`[title = '${searchCriteria_1}']`) cy.get(`[title = '${searchCriteria_1}']`)
.should('be.visible') .should('be.visible')
.trigger('mouseover') .trigger('mouseover')
.trigger('click'); .trigger('click');
} }
}); });
// To close the dropdown for anyin and notin condition // To close the dropdown for anyin and notin condition
cy.get('.ant-modal-header').click(); cy.get('.ant-modal-header').click();
@ -619,7 +610,6 @@ export const checkAddRuleWithOperator = (
cy.get('.rule--operator .ant-select-selection-item') cy.get('.rule--operator .ant-select-selection-item')
.should('be.visible') .should('be.visible')
.should('contain', `${condition_2}`); .should('contain', `${condition_2}`);
cy.wait(500);
// Verify the search criteria for the condition // Verify the search criteria for the condition
cy.get('body').then(($body) => { cy.get('body').then(($body) => {
@ -629,28 +619,18 @@ export const checkAddRuleWithOperator = (
.should('be.visible') .should('be.visible')
.type(searchCriteria_2); .type(searchCriteria_2);
} else { } else {
interceptURL('GET', '/api/v1/search/suggest?q=*', 'suggestApi');
cy.get('.widget--widget > .ant-select > .ant-select-selector') cy.get('.widget--widget > .ant-select > .ant-select-selector')
.eq(index_2) .eq(index_2)
.should('be.visible') .should('be.visible')
.type(searchCriteria_2); .type(searchCriteria_2);
}
});
cy.wait(1000); verifyResponseStatusCode('@suggestApi', 200);
// if condition has a dropdown then select value from dropdown
cy.get('body').then(($body) => { cy.get('.ant-select-dropdown')
if ( .not('.ant-select-dropdown-hidden')
$body.find(`.ant-select-dropdown [title="${searchCriteria_2}"]`).length && .find(`[title="${searchCriteria_2}"]`)
searchCriteria_2 === 'Tier.Tier2' .should('be.visible')
) {
cy.get(`[title = "${searchCriteria_2}"]`)
.eq(1)
.contains(searchCriteria_2)
.click({ force: true });
} else if (
$body.find(`.ant-select-dropdown [title="${searchCriteria_2}"]`).length
) {
cy.get(`[title = "${searchCriteria_2}"]`)
.contains(searchCriteria_2) .contains(searchCriteria_2)
.click(); .click();
} }

View File

@ -158,7 +158,7 @@ export const testServiceCreationAndIngestion = (
'api/v1/services/ingestionPipelines/*', 'api/v1/services/ingestionPipelines/*',
'getIngestionPipelineStatus' 'getIngestionPipelineStatus'
); );
cy.get('[data-testid="next-button"]').click(); cy.get('[data-testid="next-button"]').should('exist').click();
verifyResponseStatusCode('@getIngestionPipelineStatus', 200); verifyResponseStatusCode('@getIngestionPipelineStatus', 200);
// Connection Details in step 3 // Connection Details in step 3
cy.get('[data-testid="add-new-service-container"]') cy.get('[data-testid="add-new-service-container"]')

View File

@ -26,7 +26,6 @@ import {
FIELDS, FIELDS,
OPERATOR, OPERATOR,
} from '../../common/advancedSearch'; } from '../../common/advancedSearch';
import { import {
deleteCreatedService, deleteCreatedService,
interceptURL, interceptURL,
@ -34,7 +33,6 @@ import {
testServiceCreationAndIngestion, testServiceCreationAndIngestion,
verifyResponseStatusCode, verifyResponseStatusCode,
} from '../../common/common'; } from '../../common/common';
import { API_SERVICE } from '../../constants/constants'; import { API_SERVICE } from '../../constants/constants';
import { MYSQL } from '../../constants/service.constants'; import { MYSQL } from '../../constants/service.constants';
@ -111,7 +109,7 @@ describe('Single filed search', () => {
field.responseValueFirstGroup field.responseValueFirstGroup
); );
}); });
cy.wait(1000);
Object.values(CONDITIONS_MUST_NOT).forEach((condition) => { Object.values(CONDITIONS_MUST_NOT).forEach((condition) => {
checkmust_notPaths( checkmust_notPaths(
condition.name, condition.name,

View File

@ -147,7 +147,7 @@ describe('Entity Details Page', () => {
.should('be.visible') .should('be.visible')
.click(); .click();
cy.get('[data-testid="select-tier-buuton"]') cy.get('[data-testid="select-tier-button"]')
.first() .first()
.should('exist') .should('exist')
.should('be.visible') .should('be.visible')

View File

@ -781,8 +781,8 @@ describe('Glossary page should work properly', () => {
'have.value', 'have.value',
GLOSSARY_TERM_WITH_DETAILS.relatedTerms GLOSSARY_TERM_WITH_DETAILS.relatedTerms
); );
verifyResponseStatusCode('@searchGlossaryTerm', 200);
cy.get('[data-testid="loader"]').should('be.visible'); cy.get('[data-testid="loader"]').should('be.visible');
verifyResponseStatusCode('@searchGlossaryTerm', 200);
cy.get('[data-testid="user-card-container"]').should('be.visible'); cy.get('[data-testid="user-card-container"]').should('be.visible');
cy.get('[data-testid="checkboxAddUser"]').should('be.visible').click(); cy.get('[data-testid="checkboxAddUser"]').should('be.visible').click();
cy.get('[data-testid="saveButton"]').should('be.visible').click(); cy.get('[data-testid="saveButton"]').should('be.visible').click();
@ -798,8 +798,8 @@ describe('Glossary page should work properly', () => {
cy.get('[data-testid="searchbar"]') cy.get('[data-testid="searchbar"]')
.should('be.visible') .should('be.visible')
.type(GLOSSARY_TERM_WITH_DETAILS.reviewer); .type(GLOSSARY_TERM_WITH_DETAILS.reviewer);
verifyResponseStatusCode('@searchGlossaryTerm', 200);
cy.get('[data-testid="loader"]').should('be.visible'); cy.get('[data-testid="loader"]').should('be.visible');
verifyResponseStatusCode('@searchGlossaryTerm', 200);
cy.get('[data-testid="user-card-container"]').should('be.visible'); cy.get('[data-testid="user-card-container"]').should('be.visible');
cy.get('[data-testid="checkboxAddUser"]').should('be.visible').click(); cy.get('[data-testid="checkboxAddUser"]').should('be.visible').click();
cy.get('[data-testid="save-button"]').should('be.visible').click(); cy.get('[data-testid="save-button"]').should('be.visible').click();

View File

@ -11,7 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import React, { useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { import {
Builder, Builder,
Config, Config,
@ -30,7 +30,6 @@ const AdvancedSearch: React.FC<AdvancedSearchProps> = ({
onChangeJsonTree, onChangeJsonTree,
onChangeQueryFilter, onChangeQueryFilter,
searchIndex, searchIndex,
onAppliedFilterChange,
}) => { }) => {
const [config, setConfig] = useState<Config>(getQbConfigs(searchIndex)); const [config, setConfig] = useState<Config>(getQbConfigs(searchIndex));
@ -42,12 +41,22 @@ const AdvancedSearch: React.FC<AdvancedSearchProps> = ({
useEffect(() => setConfig(getQbConfigs(searchIndex)), [searchIndex]); useEffect(() => setConfig(getQbConfigs(searchIndex)), [searchIndex]);
useEffect(() => { useEffect(() => {
onAppliedFilterChange(QbUtils.sqlFormat(immutableTree, config) ?? ''); onChangeQueryFilter(
onChangeQueryFilter({ {
query: elasticSearchFormat(immutableTree, config), query: elasticSearchFormat(immutableTree, config),
}); },
QbUtils.sqlFormat(immutableTree, config) ?? ''
);
}, [immutableTree, config]); }, [immutableTree, config]);
const handleChange = useCallback(
(nTree, nConfig) => {
setConfig(nConfig);
onChangeJsonTree(QbUtils.getTree(nTree));
},
[setConfig, onChangeJsonTree]
);
return ( return (
<Query <Query
{...config} {...config}
@ -57,10 +66,7 @@ const AdvancedSearch: React.FC<AdvancedSearchProps> = ({
</div> </div>
)} )}
value={immutableTree} value={immutableTree}
onChange={(nTree, nConfig) => { onChange={handleChange}
setConfig(nConfig);
onChangeJsonTree(QbUtils.getTree(nTree));
}}
/> />
); );
}; };

View File

@ -19,9 +19,9 @@ export interface AdvancedSearchProps {
searchIndex: SearchIndex; searchIndex: SearchIndex;
onChangeJsonTree: (tree: JsonTree) => void; onChangeJsonTree: (tree: JsonTree) => void;
onChangeQueryFilter: ( onChangeQueryFilter: (
queryFilter: Record<string, unknown> | undefined queryFilter: Record<string, unknown> | undefined,
sqlFilter: string
) => void; ) => void;
onAppliedFilterChange: (value: string) => void;
} }
export type FilterObject = Record<string, string[]>; export type FilterObject = Record<string, string[]>;

View File

@ -12,21 +12,28 @@
*/ */
import { Button, Modal, Space, Typography } from 'antd'; import { Button, Modal, Space, Typography } from 'antd';
import { delay } from 'lodash'; import { debounce, delay, isString } from 'lodash';
import React, { FunctionComponent, useState } from 'react'; import Qs from 'qs';
import { JsonTree } from 'react-awesome-query-builder'; import React, {
FunctionComponent,
useCallback,
useMemo,
useState,
} from 'react';
import { JsonTree, Utils } from 'react-awesome-query-builder';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useHistory, useLocation } from 'react-router-dom';
import { SearchIndex } from '../../enums/search.enum'; import { SearchIndex } from '../../enums/search.enum';
import AdvancedSearch from '../AdvancedSearch/AdvancedSearch.component'; import AdvancedSearch from '../AdvancedSearch/AdvancedSearch.component';
interface Props { interface Props {
visible: boolean; visible: boolean;
onSubmit: (filter?: Record<string, unknown>) => void; onSubmit: (
filter: Record<string, unknown> | undefined,
sqlFilter: string
) => void;
onCancel: () => void; onCancel: () => void;
searchIndex: SearchIndex; searchIndex: SearchIndex;
onChangeJsonTree: (tree?: JsonTree) => void;
jsonTree?: JsonTree;
onAppliedFilterChange: (value: string) => void;
} }
export const AdvancedSearchModal: FunctionComponent<Props> = ({ export const AdvancedSearchModal: FunctionComponent<Props> = ({
@ -34,24 +41,79 @@ export const AdvancedSearchModal: FunctionComponent<Props> = ({
onSubmit, onSubmit,
onCancel, onCancel,
searchIndex, searchIndex,
onChangeJsonTree,
jsonTree,
onAppliedFilterChange,
}: Props) => { }: Props) => {
const [queryFilter, setQueryFilter] = useState< const [queryFilter, setQueryFilter] = useState<
Record<string, unknown> | undefined Record<string, unknown> | undefined
>(); >();
const [sqlFilter, setSQLFilter] = useState<string>('');
const { t } = useTranslation(); const { t } = useTranslation();
const history = useHistory();
const location = useLocation();
const parsedSearch = useMemo(
() =>
Qs.parse(
location.search.startsWith('?')
? location.search.substr(1)
: location.search
),
[location.search]
);
const jsonTree = useMemo(() => {
if (!isString(parsedSearch.queryFilter)) {
return undefined;
}
try {
const queryFilter = JSON.parse(parsedSearch.queryFilter);
const immutableTree = Utils.loadTree(queryFilter as JsonTree);
if (Utils.isValidTree(immutableTree)) {
return queryFilter as JsonTree;
}
} catch {
return undefined;
}
return undefined;
}, [location.search]);
const [treeInternal, setTreeInternal] = useState<JsonTree | undefined>(
jsonTree
);
const handleTreeUpdate = useCallback(
(tree?: JsonTree) => {
history.push({
pathname: history.location.pathname,
search: Qs.stringify({
...parsedSearch,
queryFilter: tree ? JSON.stringify(tree) : undefined,
page: 1,
}),
});
setTreeInternal(undefined);
},
[history, parsedSearch]
);
const handleAdvanceSearchReset = () => { const handleAdvanceSearchReset = () => {
delay(onChangeJsonTree, 100); delay(handleTreeUpdate, 100);
}; };
const handleQueryFilterUpdate = useCallback(
(queryFilter: Record<string, unknown> | undefined, sqlFilter: string) => {
setQueryFilter(queryFilter);
setSQLFilter(sqlFilter);
},
[setQueryFilter, setSQLFilter]
);
return ( return (
<Modal <Modal
closable
destroyOnClose destroyOnClose
closable={false} closeIcon={null}
footer={ footer={
<Space className="justify-between w-full"> <Space className="justify-between w-full">
<Button <Button
@ -65,7 +127,8 @@ export const AdvancedSearchModal: FunctionComponent<Props> = ({
<Button <Button
type="primary" type="primary"
onClick={() => { onClick={() => {
onSubmit(queryFilter); handleTreeUpdate(treeInternal);
onSubmit(queryFilter, sqlFilter);
onCancel(); onCancel();
}}> }}>
{t('label.apply')} {t('label.apply')}
@ -78,16 +141,16 @@ export const AdvancedSearchModal: FunctionComponent<Props> = ({
title={t('label.advanced-entity', { title={t('label.advanced-entity', {
entity: t('label.search'), entity: t('label.search'),
})} })}
width={950}> width={950}
onCancel={onCancel}>
<Typography.Text data-testid="advanced-search-message"> <Typography.Text data-testid="advanced-search-message">
{t('message.advanced-search-message')} {t('message.advanced-search-message')}
</Typography.Text> </Typography.Text>
<AdvancedSearch <AdvancedSearch
jsonTree={jsonTree} jsonTree={treeInternal}
searchIndex={searchIndex} searchIndex={searchIndex}
onAppliedFilterChange={onAppliedFilterChange} onChangeJsonTree={debounce(setTreeInternal, 1)}
onChangeJsonTree={(nTree) => onChangeJsonTree(nTree)} onChangeQueryFilter={handleQueryFilterUpdate}
onChangeQueryFilter={setQueryFilter}
/> />
</Modal> </Modal>
); );

View File

@ -60,8 +60,6 @@ import SortingDropDown from './SortingDropDown';
const Explore: React.FC<ExploreProps> = ({ const Explore: React.FC<ExploreProps> = ({
searchResults, searchResults,
tabCounts, tabCounts,
advancedSearchJsonTree,
onChangeAdvancedSearchJsonTree,
onChangeAdvancedSearchQueryFilter, onChangeAdvancedSearchQueryFilter,
postFilter, postFilter,
onChangePostFilter, onChangePostFilter,
@ -91,9 +89,6 @@ const Explore: React.FC<ExploreProps> = ({
const [appliedFilterSQLFormat, setAppliedFilterSQLFormat] = const [appliedFilterSQLFormat, setAppliedFilterSQLFormat] =
useState<string>(''); useState<string>('');
const handleAppliedFilterChange = (value: string) =>
setAppliedFilterSQLFormat(value);
const handleClosePanel = () => { const handleClosePanel = () => {
setShowSummaryPanel(false); setShowSummaryPanel(false);
}; };
@ -363,13 +358,13 @@ const Explore: React.FC<ExploreProps> = ({
)} )}
</Row> </Row>
<AdvancedSearchModal <AdvancedSearchModal
jsonTree={advancedSearchJsonTree}
searchIndex={searchIndex} searchIndex={searchIndex}
visible={showAdvanceSearchModal} visible={showAdvanceSearchModal}
onAppliedFilterChange={handleAppliedFilterChange}
onCancel={() => setShowAdvanceSearchModal(false)} onCancel={() => setShowAdvanceSearchModal(false)}
onChangeJsonTree={onChangeAdvancedSearchJsonTree} onSubmit={(query, sqlFilter) => {
onSubmit={onChangeAdvancedSearchQueryFilter} onChangeAdvancedSearchQueryFilter(query);
setAppliedFilterSQLFormat(sqlFilter);
}}
/> />
</PageLayoutV1> </PageLayoutV1>
); );

View File

@ -69,7 +69,6 @@ describe('Test Explore component', () => {
[SearchIndex.PIPELINE]: 5, [SearchIndex.PIPELINE]: 5,
[SearchIndex.MLMODEL]: 2, [SearchIndex.MLMODEL]: 2,
}} }}
onChangeAdvancedSearchJsonTree={mockFunction}
onChangeAdvancedSearchQueryFilter={mockFunction} onChangeAdvancedSearchQueryFilter={mockFunction}
onChangePostFilter={mockFunction} onChangePostFilter={mockFunction}
onChangeSearchIndex={mockFunction} onChangeSearchIndex={mockFunction}

View File

@ -13,7 +13,6 @@
import { DefaultOptionType } from 'antd/lib/select'; import { DefaultOptionType } from 'antd/lib/select';
import { SORT_ORDER } from 'enums/common.enum'; import { SORT_ORDER } from 'enums/common.enum';
import { JsonTree } from 'react-awesome-query-builder';
import { SearchIndex } from '../../enums/search.enum'; import { SearchIndex } from '../../enums/search.enum';
import { Dashboard } from '../../generated/entity/data/dashboard'; import { Dashboard } from '../../generated/entity/data/dashboard';
import { Mlmodel } from '../../generated/entity/data/mlmodel'; import { Mlmodel } from '../../generated/entity/data/mlmodel';
@ -50,8 +49,6 @@ export interface ExploreProps {
searchResults?: SearchResponse<ExploreSearchIndex>; searchResults?: SearchResponse<ExploreSearchIndex>;
advancedSearchJsonTree?: JsonTree;
onChangeAdvancedSearchJsonTree: (jsonTree: JsonTree | undefined) => void;
onChangeAdvancedSearchQueryFilter: ( onChangeAdvancedSearchQueryFilter: (
queryFilter: Record<string, unknown> | undefined queryFilter: Record<string, unknown> | undefined
) => void; ) => void;

View File

@ -46,7 +46,7 @@ describe('Test CardWithListing Component', () => {
expect(card).toBeInTheDocument(); expect(card).toBeInTheDocument();
expect(getByTestId('select-tier-buuton')).toBeInTheDocument(); expect(getByTestId('select-tier-button')).toBeInTheDocument();
}); });
it('OnClick onSelect function should call', () => { it('OnClick onSelect function should call', () => {
@ -98,7 +98,7 @@ describe('Test CardWithListing Component', () => {
expect(mockSelectFunction).toHaveBeenCalledTimes(1); expect(mockSelectFunction).toHaveBeenCalledTimes(1);
const tierSelectButton = getByTestId('select-tier-buuton'); const tierSelectButton = getByTestId('select-tier-button');
expect(tierSelectButton).toBeInTheDocument(); expect(tierSelectButton).toBeInTheDocument();
}); });
@ -127,7 +127,7 @@ describe('Test CardWithListing Component', () => {
expect(mockSelectFunction).toHaveBeenCalledTimes(1); expect(mockSelectFunction).toHaveBeenCalledTimes(1);
const tierSelectButton = getByTestId('select-tier-buuton'); const tierSelectButton = getByTestId('select-tier-button');
expect(tierSelectButton).toBeInTheDocument(); expect(tierSelectButton).toBeInTheDocument();

View File

@ -68,7 +68,7 @@ const CardListItem: FunctionComponent<Props> = ({
default: default:
return ( return (
<Button <Button
data-testid="select-tier-buuton" data-testid="select-tier-button"
size="small" size="small"
theme="primary" theme="primary"
onClick={() => onSave(tier)}> onClick={() => onSave(tier)}>
@ -88,7 +88,7 @@ const CardListItem: FunctionComponent<Props> = ({
} else { } else {
return ( return (
<Button <Button
data-testid="select-tier-buuton" data-testid="select-tier-button"
size="small" size="small"
theme="primary" theme="primary"
variant="outlined" variant="outlined"

View File

@ -13,7 +13,7 @@
import { Tooltip } from 'antd'; import { Tooltip } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import { isNil, isUndefined, toLower } from 'lodash'; import { isNil, isUndefined, toLower, toString } from 'lodash';
import React, { FunctionComponent, useEffect, useRef, useState } from 'react'; import React, { FunctionComponent, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { SIZE } from '../../enums/common.enum'; import { SIZE } from '../../enums/common.enum';
@ -163,6 +163,7 @@ const DropDownList: FunctionComponent<DropDownListProp> = ({
id={`menu-item-${index}`} id={`menu-item-${index}`}
key={index} key={index}
role="menuitem" role="menuitem"
title={toString(item.name)}
onClick={(e) => onClick={(e) =>
!item.disabled && item.value !== value && onSelect?.(e, item.value) !item.disabled && item.value !== value && onSelect?.(e, item.value)
}> }>
@ -179,8 +180,7 @@ const DropDownList: FunctionComponent<DropDownListProp> = ({
className={classNames( className={classNames(
'tw-truncate d-flex items-center justify-between', 'tw-truncate d-flex items-center justify-between',
widthClass widthClass
)} )}>
title={item.name as string}>
{item.name} {item.name}
{removeOwnerButton(item)} {removeOwnerButton(item)}
@ -327,6 +327,7 @@ const DropDownList: FunctionComponent<DropDownListProp> = ({
<> <>
<button <button
className="tw-z-10 tw-fixed tw-inset-0 tw-h-full tw-w-full tw-bg-black tw-opacity-0" className="tw-z-10 tw-fixed tw-inset-0 tw-h-full tw-w-full tw-bg-black tw-opacity-0"
data-testid="backdrop-button"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();

View File

@ -22,7 +22,13 @@ import {
import { SORT_ORDER } from 'enums/common.enum'; import { SORT_ORDER } from 'enums/common.enum';
import { isNil, isString } from 'lodash'; import { isNil, isString } from 'lodash';
import Qs from 'qs'; import Qs from 'qs';
import React, { FunctionComponent, useEffect, useMemo, useState } from 'react'; import React, {
FunctionComponent,
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import { JsonTree, Utils as QbUtils } from 'react-awesome-query-builder'; import { JsonTree, Utils as QbUtils } from 'react-awesome-query-builder';
import { useHistory, useLocation, useParams } from 'react-router-dom'; import { useHistory, useLocation, useParams } from 'react-router-dom';
import { searchQuery } from 'rest/searchAPI'; import { searchQuery } from 'rest/searchAPI';
@ -108,7 +114,7 @@ const ExplorePage: FunctionComponent = () => {
setAdvancedSearchQueryFilter(undefined); setAdvancedSearchQueryFilter(undefined);
}; };
const handleQueryFilterChange: ExploreProps['onChangeAdvancedSearchJsonTree'] = const handleQueryFilterChange = useCallback(
(queryFilter) => { (queryFilter) => {
history.push({ history.push({
search: Qs.stringify({ search: Qs.stringify({
@ -117,7 +123,9 @@ const ExplorePage: FunctionComponent = () => {
page: 1, page: 1,
}), }),
}); });
}; },
[history, parsedSearch]
);
const handlePostFilterChange: ExploreProps['onChangePostFilter'] = ( const handlePostFilterChange: ExploreProps['onChangePostFilter'] = (
postFilter postFilter
@ -268,12 +276,13 @@ const ExplorePage: FunctionComponent = () => {
page, page,
]); ]);
const handleAdvanceSearchQueryFilterChange = ( const handleAdvanceSearchQueryFilterChange = useCallback(
filter?: Record<string, unknown> (filter?: Record<string, unknown>) => {
) => {
handlePageChange(1); handlePageChange(1);
setAdvancedSearchQueryFilter(filter); setAdvancedSearchQueryFilter(filter);
}; },
[setAdvancedSearchQueryFilter]
);
useEffect(() => { useEffect(() => {
AppState.updateExplorePageTab(tab); AppState.updateExplorePageTab(tab);
@ -282,7 +291,6 @@ const ExplorePage: FunctionComponent = () => {
return ( return (
<PageContainerV1> <PageContainerV1>
<Explore <Explore
advancedSearchJsonTree={queryFilter}
loading={isLoading} loading={isLoading}
page={page} page={page}
postFilter={postFilter} postFilter={postFilter}
@ -292,7 +300,6 @@ const ExplorePage: FunctionComponent = () => {
sortOrder={sortOrder} sortOrder={sortOrder}
sortValue={sortValue} sortValue={sortValue}
tabCounts={searchHitCounts} tabCounts={searchHitCounts}
onChangeAdvancedSearchJsonTree={handleQueryFilterChange}
onChangeAdvancedSearchQueryFilter={handleAdvanceSearchQueryFilterChange} onChangeAdvancedSearchQueryFilter={handleAdvanceSearchQueryFilterChange}
onChangePage={handlePageChange} onChangePage={handlePageChange}
onChangePostFilter={handlePostFilterChange} onChangePostFilter={handlePostFilterChange}

View File

@ -161,7 +161,6 @@ const TourPage = () => {
sortOrder={INITIAL_SORT_ORDER} sortOrder={INITIAL_SORT_ORDER}
sortValue={INITIAL_SORT_FIELD} sortValue={INITIAL_SORT_FIELD}
tabCounts={explorePageCounts} tabCounts={explorePageCounts}
onChangeAdvancedSearchJsonTree={noop}
onChangeAdvancedSearchQueryFilter={noop} onChangeAdvancedSearchQueryFilter={noop}
onChangePostFilter={noop} onChangePostFilter={noop}
onChangeSearchIndex={noop} onChangeSearchIndex={noop}