mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-27 18:36:08 +00:00
fix(ui) : owner dropdown for teams with search text is not working (#9921)
* fix(ui) : owner dropdown for teams with search text is not working * chore : convert searchFormattedUsersAndTeams to async/await * chore: use searchFormattedUsersAndTeams for owner search on add alerts page * fix : search api call with query is not working * fix : filter issue for team assets * fix : cy test for alerts * fix : cy tests * fix: cy test * chore: update the search query logic * fix: cy tests * Fix search teams with special chars * fix localization missing for constant --------- Co-authored-by: Sriharsha Chintalapani <harsha@getcollate.io> Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
parent
4bef627fd7
commit
aa294a6a36
@ -85,7 +85,9 @@ public class SearchResource {
|
||||
private static final Integer MAX_AGGREGATE_SIZE = 50;
|
||||
private static final Integer MAX_RESULT_HITS = 10000;
|
||||
private static final String NAME = "name";
|
||||
private static final String NAME_KEYWORD = "name.keyword";
|
||||
private static final String DISPLAY_NAME = "displayName";
|
||||
private static final String DISPLAY_NAME_KEYWORD = "displayName.keyword";
|
||||
private static final String DESCRIPTION = "description";
|
||||
private static final String UNIFIED = "unified";
|
||||
|
||||
@ -570,13 +572,23 @@ public class SearchResource {
|
||||
|
||||
private SearchSourceBuilder buildUserSearchBuilder(String query, int from, int size) {
|
||||
QueryStringQueryBuilder queryBuilder =
|
||||
QueryBuilders.queryStringQuery(query).field(DISPLAY_NAME, 5.0f).field(NAME, 3.0f).lenient(true);
|
||||
QueryBuilders.queryStringQuery(query)
|
||||
.field(DISPLAY_NAME, 5.0f)
|
||||
.field(DISPLAY_NAME_KEYWORD, 3.0f)
|
||||
.field(NAME, 2.0f)
|
||||
.field(NAME_KEYWORD, 3.0f)
|
||||
.fuzziness(Fuzziness.AUTO);
|
||||
return searchBuilder(queryBuilder, null, from, size);
|
||||
}
|
||||
|
||||
private SearchSourceBuilder buildTeamSearchBuilder(String query, int from, int size) {
|
||||
QueryStringQueryBuilder queryBuilder =
|
||||
QueryBuilders.queryStringQuery(query).field(DISPLAY_NAME, 5.0f).field(NAME, 3.0f).lenient(true);
|
||||
QueryBuilders.queryStringQuery(query)
|
||||
.field(DISPLAY_NAME, 5.0f)
|
||||
.field(DISPLAY_NAME_KEYWORD, 3.0f)
|
||||
.field(NAME, 2.0f)
|
||||
.field(NAME_KEYWORD, 3.0f)
|
||||
.fuzziness(Fuzziness.AUTO);
|
||||
return searchBuilder(queryBuilder, null, from, size);
|
||||
}
|
||||
|
||||
|
@ -60,8 +60,8 @@ describe('Alerts page should work properly', () => {
|
||||
cy.get('[data-testid="matchAnyOwnerName-select"]')
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.type('Engineering');
|
||||
cy.get('[title="Engineering"]').should('be.visible').click();
|
||||
.type('Applications');
|
||||
cy.get('[title="Applications"]').should('be.visible').click();
|
||||
cy.get('#description').should('be.visible').click();
|
||||
// Select include/exclude
|
||||
cy.get('[title="Include"]').should('be.visible').click();
|
||||
@ -141,16 +141,16 @@ describe('Alerts page should work properly', () => {
|
||||
cy.get('[data-testid="matchAnyOwnerName-select"]')
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.type('Engineering');
|
||||
cy.get('[title="Engineering"]').should('be.visible').click();
|
||||
.type('Applications');
|
||||
cy.get('[title="Applications"]').should('be.visible').click();
|
||||
cy.get('#name').should('be.visible').click();
|
||||
|
||||
// Select second owner
|
||||
cy.get('[data-testid="matchAnyOwnerName-select"]')
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.type('Applications');
|
||||
cy.get('[title="Applications"]').should('be.visible').click();
|
||||
.type('Marketplace');
|
||||
cy.get('[title="Marketplace"]').should('be.visible').click();
|
||||
cy.get('#name').should('be.visible').click();
|
||||
|
||||
// Select include/exclude
|
||||
@ -305,8 +305,8 @@ describe('Alerts page should work properly', () => {
|
||||
cy.get('[data-testid="matchAnyOwnerName-select"]')
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.type('Engineering');
|
||||
cy.get('[title="Engineering"]').should('be.visible').click();
|
||||
.type('Applications');
|
||||
cy.get('[title="Applications"]').should('be.visible').click();
|
||||
cy.get('#description').should('be.visible').click();
|
||||
// Select include/exclude
|
||||
cy.get('[title="Include"]').should('be.visible').click();
|
||||
|
@ -135,13 +135,13 @@ describe('MyData page should work', () => {
|
||||
it('My data and following section, CTA should work properly', () => {
|
||||
cy.get('[data-testid="my-data-container"]')
|
||||
.find('[data-testid*="My data"]')
|
||||
.should('have.length', FOLLOWING_MYDATA_COUNT);
|
||||
.should('have.length', FOLLOWING_MYDATA_COUNT + 1);
|
||||
cy.get('[data-testid="following-data-container"]')
|
||||
.find('[data-testid*="Following data"]')
|
||||
.should('have.length', FOLLOWING_MYDATA_COUNT);
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/search/query?q=owner.id:*&from=0&size=10&index=*',
|
||||
'/api/v1/search/query?q=*owner.id:*&from=0&size=10&index=*',
|
||||
'userDetailsmyDataTab'
|
||||
);
|
||||
cy.get('[data-testid="my-data-total-count"]').should('be.visible').click();
|
||||
@ -150,7 +150,7 @@ describe('MyData page should work', () => {
|
||||
cy.clickOnLogo();
|
||||
interceptURL(
|
||||
'GET',
|
||||
'api/v1/search/query?q=followers:*&from=0&size=10&index=*',
|
||||
'api/v1/search/query?q=*followers:*&from=0&size=10&index=*',
|
||||
'userDetailsFollowTab'
|
||||
);
|
||||
cy.get('[data-testid="following-data-total-count"]')
|
||||
|
@ -11,8 +11,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import i18next from 'i18next';
|
||||
import { ServiceTypes } from 'Models';
|
||||
import i18n from 'utils/i18next/LocalUtil';
|
||||
import addPlaceHolder from '../assets/img/add-placeholder.svg';
|
||||
import airbyte from '../assets/img/Airbyte.png';
|
||||
import noDataFound from '../assets/img/no-data-placeholder.svg';
|
||||
@ -200,23 +200,23 @@ export const SERVICE_CATEGORY_TYPE = {
|
||||
};
|
||||
|
||||
export const servicesDisplayName: { [key: string]: string } = {
|
||||
databaseServices: i18next.t('label.entity-service', {
|
||||
entity: i18next.t('label.database'),
|
||||
databaseServices: i18n.t('label.entity-service', {
|
||||
entity: i18n.t('label.database'),
|
||||
}),
|
||||
messagingServices: i18next.t('label.entity-service', {
|
||||
entity: i18next.t('label.messaging'),
|
||||
messagingServices: i18n.t('label.entity-service', {
|
||||
entity: i18n.t('label.messaging'),
|
||||
}),
|
||||
dashboardServices: i18next.t('label.entity-service', {
|
||||
entity: i18next.t('label.dashboard'),
|
||||
dashboardServices: i18n.t('label.entity-service', {
|
||||
entity: i18n.t('label.dashboard'),
|
||||
}),
|
||||
pipelineServices: i18next.t('label.entity-service', {
|
||||
entity: i18next.t('label.pipeline'),
|
||||
pipelineServices: i18n.t('label.entity-service', {
|
||||
entity: i18n.t('label.pipeline'),
|
||||
}),
|
||||
mlmodelServices: i18next.t('label.entity-service', {
|
||||
entity: i18next.t('label.ml-model'),
|
||||
mlmodelServices: i18n.t('label.entity-service', {
|
||||
entity: i18n.t('label.ml-model'),
|
||||
}),
|
||||
metadataServices: i18next.t('label.entity-service', {
|
||||
entity: i18next.t('label.metadata'),
|
||||
metadataServices: i18n.t('label.entity-service', {
|
||||
entity: i18n.t('label.metadata'),
|
||||
}),
|
||||
};
|
||||
|
||||
|
@ -43,7 +43,9 @@ import {
|
||||
getFilterFunctions,
|
||||
updateAlert,
|
||||
} from 'rest/alertsAPI';
|
||||
import { getSearchedUsersAndTeams, getSuggestions } from 'rest/miscAPI';
|
||||
import { getSuggestions } from 'rest/miscAPI';
|
||||
import { getEntityName } from 'utils/CommonUtils';
|
||||
import { searchFormattedUsersAndTeams } from 'utils/UserDataUtils';
|
||||
import {
|
||||
GlobalSettingOptions,
|
||||
GlobalSettingsMenuCategory,
|
||||
@ -279,11 +281,11 @@ const AddAlertPage = () => {
|
||||
|
||||
const getUsersAndTeamsOptions = useCallback(async (search: string) => {
|
||||
try {
|
||||
const response = await getSearchedUsersAndTeams(search, 1);
|
||||
const { teams, users } = await searchFormattedUsersAndTeams(search, 1);
|
||||
|
||||
return response.hits.hits.map((d) => ({
|
||||
label: d._source.displayName ?? d._source.name,
|
||||
value: d._source.fullyQualifiedName,
|
||||
return [...teams, ...users].map((d) => ({
|
||||
label: getEntityName(d),
|
||||
value: d.name,
|
||||
}));
|
||||
} catch (error) {
|
||||
return [];
|
||||
|
@ -126,12 +126,12 @@ const UserPage = () => {
|
||||
setIsUserEntitiesLoading(true);
|
||||
try {
|
||||
const response = await searchData(
|
||||
'',
|
||||
entity.currPage,
|
||||
PAGE_SIZE,
|
||||
fetchOwnedEntities
|
||||
? `owner.id:${userData.id}`
|
||||
: `followers:${userData.id}`,
|
||||
entity.currPage,
|
||||
PAGE_SIZE,
|
||||
``,
|
||||
'',
|
||||
'',
|
||||
myDataSearchIndex
|
||||
|
@ -500,10 +500,10 @@ const TeamsPage = () => {
|
||||
|
||||
const fetchAssets = () => {
|
||||
searchData(
|
||||
`owner.id:${selectedTeam.id}`,
|
||||
``,
|
||||
assets.currPage,
|
||||
LIST_SIZE,
|
||||
``,
|
||||
`owner.id:${selectedTeam.id}`,
|
||||
'',
|
||||
'',
|
||||
myDataSearchIndex
|
||||
|
@ -202,9 +202,18 @@ export const getSearchedUsers = (
|
||||
export const getSearchedTeams = (
|
||||
queryString: string,
|
||||
from: number,
|
||||
filter?: string,
|
||||
size = 10
|
||||
) => {
|
||||
return searchData(queryString, from, size, '', '', '', SearchIndex.TEAM);
|
||||
return searchData(
|
||||
queryString,
|
||||
from,
|
||||
size,
|
||||
filter ?? '',
|
||||
'',
|
||||
'',
|
||||
SearchIndex.TEAM
|
||||
);
|
||||
};
|
||||
|
||||
export const getSearchedUsersAndTeams = async (
|
||||
|
@ -27,7 +27,10 @@ export const getSearchAPIQueryParams = (
|
||||
trackTotalHits = false
|
||||
): Record<string, string | boolean | number | string[]> => {
|
||||
const start = (from - 1) * size;
|
||||
const query = queryString ? queryString : WILD_CARD_CHAR;
|
||||
const query =
|
||||
queryString && queryString === WILD_CARD_CHAR
|
||||
? queryString
|
||||
: `*${queryString}*`;
|
||||
|
||||
const params: Record<string, string | boolean | number | string[]> = {
|
||||
q: query + (filters ? ` AND ${filters}` : ''),
|
||||
|
@ -146,46 +146,43 @@ export const getUserProfilePic = (
|
||||
return profile;
|
||||
};
|
||||
|
||||
export const searchFormattedUsersAndTeams = (
|
||||
export const searchFormattedUsersAndTeams = async (
|
||||
searchQuery = WILD_CARD_CHAR,
|
||||
from = 1
|
||||
): Promise<SearchedUsersAndTeams> => {
|
||||
return new Promise<SearchedUsersAndTeams>((resolve, reject) => {
|
||||
const teamQuery = `${searchQuery} AND teamType:Group`;
|
||||
) => {
|
||||
try {
|
||||
const promises = [
|
||||
getSearchedUsers(searchQuery, from),
|
||||
getSearchedTeams(teamQuery, from),
|
||||
getSearchedTeams(searchQuery, from, 'teamType:Group'),
|
||||
];
|
||||
Promise.allSettled(promises)
|
||||
.then(([resUsers, resTeams]) => {
|
||||
const users =
|
||||
resUsers.status === SettledStatus.FULFILLED
|
||||
? formatUsersResponse(
|
||||
(resUsers.value.data as SearchResponse<SearchIndex.USER>).hits
|
||||
.hits
|
||||
)
|
||||
: [];
|
||||
const teams =
|
||||
resTeams.status === SettledStatus.FULFILLED
|
||||
? formatTeamsResponse(
|
||||
(resTeams.value.data as SearchResponse<SearchIndex.TEAM>).hits
|
||||
.hits
|
||||
)
|
||||
: [];
|
||||
const usersTotal =
|
||||
resUsers.status === SettledStatus.FULFILLED
|
||||
? resUsers.value.data.hits.total.value
|
||||
: 0;
|
||||
const teamsTotal =
|
||||
resTeams.status === SettledStatus.FULFILLED
|
||||
? resTeams.value.data.hits.total.value
|
||||
: 0;
|
||||
resolve({ users, teams, usersTotal, teamsTotal });
|
||||
})
|
||||
.catch((err: AxiosError) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
|
||||
const [resUsers, resTeams] = await Promise.allSettled(promises);
|
||||
|
||||
const users =
|
||||
resUsers.status === SettledStatus.FULFILLED
|
||||
? formatUsersResponse(
|
||||
(resUsers.value.data as SearchResponse<SearchIndex.USER>).hits.hits
|
||||
)
|
||||
: [];
|
||||
const teams =
|
||||
resTeams.status === SettledStatus.FULFILLED
|
||||
? formatTeamsResponse(
|
||||
(resTeams.value.data as SearchResponse<SearchIndex.TEAM>).hits.hits
|
||||
)
|
||||
: [];
|
||||
const usersTotal =
|
||||
resUsers.status === SettledStatus.FULFILLED
|
||||
? resUsers.value.data.hits.total.value
|
||||
: 0;
|
||||
const teamsTotal =
|
||||
resTeams.status === SettledStatus.FULFILLED
|
||||
? resTeams.value.data.hits.total.value
|
||||
: 0;
|
||||
|
||||
return { users, teams, usersTotal, teamsTotal };
|
||||
} catch (error) {
|
||||
return { users: [], teams: [], usersTotal: 0, teamsTotal: 0 };
|
||||
}
|
||||
};
|
||||
|
||||
export const suggestFormattedUsersAndTeams = (
|
||||
|
Loading…
x
Reference in New Issue
Block a user