mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-24 17:08:28 +00:00
GEN-1226: Add display name field in the advanced search filter (#17829)
* Add display name filter field for advanced search * Localization changes * Update advanced search tests to include display name filter checks * Fix the failing playwright tests * localization changes * Fix flaky tests --------- Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
parent
17d68ddd0c
commit
d65c9ce1f9
@ -50,6 +50,7 @@
|
|||||||
/playwright/e2e/.cache/
|
/playwright/e2e/.cache/
|
||||||
/playwright/.env
|
/playwright/.env
|
||||||
/playwright/.auth
|
/playwright/.auth
|
||||||
|
"/playwright/tsconfig.json"
|
||||||
|
|
||||||
# webpack
|
# webpack
|
||||||
/webpack
|
/webpack
|
||||||
|
@ -143,7 +143,7 @@ test.describe('Activity feed', () => {
|
|||||||
|
|
||||||
test('Assigned task should appear to task tab', async ({ page }) => {
|
test('Assigned task should appear to task tab', async ({ page }) => {
|
||||||
const value: TaskDetails = {
|
const value: TaskDetails = {
|
||||||
term: entity.entity.name,
|
term: entity.entity.displayName,
|
||||||
assignee: user1.responseData.name,
|
assignee: user1.responseData.name,
|
||||||
};
|
};
|
||||||
await redirectToHomePage(page);
|
await redirectToHomePage(page);
|
||||||
@ -309,7 +309,7 @@ test.describe('Activity feed', () => {
|
|||||||
|
|
||||||
test('Update Description Task on Columns', async ({ page }) => {
|
test('Update Description Task on Columns', async ({ page }) => {
|
||||||
const firstTaskValue: TaskDetails = {
|
const firstTaskValue: TaskDetails = {
|
||||||
term: entity4.entity.name,
|
term: entity4.entity.displayName,
|
||||||
assignee: user1.responseData.name,
|
assignee: user1.responseData.name,
|
||||||
description: 'Column Description 1',
|
description: 'Column Description 1',
|
||||||
columnName: entity4.entity.columns[0].name,
|
columnName: entity4.entity.columns[0].name,
|
||||||
@ -376,7 +376,7 @@ test.describe('Activity feed', () => {
|
|||||||
|
|
||||||
test('Comment and Close Task should work in Task Flow', async ({ page }) => {
|
test('Comment and Close Task should work in Task Flow', async ({ page }) => {
|
||||||
const value: TaskDetails = {
|
const value: TaskDetails = {
|
||||||
term: entity2.entity.name,
|
term: entity2.entity.displayName,
|
||||||
assignee: user1.responseData.name,
|
assignee: user1.responseData.name,
|
||||||
};
|
};
|
||||||
await redirectToHomePage(page);
|
await redirectToHomePage(page);
|
||||||
@ -436,7 +436,7 @@ test.describe('Activity feed', () => {
|
|||||||
|
|
||||||
test('Open and Closed Task Tab', async ({ page }) => {
|
test('Open and Closed Task Tab', async ({ page }) => {
|
||||||
const value: TaskDetails = {
|
const value: TaskDetails = {
|
||||||
term: entity3.entity.name,
|
term: entity3.entity.displayName,
|
||||||
assignee: user1.responseData.name,
|
assignee: user1.responseData.name,
|
||||||
};
|
};
|
||||||
await redirectToHomePage(page);
|
await redirectToHomePage(page);
|
||||||
@ -501,7 +501,7 @@ test.describe('Activity feed', () => {
|
|||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
const value: TaskDetails = {
|
const value: TaskDetails = {
|
||||||
term: entity4.entity.name,
|
term: entity4.entity.displayName,
|
||||||
assignee: user1.responseData.name,
|
assignee: user1.responseData.name,
|
||||||
};
|
};
|
||||||
await redirectToHomePage(page);
|
await redirectToHomePage(page);
|
||||||
@ -627,7 +627,7 @@ base.describe('Activity feed with Data Consumer User', () => {
|
|||||||
await performUserLogin(browser, user2);
|
await performUserLogin(browser, user2);
|
||||||
|
|
||||||
const value: TaskDetails = {
|
const value: TaskDetails = {
|
||||||
term: entity.entity.name,
|
term: entity.entity.displayName,
|
||||||
assignee: user2.responseData.name,
|
assignee: user2.responseData.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -760,7 +760,7 @@ base.describe('Activity feed with Data Consumer User', () => {
|
|||||||
await performUserLogin(browser, user2);
|
await performUserLogin(browser, user2);
|
||||||
|
|
||||||
const value: TaskDetails = {
|
const value: TaskDetails = {
|
||||||
term: entity2.entity.name,
|
term: entity2.entity.displayName,
|
||||||
assignee: user2.responseData.name,
|
assignee: user2.responseData.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -944,7 +944,7 @@ base.describe('Activity feed with Data Consumer User', () => {
|
|||||||
await performUserLogin(browser, viewAllUser);
|
await performUserLogin(browser, viewAllUser);
|
||||||
|
|
||||||
const value: TaskDetails = {
|
const value: TaskDetails = {
|
||||||
term: entity3.entity.name,
|
term: entity3.entity.displayName,
|
||||||
assignee: viewAllUser.responseData.name,
|
assignee: viewAllUser.responseData.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,6 +99,10 @@ test.describe('Advanced Search', { tag: '@advanced-search' }, () => {
|
|||||||
'database.displayName': [table1.database.name, table2.database.name],
|
'database.displayName': [table1.database.name, table2.database.name],
|
||||||
'databaseSchema.displayName': [table1.schema.name, table2.schema.name],
|
'databaseSchema.displayName': [table1.schema.name, table2.schema.name],
|
||||||
'columns.name.keyword': ['email', 'shop_id'],
|
'columns.name.keyword': ['email', 'shop_id'],
|
||||||
|
'displayName.keyword': [
|
||||||
|
table1.entity.displayName,
|
||||||
|
table2.entity.displayName,
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
await afterAction();
|
await afterAction();
|
||||||
|
@ -37,8 +37,8 @@ const queryData = {
|
|||||||
tagFqn: 'PersonalData.Personal',
|
tagFqn: 'PersonalData.Personal',
|
||||||
tagName: 'Personal',
|
tagName: 'Personal',
|
||||||
queryUsedIn: {
|
queryUsedIn: {
|
||||||
table1: table2.entity.name,
|
table1: table2.entity.displayName,
|
||||||
table2: table3.entity.name,
|
table2: table3.entity.displayName,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import { StoredProcedureClass } from '../../support/entity/StoredProcedureClass'
|
|||||||
import { TableClass } from '../../support/entity/TableClass';
|
import { TableClass } from '../../support/entity/TableClass';
|
||||||
import { TopicClass } from '../../support/entity/TopicClass';
|
import { TopicClass } from '../../support/entity/TopicClass';
|
||||||
import { createNewPage, redirectToHomePage } from '../../utils/common';
|
import { createNewPage, redirectToHomePage } from '../../utils/common';
|
||||||
|
import { getEntityDisplayName } from '../../utils/entity';
|
||||||
|
|
||||||
const entities = [
|
const entities = [
|
||||||
new ApiEndpointClass(),
|
new ApiEndpointClass(),
|
||||||
@ -77,7 +78,9 @@ test.describe('Recently viewed data assets', () => {
|
|||||||
|
|
||||||
await page.waitForSelector(`[data-testid="recently-viewed-widget"]`);
|
await page.waitForSelector(`[data-testid="recently-viewed-widget"]`);
|
||||||
|
|
||||||
const selector = `[data-testid="recently-viewed-widget"] [title="${entity.entity.name}"]`;
|
const selector = `[data-testid="recently-viewed-widget"] [title="${getEntityDisplayName(
|
||||||
|
entity.entity
|
||||||
|
)}"]`;
|
||||||
|
|
||||||
await expect(page.locator(selector)).toBeVisible();
|
await expect(page.locator(selector)).toBeVisible();
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ export class TableClass extends EntityClass {
|
|||||||
|
|
||||||
entity = {
|
entity = {
|
||||||
name: `pw-table-${uuid()}`,
|
name: `pw-table-${uuid()}`,
|
||||||
|
displayName: `pw table ${uuid()}`,
|
||||||
description: 'description',
|
description: 'description',
|
||||||
columns: this.children,
|
columns: this.children,
|
||||||
databaseSchema: `${this.service.name}.${this.database.name}.${this.schema.name}`,
|
databaseSchema: `${this.service.name}.${this.database.name}.${this.schema.name}`,
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"incremental": true,
|
||||||
|
"target": "ES5",
|
||||||
|
"module": "esnext",
|
||||||
|
"lib": ["dom", "dom.iterable", "ES2020.Promise", "es2021"],
|
||||||
|
"allowJs": true,
|
||||||
|
"jsx": "react",
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"composite": false,
|
||||||
|
"removeComments": false,
|
||||||
|
"noEmit": true,
|
||||||
|
"importHelpers": true,
|
||||||
|
"downlevelIteration": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"allowUnreachableCode": false,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"noImplicitAny": true
|
||||||
|
}
|
||||||
|
}
|
@ -12,11 +12,13 @@
|
|||||||
*/
|
*/
|
||||||
import { expect, Locator, Page } from '@playwright/test';
|
import { expect, Locator, Page } from '@playwright/test';
|
||||||
import { clickOutside } from './common';
|
import { clickOutside } from './common';
|
||||||
|
import { getEncodedFqn } from './entity';
|
||||||
|
|
||||||
type EntityFields = {
|
type EntityFields = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
localSearch: boolean;
|
localSearch: boolean;
|
||||||
|
skipConditions?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FIELDS: EntityFields[] = [
|
export const FIELDS: EntityFields[] = [
|
||||||
@ -55,6 +57,12 @@ export const FIELDS: EntityFields[] = [
|
|||||||
name: 'columns.name.keyword',
|
name: 'columns.name.keyword',
|
||||||
localSearch: false,
|
localSearch: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'Display Name',
|
||||||
|
name: 'displayName.keyword',
|
||||||
|
localSearch: false,
|
||||||
|
skipConditions: ['isNull', 'isNotNull'], // Null and isNotNull conditions are not present for display name
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const OPERATOR = {
|
export const OPERATOR = {
|
||||||
@ -121,6 +129,9 @@ const selectOption = async (
|
|||||||
optionTitle: string
|
optionTitle: string
|
||||||
) => {
|
) => {
|
||||||
await dropdownLocator.click();
|
await dropdownLocator.click();
|
||||||
|
await page.waitForSelector(`.ant-select-dropdown:visible`, {
|
||||||
|
state: 'visible',
|
||||||
|
});
|
||||||
await page.click(`.ant-select-dropdown:visible [title="${optionTitle}"]`);
|
await page.click(`.ant-select-dropdown:visible [title="${optionTitle}"]`);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -134,7 +145,7 @@ export const fillRule = async (
|
|||||||
}: {
|
}: {
|
||||||
condition: string;
|
condition: string;
|
||||||
field: EntityFields;
|
field: EntityFields;
|
||||||
searchCriteria: string;
|
searchCriteria?: string;
|
||||||
index: number;
|
index: number;
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
@ -192,7 +203,17 @@ export const fillRule = async (
|
|||||||
|
|
||||||
export const checkMustPaths = async (
|
export const checkMustPaths = async (
|
||||||
page: Page,
|
page: Page,
|
||||||
{ condition, field, searchCriteria, index }
|
{
|
||||||
|
condition,
|
||||||
|
field,
|
||||||
|
searchCriteria,
|
||||||
|
index,
|
||||||
|
}: {
|
||||||
|
condition: string;
|
||||||
|
field: EntityFields;
|
||||||
|
searchCriteria: string;
|
||||||
|
index: number;
|
||||||
|
}
|
||||||
) => {
|
) => {
|
||||||
const searchData = field.localSearch
|
const searchData = field.localSearch
|
||||||
? searchCriteria
|
? searchCriteria
|
||||||
@ -209,13 +230,14 @@ export const checkMustPaths = async (
|
|||||||
'/api/v1/search/query?*index=dataAsset&from=0&size=10*'
|
'/api/v1/search/query?*index=dataAsset&from=0&size=10*'
|
||||||
);
|
);
|
||||||
await page.getByTestId('apply-btn').click();
|
await page.getByTestId('apply-btn').click();
|
||||||
await searchRes.then(async (res) => {
|
|
||||||
await expect(res.request().url()).toContain(encodeURI(searchData));
|
|
||||||
|
|
||||||
await res.json().then(async (json) => {
|
const res = await searchRes;
|
||||||
await expect(JSON.stringify(json.hits.hits)).toContain(searchCriteria);
|
|
||||||
});
|
expect(res.request().url()).toContain(getEncodedFqn(searchData, true));
|
||||||
});
|
|
||||||
|
const json = await res.json();
|
||||||
|
|
||||||
|
expect(JSON.stringify(json.hits.hits)).toContain(searchCriteria);
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByTestId('advance-search-filter-container')
|
page.getByTestId('advance-search-filter-container')
|
||||||
@ -224,7 +246,17 @@ export const checkMustPaths = async (
|
|||||||
|
|
||||||
export const checkMustNotPaths = async (
|
export const checkMustNotPaths = async (
|
||||||
page: Page,
|
page: Page,
|
||||||
{ condition, field, searchCriteria, index }
|
{
|
||||||
|
condition,
|
||||||
|
field,
|
||||||
|
searchCriteria,
|
||||||
|
index,
|
||||||
|
}: {
|
||||||
|
condition: string;
|
||||||
|
field: EntityFields;
|
||||||
|
searchCriteria: string;
|
||||||
|
index: number;
|
||||||
|
}
|
||||||
) => {
|
) => {
|
||||||
const searchData = field.localSearch
|
const searchData = field.localSearch
|
||||||
? searchCriteria
|
? searchCriteria
|
||||||
@ -241,17 +273,15 @@ export const checkMustNotPaths = async (
|
|||||||
'/api/v1/search/query?*index=dataAsset&from=0&size=10*'
|
'/api/v1/search/query?*index=dataAsset&from=0&size=10*'
|
||||||
);
|
);
|
||||||
await page.getByTestId('apply-btn').click();
|
await page.getByTestId('apply-btn').click();
|
||||||
await searchRes.then(async (res) => {
|
const res = await searchRes;
|
||||||
await expect(res.request().url()).toContain(encodeURI(searchData));
|
|
||||||
|
expect(res.request().url()).toContain(getEncodedFqn(searchData, true));
|
||||||
|
|
||||||
if (!['columns.name.keyword'].includes(field.name)) {
|
if (!['columns.name.keyword'].includes(field.name)) {
|
||||||
await res.json().then(async (json) => {
|
const json = await res.json();
|
||||||
await expect(JSON.stringify(json.hits.hits)).not.toContain(
|
|
||||||
searchCriteria
|
expect(JSON.stringify(json.hits.hits)).not.toContain(searchCriteria);
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByTestId('advance-search-filter-container')
|
page.getByTestId('advance-search-filter-container')
|
||||||
@ -260,7 +290,17 @@ export const checkMustNotPaths = async (
|
|||||||
|
|
||||||
export const checkNullPaths = async (
|
export const checkNullPaths = async (
|
||||||
page: Page,
|
page: Page,
|
||||||
{ condition, field, searchCriteria, index }
|
{
|
||||||
|
condition,
|
||||||
|
field,
|
||||||
|
searchCriteria,
|
||||||
|
index,
|
||||||
|
}: {
|
||||||
|
condition: string;
|
||||||
|
field: EntityFields;
|
||||||
|
searchCriteria?: string;
|
||||||
|
index: number;
|
||||||
|
}
|
||||||
) => {
|
) => {
|
||||||
await fillRule(page, {
|
await fillRule(page, {
|
||||||
condition,
|
condition,
|
||||||
@ -273,7 +313,7 @@ export const checkNullPaths = async (
|
|||||||
'/api/v1/search/query?*index=dataAsset&from=0&size=10*'
|
'/api/v1/search/query?*index=dataAsset&from=0&size=10*'
|
||||||
);
|
);
|
||||||
await page.getByTestId('apply-btn').click();
|
await page.getByTestId('apply-btn').click();
|
||||||
await searchRes.then(async (res) => {
|
const res = await searchRes;
|
||||||
const urlParams = new URLSearchParams(res.request().url());
|
const urlParams = new URLSearchParams(res.request().url());
|
||||||
const queryFilter = JSON.parse(urlParams.get('query_filter') ?? '');
|
const queryFilter = JSON.parse(urlParams.get('query_filter') ?? '');
|
||||||
|
|
||||||
@ -314,10 +354,7 @@ export const checkNullPaths = async (
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await expect(JSON.stringify(queryFilter)).toContain(
|
expect(JSON.stringify(queryFilter)).toContain(JSON.stringify(resultQuery));
|
||||||
JSON.stringify(resultQuery)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const verifyAllConditions = async (
|
export const verifyAllConditions = async (
|
||||||
@ -349,6 +386,11 @@ export const verifyAllConditions = async (
|
|||||||
await page.getByTestId('clear-filters').click();
|
await page.getByTestId('clear-filters').click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't run null path if it's present in skipConditions
|
||||||
|
if (
|
||||||
|
!field.skipConditions?.includes('isNull') ||
|
||||||
|
!field.skipConditions?.includes('isNotNull')
|
||||||
|
) {
|
||||||
// Check for Null and Not Null conditions
|
// Check for Null and Not Null conditions
|
||||||
for (const condition of Object.values(NULL_CONDITIONS)) {
|
for (const condition of Object.values(NULL_CONDITIONS)) {
|
||||||
await showAdvancedSearchDialog(page);
|
await showAdvancedSearchDialog(page);
|
||||||
@ -360,10 +402,11 @@ export const verifyAllConditions = async (
|
|||||||
});
|
});
|
||||||
await page.getByTestId('clear-filters').click();
|
await page.getByTestId('clear-filters').click();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const checkAddRuleOrGroupWithOperator = async (
|
export const checkAddRuleOrGroupWithOperator = async (
|
||||||
page,
|
page: Page,
|
||||||
{
|
{
|
||||||
field,
|
field,
|
||||||
operator,
|
operator,
|
||||||
@ -405,27 +448,25 @@ export const checkAddRuleOrGroupWithOperator = async (
|
|||||||
if (operator === 'OR') {
|
if (operator === 'OR') {
|
||||||
await page
|
await page
|
||||||
.getByTestId('advanced-search-modal')
|
.getByTestId('advanced-search-modal')
|
||||||
.getByRole('button', { name: 'Or' });
|
.getByRole('button', { name: 'Or' })
|
||||||
|
.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchRes = page.waitForResponse(
|
const searchRes = page.waitForResponse(
|
||||||
'/api/v1/search/query?*index=dataAsset&from=0&size=10*'
|
'/api/v1/search/query?*index=dataAsset&from=0&size=10*'
|
||||||
);
|
);
|
||||||
await page.getByTestId('apply-btn').click();
|
await page.getByTestId('apply-btn').click();
|
||||||
await searchRes;
|
|
||||||
await searchRes.then(async (res) => {
|
// Since the OR operator with must not conditions will result in huge API response
|
||||||
await res.json().then(async (json) => {
|
// with huge data, checking the required criteria might not be present on first page
|
||||||
if (field.id !== 'Column') {
|
// Hence, checking the criteria only for AND operator
|
||||||
if (operator === 'Or') {
|
if (field.id !== 'Column' && operator === 'AND') {
|
||||||
await expect(JSON.stringify(json)).toContain(searchCriteria1);
|
const res = await searchRes;
|
||||||
await expect(JSON.stringify(json)).toContain(searchCriteria2);
|
const json = await res.json();
|
||||||
} else {
|
|
||||||
await expect(JSON.stringify(json)).toContain(searchCriteria1);
|
expect(JSON.stringify(json)).toContain(searchCriteria1);
|
||||||
await expect(JSON.stringify(json)).not.toContain(searchCriteria2);
|
expect(JSON.stringify(json)).not.toContain(searchCriteria2);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const runRuleGroupTests = async (
|
export const runRuleGroupTests = async (
|
||||||
|
@ -116,7 +116,7 @@ export const setValueForProperty = async (data: {
|
|||||||
|
|
||||||
case 'enum':
|
case 'enum':
|
||||||
await page.click('#enumValues');
|
await page.click('#enumValues');
|
||||||
await page.fill('#enumValues', value);
|
await page.fill('#enumValues', value, { force: true });
|
||||||
await page.press('#enumValues', 'Enter');
|
await page.press('#enumValues', 'Enter');
|
||||||
await clickOutside(page);
|
await clickOutside(page);
|
||||||
await container.locator('[data-testid="inline-save-btn"]').click();
|
await container.locator('[data-testid="inline-save-btn"]').click();
|
||||||
@ -384,12 +384,15 @@ export const createCustomPropertyForEntity = async (
|
|||||||
'/api/v1/metadata/types?category=field&limit=20'
|
'/api/v1/metadata/types?category=field&limit=20'
|
||||||
);
|
);
|
||||||
const properties = await propertiesResponse.json();
|
const properties = await propertiesResponse.json();
|
||||||
const propertyList = properties.data.filter((item) =>
|
const propertyList = properties.data.filter(
|
||||||
|
(item: { name: CustomPropertyTypeByName }) =>
|
||||||
Object.values(CustomPropertyTypeByName).includes(item.name)
|
Object.values(CustomPropertyTypeByName).includes(item.name)
|
||||||
);
|
);
|
||||||
|
|
||||||
const entitySchemaResponse = await apiContext.get(
|
const entitySchemaResponse = await apiContext.get(
|
||||||
`/api/v1/metadata/types/name/${ENTITY_PATH[endpoint]}`
|
`/api/v1/metadata/types/name/${
|
||||||
|
ENTITY_PATH[endpoint as keyof typeof ENTITY_PATH]
|
||||||
|
}`
|
||||||
);
|
);
|
||||||
const entitySchema = await entitySchemaResponse.json();
|
const entitySchema = await entitySchemaResponse.json();
|
||||||
|
|
||||||
@ -414,7 +417,7 @@ export const createCustomPropertyForEntity = async (
|
|||||||
acc[`user${index + 1}`] = user.getUserName();
|
acc[`user${index + 1}`] = user.getUserName();
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {} as Record<string, string>);
|
||||||
|
|
||||||
// Define an asynchronous function to clean up (delete) all users in the users array
|
// Define an asynchronous function to clean up (delete) all users in the users array
|
||||||
const cleanupUser = async (apiContext: APIRequestContext) => {
|
const cleanupUser = async (apiContext: APIRequestContext) => {
|
||||||
@ -501,7 +504,11 @@ export const createCustomPropertyForEntity = async (
|
|||||||
const customProperty = await customPropertyResponse.json();
|
const customProperty = await customPropertyResponse.json();
|
||||||
|
|
||||||
// Process the custom properties
|
// Process the custom properties
|
||||||
customProperties = customProperty.customProperties.reduce((prev, curr) => {
|
customProperties = customProperty.customProperties.reduce(
|
||||||
|
(
|
||||||
|
prev: Record<string, string>,
|
||||||
|
curr: Record<string, Record<string, string>>
|
||||||
|
) => {
|
||||||
const propertyTypeName = curr.propertyType.name;
|
const propertyTypeName = curr.propertyType.name;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -511,7 +518,9 @@ export const createCustomPropertyForEntity = async (
|
|||||||
property: curr,
|
property: curr,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}, {});
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { customProperties, cleanupUser };
|
return { customProperties, cleanupUser };
|
||||||
|
@ -77,7 +77,7 @@ export const removeDomain = async (page: Page) => {
|
|||||||
await expect(page.getByTestId('no-domain-text')).toContainText('No Domain');
|
await expect(page.getByTestId('no-domain-text')).toContainText('No Domain');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const validateDomainForm = async (page) => {
|
export const validateDomainForm = async (page: Page) => {
|
||||||
// Error messages
|
// Error messages
|
||||||
await expect(page.locator('#name_help')).toHaveText('Name is required');
|
await expect(page.locator('#name_help')).toHaveText('Name is required');
|
||||||
await expect(page.locator('#description_help')).toHaveText(
|
await expect(page.locator('#description_help')).toHaveText(
|
||||||
@ -408,7 +408,7 @@ export const createDataProduct = async (
|
|||||||
page: Page,
|
page: Page,
|
||||||
dataProduct: DataProduct['data']
|
dataProduct: DataProduct['data']
|
||||||
) => {
|
) => {
|
||||||
await page.getByTestId('domain-details-add-button').click();
|
await page.getByTestId('domain-details-add-button').click({ force: true });
|
||||||
await page.getByRole('menuitem', { name: 'Data Products' }).click();
|
await page.getByRole('menuitem', { name: 'Data Products' }).click();
|
||||||
|
|
||||||
await expect(page.getByText('Add Data Product')).toBeVisible();
|
await expect(page.getByText('Add Data Product')).toBeVisible();
|
||||||
|
@ -957,7 +957,15 @@ export const updateDisplayNameForEntity = async (
|
|||||||
).toHaveText(displayName);
|
).toHaveText(displayName);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const checkForEditActions = async ({ entityType, deleted, page }) => {
|
export const checkForEditActions = async ({
|
||||||
|
page,
|
||||||
|
entityType,
|
||||||
|
deleted = false,
|
||||||
|
}: {
|
||||||
|
page: Page;
|
||||||
|
entityType: string;
|
||||||
|
deleted?: boolean;
|
||||||
|
}) => {
|
||||||
for (const {
|
for (const {
|
||||||
containerSelector,
|
containerSelector,
|
||||||
elementSelector,
|
elementSelector,
|
||||||
@ -1320,3 +1328,20 @@ export const escapeESReservedCharacters = (text?: string) => {
|
|||||||
? text.replace(reUnescapedHtml, getReplacedChar)
|
? text.replace(reUnescapedHtml, getReplacedChar)
|
||||||
: text ?? '';
|
: text ?? '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getEncodedFqn = (fqn: string, spaceAsPlus = false) => {
|
||||||
|
let uri = encodeURIComponent(fqn);
|
||||||
|
|
||||||
|
if (spaceAsPlus) {
|
||||||
|
uri = uri.replaceAll('%20', '+');
|
||||||
|
}
|
||||||
|
|
||||||
|
return uri;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getEntityDisplayName = (entity?: {
|
||||||
|
name?: string;
|
||||||
|
displayName?: string;
|
||||||
|
}) => {
|
||||||
|
return entity?.displayName || entity?.name || '';
|
||||||
|
};
|
||||||
|
@ -928,6 +928,7 @@
|
|||||||
"regenerate-registration-token": "Neuen Registrierungstoken generieren",
|
"regenerate-registration-token": "Neuen Registrierungstoken generieren",
|
||||||
"region-name": "Region Name",
|
"region-name": "Region Name",
|
||||||
"registry": "Register",
|
"registry": "Register",
|
||||||
|
"regular-expression": "Regular Expression",
|
||||||
"reject": "Ablehnen",
|
"reject": "Ablehnen",
|
||||||
"reject-all": "Reject All",
|
"reject-all": "Reject All",
|
||||||
"rejected": "Rejected",
|
"rejected": "Rejected",
|
||||||
|
@ -928,6 +928,7 @@
|
|||||||
"regenerate-registration-token": "Regenerate registration token",
|
"regenerate-registration-token": "Regenerate registration token",
|
||||||
"region-name": "Region Name",
|
"region-name": "Region Name",
|
||||||
"registry": "Registry",
|
"registry": "Registry",
|
||||||
|
"regular-expression": "Regular Expression",
|
||||||
"reject": "Reject",
|
"reject": "Reject",
|
||||||
"reject-all": "Reject All",
|
"reject-all": "Reject All",
|
||||||
"rejected": "Rejected",
|
"rejected": "Rejected",
|
||||||
|
@ -928,6 +928,7 @@
|
|||||||
"regenerate-registration-token": "Regenerar token de registro",
|
"regenerate-registration-token": "Regenerar token de registro",
|
||||||
"region-name": "Nombre de la región",
|
"region-name": "Nombre de la región",
|
||||||
"registry": "Registro",
|
"registry": "Registro",
|
||||||
|
"regular-expression": "Regular Expression",
|
||||||
"reject": "Rechazar",
|
"reject": "Rechazar",
|
||||||
"reject-all": "Reject All",
|
"reject-all": "Reject All",
|
||||||
"rejected": "Rechazado",
|
"rejected": "Rechazado",
|
||||||
|
@ -928,6 +928,7 @@
|
|||||||
"regenerate-registration-token": "Regénérer le Jeton d'Inscription",
|
"regenerate-registration-token": "Regénérer le Jeton d'Inscription",
|
||||||
"region-name": "Nom de Région",
|
"region-name": "Nom de Région",
|
||||||
"registry": "Registre",
|
"registry": "Registre",
|
||||||
|
"regular-expression": "Regular Expression",
|
||||||
"reject": "Rejeter",
|
"reject": "Rejeter",
|
||||||
"reject-all": "Rejeter Tout",
|
"reject-all": "Rejeter Tout",
|
||||||
"rejected": "Rejeté",
|
"rejected": "Rejeté",
|
||||||
|
@ -928,6 +928,7 @@
|
|||||||
"regenerate-registration-token": "הפק מחדש את אסימון הרישום",
|
"regenerate-registration-token": "הפק מחדש את אסימון הרישום",
|
||||||
"region-name": "שם האזור",
|
"region-name": "שם האזור",
|
||||||
"registry": "רשומון",
|
"registry": "רשומון",
|
||||||
|
"regular-expression": "Regular Expression",
|
||||||
"reject": "דחה",
|
"reject": "דחה",
|
||||||
"reject-all": "Reject All",
|
"reject-all": "Reject All",
|
||||||
"rejected": "נדחה",
|
"rejected": "נדחה",
|
||||||
|
@ -928,6 +928,7 @@
|
|||||||
"regenerate-registration-token": "登録するトークンを作り直す",
|
"regenerate-registration-token": "登録するトークンを作り直す",
|
||||||
"region-name": "リージョン名",
|
"region-name": "リージョン名",
|
||||||
"registry": "レジストリ",
|
"registry": "レジストリ",
|
||||||
|
"regular-expression": "Regular Expression",
|
||||||
"reject": "Reject",
|
"reject": "Reject",
|
||||||
"reject-all": "Reject All",
|
"reject-all": "Reject All",
|
||||||
"rejected": "Rejected",
|
"rejected": "Rejected",
|
||||||
|
@ -928,6 +928,7 @@
|
|||||||
"regenerate-registration-token": "Opnieuw genereren registratietoken",
|
"regenerate-registration-token": "Opnieuw genereren registratietoken",
|
||||||
"region-name": "Regionaam",
|
"region-name": "Regionaam",
|
||||||
"registry": "Register",
|
"registry": "Register",
|
||||||
|
"regular-expression": "Regular Expression",
|
||||||
"reject": "Weigeren",
|
"reject": "Weigeren",
|
||||||
"reject-all": "Reject All",
|
"reject-all": "Reject All",
|
||||||
"rejected": "Geweigerd",
|
"rejected": "Geweigerd",
|
||||||
|
@ -928,6 +928,7 @@
|
|||||||
"regenerate-registration-token": "Regenerar token de registro",
|
"regenerate-registration-token": "Regenerar token de registro",
|
||||||
"region-name": "Nome da Região",
|
"region-name": "Nome da Região",
|
||||||
"registry": "Registro",
|
"registry": "Registro",
|
||||||
|
"regular-expression": "Regular Expression",
|
||||||
"reject": "Rejeitar",
|
"reject": "Rejeitar",
|
||||||
"reject-all": "Reject All",
|
"reject-all": "Reject All",
|
||||||
"rejected": "Rejeitado",
|
"rejected": "Rejeitado",
|
||||||
|
@ -928,6 +928,7 @@
|
|||||||
"regenerate-registration-token": "Восстановить регистрационный токен",
|
"regenerate-registration-token": "Восстановить регистрационный токен",
|
||||||
"region-name": "Наименование региона",
|
"region-name": "Наименование региона",
|
||||||
"registry": "Реестр",
|
"registry": "Реестр",
|
||||||
|
"regular-expression": "Regular Expression",
|
||||||
"reject": "Reject",
|
"reject": "Reject",
|
||||||
"reject-all": "Reject All",
|
"reject-all": "Reject All",
|
||||||
"rejected": "Rejected",
|
"rejected": "Rejected",
|
||||||
|
@ -928,6 +928,7 @@
|
|||||||
"regenerate-registration-token": "重新产生注册令牌",
|
"regenerate-registration-token": "重新产生注册令牌",
|
||||||
"region-name": "区域名称",
|
"region-name": "区域名称",
|
||||||
"registry": "仓库",
|
"registry": "仓库",
|
||||||
|
"regular-expression": "Regular Expression",
|
||||||
"reject": "拒绝",
|
"reject": "拒绝",
|
||||||
"reject-all": "拒绝全部",
|
"reject-all": "拒绝全部",
|
||||||
"rejected": "已拒绝",
|
"rejected": "已拒绝",
|
||||||
|
@ -30,6 +30,74 @@ import { getCombinedQueryFilterObject } from './ExplorePage/ExplorePageUtils';
|
|||||||
|
|
||||||
class AdvancedSearchClassBase {
|
class AdvancedSearchClassBase {
|
||||||
baseConfig = AntdConfig as BasicConfig;
|
baseConfig = AntdConfig as BasicConfig;
|
||||||
|
configTypes: BasicConfig['types'] = {
|
||||||
|
...this.baseConfig.types,
|
||||||
|
multiselect: {
|
||||||
|
...this.baseConfig.types.multiselect,
|
||||||
|
widgets: {
|
||||||
|
...this.baseConfig.types.multiselect.widgets,
|
||||||
|
// Adds the "Contains" and "Not contains" options for fields with type multiselect
|
||||||
|
text: {
|
||||||
|
operators: ['like', 'not_like', 'regexp'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Limits source to user input values, not other fields
|
||||||
|
valueSources: ['value'],
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
...this.baseConfig.types.select,
|
||||||
|
widgets: {
|
||||||
|
...this.baseConfig.types.select.widgets,
|
||||||
|
text: {
|
||||||
|
operators: ['like', 'not_like', 'regexp'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valueSources: ['value'],
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
...this.baseConfig.types.text,
|
||||||
|
valueSources: ['value'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
configWidgets: BasicConfig['widgets'] = {
|
||||||
|
...this.baseConfig.widgets,
|
||||||
|
multiselect: {
|
||||||
|
...this.baseConfig.widgets.multiselect,
|
||||||
|
showSearch: true,
|
||||||
|
showCheckboxes: true,
|
||||||
|
useAsyncSearch: true,
|
||||||
|
useLoadMore: false,
|
||||||
|
customProps: {
|
||||||
|
popupClassName: 'w-max-600',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
...this.baseConfig.widgets.select,
|
||||||
|
showSearch: true,
|
||||||
|
showCheckboxes: true,
|
||||||
|
useAsyncSearch: true,
|
||||||
|
useLoadMore: false,
|
||||||
|
customProps: {
|
||||||
|
popupClassName: 'w-max-600',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
...this.baseConfig.widgets.text,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
configOperators = {
|
||||||
|
...this.baseConfig.operators,
|
||||||
|
like: {
|
||||||
|
...this.baseConfig.operators.like,
|
||||||
|
elasticSearchQueryType: 'wildcard',
|
||||||
|
},
|
||||||
|
regexp: {
|
||||||
|
label: t('label.regular-expression'),
|
||||||
|
labelForFormat: t('label.regular-expression'),
|
||||||
|
elasticSearchQueryType: 'regexp',
|
||||||
|
valueSources: ['value'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
mainWidgetProps = {
|
mainWidgetProps = {
|
||||||
fullWidth: true,
|
fullWidth: true,
|
||||||
@ -97,7 +165,7 @@ class AdvancedSearchClassBase {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
tableType: {
|
[EntityFields.TABLE_TYPE]: {
|
||||||
label: t('label.table-type'),
|
label: t('label.table-type'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -115,7 +183,7 @@ class AdvancedSearchClassBase {
|
|||||||
* Fields specific to pipelines
|
* Fields specific to pipelines
|
||||||
*/
|
*/
|
||||||
pipelineQueryBuilderFields: Fields = {
|
pipelineQueryBuilderFields: Fields = {
|
||||||
'tasks.displayName.keyword': {
|
[EntityFields.TASK]: {
|
||||||
label: t('label.task'),
|
label: t('label.task'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -133,7 +201,7 @@ class AdvancedSearchClassBase {
|
|||||||
* Fields specific to topics
|
* Fields specific to topics
|
||||||
*/
|
*/
|
||||||
topicQueryBuilderFields: Fields = {
|
topicQueryBuilderFields: Fields = {
|
||||||
'messageSchema.schemaFields.name.keyword': {
|
[EntityFields.SCHEMA_FIELD]: {
|
||||||
label: t('label.schema-field'),
|
label: t('label.schema-field'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -151,7 +219,7 @@ class AdvancedSearchClassBase {
|
|||||||
* Fields specific to API endpoints
|
* Fields specific to API endpoints
|
||||||
*/
|
*/
|
||||||
apiEndpointQueryBuilderFields: Fields = {
|
apiEndpointQueryBuilderFields: Fields = {
|
||||||
'requestSchema.schemaFields.name.keyword': {
|
[EntityFields.REQUEST_SCHEMA_FIELD]: {
|
||||||
label: t('label.request-schema-field'),
|
label: t('label.request-schema-field'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -163,7 +231,7 @@ class AdvancedSearchClassBase {
|
|||||||
useAsyncSearch: true,
|
useAsyncSearch: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'responseSchema.schemaFields.name.keyword': {
|
[EntityFields.RESPONSE_SCHEMA_FIELD]: {
|
||||||
label: t('label.response-schema-field'),
|
label: t('label.response-schema-field'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -181,7 +249,7 @@ class AdvancedSearchClassBase {
|
|||||||
* Fields specific to Glossary
|
* Fields specific to Glossary
|
||||||
*/
|
*/
|
||||||
glossaryQueryBuilderFields: Fields = {
|
glossaryQueryBuilderFields: Fields = {
|
||||||
status: {
|
[EntityFields.GLOSSARY_TERM_STATUS]: {
|
||||||
label: t('label.status'),
|
label: t('label.status'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -199,7 +267,7 @@ class AdvancedSearchClassBase {
|
|||||||
* Fields specific to dashboard
|
* Fields specific to dashboard
|
||||||
*/
|
*/
|
||||||
dashboardQueryBuilderFields: Fields = {
|
dashboardQueryBuilderFields: Fields = {
|
||||||
'dataModels.displayName.keyword': {
|
[EntityFields.DATA_MODEL]: {
|
||||||
label: t('label.data-model'),
|
label: t('label.data-model'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -211,7 +279,7 @@ class AdvancedSearchClassBase {
|
|||||||
useAsyncSearch: true,
|
useAsyncSearch: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'charts.displayName.keyword': {
|
[EntityFields.CHART]: {
|
||||||
label: t('label.chart'),
|
label: t('label.chart'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -223,7 +291,7 @@ class AdvancedSearchClassBase {
|
|||||||
useAsyncSearch: true,
|
useAsyncSearch: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'project.keyword': {
|
[EntityFields.PROJECT]: {
|
||||||
label: t('label.project'),
|
label: t('label.project'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -241,7 +309,7 @@ class AdvancedSearchClassBase {
|
|||||||
* Fields specific to ML models
|
* Fields specific to ML models
|
||||||
*/
|
*/
|
||||||
mlModelQueryBuilderFields: Fields = {
|
mlModelQueryBuilderFields: Fields = {
|
||||||
'mlFeatures.name': {
|
[EntityFields.FEATURE]: {
|
||||||
label: t('label.feature'),
|
label: t('label.feature'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -259,7 +327,7 @@ class AdvancedSearchClassBase {
|
|||||||
* Fields specific to containers
|
* Fields specific to containers
|
||||||
*/
|
*/
|
||||||
containerQueryBuilderFields: Fields = {
|
containerQueryBuilderFields: Fields = {
|
||||||
'dataModel.columns.name.keyword': {
|
[EntityFields.CONTAINER_COLUMN]: {
|
||||||
label: t('label.container-column'),
|
label: t('label.container-column'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -277,7 +345,7 @@ class AdvancedSearchClassBase {
|
|||||||
* Fields specific to search indexes
|
* Fields specific to search indexes
|
||||||
*/
|
*/
|
||||||
searchIndexQueryBuilderFields: Fields = {
|
searchIndexQueryBuilderFields: Fields = {
|
||||||
'fields.name.keyword': {
|
[EntityFields.FIELD]: {
|
||||||
label: t('label.field'),
|
label: t('label.field'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -295,7 +363,7 @@ class AdvancedSearchClassBase {
|
|||||||
* Fields specific to dashboard data models
|
* Fields specific to dashboard data models
|
||||||
*/
|
*/
|
||||||
dataModelQueryBuilderFields: Fields = {
|
dataModelQueryBuilderFields: Fields = {
|
||||||
dataModelType: {
|
[EntityFields.DATA_MODEL_TYPE]: {
|
||||||
label: t('label.data-model-type'),
|
label: t('label.data-model-type'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -307,7 +375,7 @@ class AdvancedSearchClassBase {
|
|||||||
useAsyncSearch: true,
|
useAsyncSearch: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'project.keyword': {
|
[EntityFields.PROJECT]: {
|
||||||
label: t('label.project'),
|
label: t('label.project'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -328,62 +396,9 @@ class AdvancedSearchClassBase {
|
|||||||
public getInitialConfigWithoutFields = (isExplorePage = true) => {
|
public getInitialConfigWithoutFields = (isExplorePage = true) => {
|
||||||
const initialConfigWithoutFields: BasicConfig = {
|
const initialConfigWithoutFields: BasicConfig = {
|
||||||
...this.baseConfig,
|
...this.baseConfig,
|
||||||
types: {
|
types: this.configTypes,
|
||||||
...this.baseConfig.types,
|
widgets: this.configWidgets,
|
||||||
multiselect: {
|
operators: this.configOperators,
|
||||||
...this.baseConfig.types.multiselect,
|
|
||||||
widgets: {
|
|
||||||
...this.baseConfig.types.multiselect.widgets,
|
|
||||||
// Adds the "Contains" and "Not contains" options for fields with type multiselect
|
|
||||||
text: {
|
|
||||||
operators: ['like', 'not_like'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Limits source to user input values, not other fields
|
|
||||||
valueSources: ['value'],
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
...this.baseConfig.types.select,
|
|
||||||
widgets: {
|
|
||||||
...this.baseConfig.types.select.widgets,
|
|
||||||
text: {
|
|
||||||
operators: ['like', 'not_like'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
valueSources: ['value'],
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
...this.baseConfig.types.text,
|
|
||||||
valueSources: ['value'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
widgets: {
|
|
||||||
...this.baseConfig.widgets,
|
|
||||||
multiselect: {
|
|
||||||
...this.baseConfig.widgets.multiselect,
|
|
||||||
showSearch: true,
|
|
||||||
showCheckboxes: true,
|
|
||||||
useAsyncSearch: true,
|
|
||||||
useLoadMore: false,
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
...this.baseConfig.widgets.select,
|
|
||||||
showSearch: true,
|
|
||||||
showCheckboxes: true,
|
|
||||||
useAsyncSearch: true,
|
|
||||||
useLoadMore: false,
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
...this.baseConfig.widgets.text,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
operators: {
|
|
||||||
...this.baseConfig.operators,
|
|
||||||
like: {
|
|
||||||
...this.baseConfig.operators.like,
|
|
||||||
elasticSearchQueryType: 'wildcard',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
settings: {
|
settings: {
|
||||||
...this.baseConfig.settings,
|
...this.baseConfig.settings,
|
||||||
showLabels: isExplorePage,
|
showLabels: isExplorePage,
|
||||||
@ -427,13 +442,35 @@ class AdvancedSearchClassBase {
|
|||||||
} = args;
|
} = args;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
[EntityFields.DISPLAY_NAME_KEYWORD]: {
|
||||||
|
label: t('label.display-name'),
|
||||||
|
type: 'select',
|
||||||
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
|
fieldSettings: {
|
||||||
|
asyncFetch: this.autocomplete({
|
||||||
|
searchIndex: entitySearchIndex ?? [SearchIndex.DATA_ASSET],
|
||||||
|
entityField: EntityFields.DISPLAY_NAME_KEYWORD,
|
||||||
|
}),
|
||||||
|
useAsyncSearch: true,
|
||||||
|
},
|
||||||
|
operators: [
|
||||||
|
'select_equals',
|
||||||
|
'select_not_equals',
|
||||||
|
'select_any_in',
|
||||||
|
'select_not_any_in',
|
||||||
|
'like',
|
||||||
|
'not_like',
|
||||||
|
'regexp',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
deleted: {
|
deleted: {
|
||||||
label: t('label.deleted'),
|
label: t('label.deleted'),
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
defaultValue: true,
|
defaultValue: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
'owners.displayName.keyword': {
|
[EntityFields.OWNERS]: {
|
||||||
label: t('label.owner'),
|
label: t('label.owner'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -447,7 +484,7 @@ class AdvancedSearchClassBase {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
'domain.displayName.keyword': {
|
[EntityFields.DOMAIN]: {
|
||||||
label: t('label.domain'),
|
label: t('label.domain'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -461,7 +498,7 @@ class AdvancedSearchClassBase {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
serviceType: {
|
[EntityFields.SERVICE_TYPE]: {
|
||||||
label: t('label.service-type'),
|
label: t('label.service-type'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -475,7 +512,7 @@ class AdvancedSearchClassBase {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
'tags.tagFQN': {
|
[EntityFields.TAG]: {
|
||||||
label: t('label.tag-plural'),
|
label: t('label.tag-plural'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -490,7 +527,7 @@ class AdvancedSearchClassBase {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
'tier.tagFQN': {
|
[EntityFields.TIER]: {
|
||||||
label: t('label.tier'),
|
label: t('label.tier'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -540,7 +577,7 @@ class AdvancedSearchClassBase {
|
|||||||
|
|
||||||
return !isEmpty(searchIndexWithColumns)
|
return !isEmpty(searchIndexWithColumns)
|
||||||
? {
|
? {
|
||||||
'columns.name.keyword': {
|
[EntityFields.COLUMN]: {
|
||||||
label: t('label.column'),
|
label: t('label.column'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
@ -618,7 +655,7 @@ class AdvancedSearchClassBase {
|
|||||||
shouldAddServiceField?: boolean;
|
shouldAddServiceField?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const serviceQueryBuilderFields: Fields = {
|
const serviceQueryBuilderFields: Fields = {
|
||||||
'service.displayName.keyword': {
|
[EntityFields.SERVICE]: {
|
||||||
label: t('label.service'),
|
label: t('label.service'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
mainWidgetProps: this.mainWidgetProps,
|
mainWidgetProps: this.mainWidgetProps,
|
||||||
|
@ -181,6 +181,7 @@ function determineQueryField(fieldDataType, fullFieldName, queryType) {
|
|||||||
function buildRegexpParameters(value) {
|
function buildRegexpParameters(value) {
|
||||||
return {
|
return {
|
||||||
value: value,
|
value: value,
|
||||||
|
case_insensitive: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user