From 7c25b5fddd7f874e573d8ba0fa32d69f989f295a Mon Sep 17 00:00:00 2001 From: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com> Date: Sat, 14 Oct 2023 19:40:01 +0530 Subject: [PATCH] fix(ui): ui feedbacks for 1.2 release (#13522) * fix(ui): ui feedbacks for 1.2 release * fix notification panel height issue and data model expand icon issue * Data Quality, test creation, and minimizing the side panel. It shows the name as "Setup Guide.", It should be "Data Profiler Metrics." * changes locales * fix: displayName for the test cases * fix: Remove Domain shows tool tip as "Remove Owner" * chore: remove box shadow from primary buttons * fix: icon alignment in activity feed tab * Long names should be truncated * Increase the profile picture size to align with both the name and the persona * Text in Knowledge panels should be of the same size * Domain should be displayed on the explore card if the domain is available for any entity * If the Domains not configure the search filter is empty. "No data available." -> "No Domains are Assigned to Tables" etc. * fix: unit tests * fix: unit tets --------- Co-authored-by: Ashish Gupta Co-authored-by: Sachin Chaurasiya --- .../data/tests/columnValueMaxToBeBetween.json | 2 +- .../tests/columnValueMeanToBeBetween.json | 2 +- .../ActivityFeedTab.component.tsx | 17 +++++++--- .../AddDataQualityTestV1.tsx | 2 +- .../CreateUser/CreateUser.component.tsx | 13 ++++---- .../ModelTab/ModelTab.component.tsx | 3 +- .../Explore/ExploreQuickFilters.tsx | 2 ++ .../ExploreSearchCard/ExploreSearchCard.tsx | 13 ++++++++ .../LeftSidebar/LeftSidebar.component.tsx | 2 +- .../MyDataWidget/MyDataWidget.component.tsx | 10 +++--- .../NotificationBox.component.tsx | 2 +- .../NotificationBox/notification-box.less | 9 ++++++ .../SchemaTable/SchemaTable.component.tsx | 18 +++++------ .../SchemaTable/SchemaTable.test.tsx | 8 ++--- .../SearchDropdown.interface.ts | 3 ++ .../SearchDropdown/SearchDropdown.test.tsx | 1 + .../SearchDropdown/SearchDropdown.tsx | 14 +++++++-- .../ui/src/components/Services/Services.tsx | 2 +- .../TeamsSelectable.interface.ts | 6 ++-- .../TeamsSelectable/TeamsSelectable.tsx | 31 +++++++++++++------ .../UserProfileIcon.component.tsx | 17 +++++----- .../UserProfileTeams.component.tsx | 7 +++-- .../DomainSelectableList.component.tsx | 3 ++ .../EntitySummaryDetails.tsx | 15 +++++++++ .../SelectableList.component.tsx | 23 +++++++++++--- .../SelectableList.interface.ts | 1 + .../ui/src/components/nav-bar/nav-bar.less | 2 +- .../searched-data/SearchedData.interface.ts | 3 +- .../resources/ui/src/constants/constants.ts | 5 +++ .../ui/src/constants/explore.constants.ts | 12 +++---- .../ui/src/locale/languages/de-de.json | 2 ++ .../ui/src/locale/languages/en-us.json | 2 ++ .../ui/src/locale/languages/es-es.json | 2 ++ .../ui/src/locale/languages/fr-fr.json | 2 ++ .../ui/src/locale/languages/ja-jp.json | 2 ++ .../ui/src/locale/languages/pt-br.json | 2 ++ .../ui/src/locale/languages/ru-ru.json | 2 ++ .../ui/src/locale/languages/zh-cn.json | 2 ++ .../src/main/resources/ui/src/styles/app.less | 7 +++++ .../ui/src/styles/components/button.less | 4 +++ .../ui/src/styles/components/size.less | 3 ++ .../ui/src/utils/DataInsightUtils.tsx | 8 ++--- .../ui/src/utils/GlobalSettingsUtils.tsx | 18 +++++------ 43 files changed, 218 insertions(+), 86 deletions(-) diff --git a/openmetadata-service/src/main/resources/json/data/tests/columnValueMaxToBeBetween.json b/openmetadata-service/src/main/resources/json/data/tests/columnValueMaxToBeBetween.json index d970127f0693..633d143cfb7e 100644 --- a/openmetadata-service/src/main/resources/json/data/tests/columnValueMaxToBeBetween.json +++ b/openmetadata-service/src/main/resources/json/data/tests/columnValueMaxToBeBetween.json @@ -1,7 +1,7 @@ { "name": "columnValueMaxToBeBetween", "fullyQualifiedName": "columnValueMaxToBeBetween", - "displayName": "Column Value Max. to be Between", + "displayName": "Column Value Max. To Be Between", "description": "This schema defines the test ColumnValueMaxToBeBetween. Test the maximum value in a col is within a range.", "entityType": "COLUMN", "testPlatforms": ["OpenMetadata", "DBT"], diff --git a/openmetadata-service/src/main/resources/json/data/tests/columnValueMeanToBeBetween.json b/openmetadata-service/src/main/resources/json/data/tests/columnValueMeanToBeBetween.json index bfc7b1858107..5e5fe10a1d63 100644 --- a/openmetadata-service/src/main/resources/json/data/tests/columnValueMeanToBeBetween.json +++ b/openmetadata-service/src/main/resources/json/data/tests/columnValueMeanToBeBetween.json @@ -1,7 +1,7 @@ { "name": "columnValueMeanToBeBetween", "fullyQualifiedName": "columnValueMeanToBeBetween", - "displayName": "Column Value Mean To BeBetween", + "displayName": "Column Value Mean To Be Between", "description": "This schema defines the test ColumnValueMeanToBeBetween. Test the mean value in a col is within a range.", "entityType": "COLUMN", "testPlatforms": ["OpenMetadata"], diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx index 20235aeb21b1..a0aa295d49c2 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx @@ -29,7 +29,10 @@ import { ReactComponent as CheckIcon } from '../../../assets/svg/ic-check.svg'; import { ReactComponent as MentionIcon } from '../../../assets/svg/ic-mentions.svg'; import { ReactComponent as TaskIcon } from '../../../assets/svg/ic-task.svg'; import { ReactComponent as TaskListIcon } from '../../../assets/svg/task-ic.svg'; -import { ICON_DIMENSION } from '../../../constants/constants'; +import { + COMMON_ICON_STYLES, + ICON_DIMENSION, +} from '../../../constants/constants'; import { observerOptions } from '../../../constants/Mydata.constants'; import { EntityTabs, EntityType } from '../../../enums/entity.enum'; import { FeedFilter } from '../../../enums/mydata.enum'; @@ -298,7 +301,10 @@ export const ActivityFeedTab = ({ label: (
- + {t('label.all')} @@ -316,7 +322,7 @@ export const ActivityFeedTab = ({ { label: ( - + {t('label.mention-plural')} ), @@ -326,7 +332,10 @@ export const ActivityFeedTab = ({ label: (
- + {t('label.task-plural')} {getCountBadge(tasksCount, '', isTaskActiveTab)} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/AddDataQualityTestV1.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/AddDataQualityTestV1.tsx index 1ca167fa4ee1..e3fd9251df73 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/AddDataQualityTestV1.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/AddDataQualityTestV1.tsx @@ -293,7 +293,7 @@ const AddDataQualityTestV1: React.FC = ({ flex: 0.4, overlay: { displayThreshold: 200, - header: t('label.setup-guide'), + header: t('label.data-profiler-metrics'), rotation: 'counter-clockwise', }, }} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/CreateUser/CreateUser.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/CreateUser/CreateUser.component.tsx index 809ff7c3250b..e9b202d44a9f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/CreateUser/CreateUser.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/CreateUser/CreateUser.component.tsx @@ -22,7 +22,7 @@ import { Switch, } from 'antd'; import { AxiosError } from 'axios'; -import { isEmpty, isUndefined, map, trim } from 'lodash'; +import { compact, isEmpty, map, trim } from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { VALIDATION_MESSAGES } from '../../constants/constants'; @@ -33,6 +33,7 @@ import { CreatePasswordType, CreateUser as CreateUserSchema, } from '../../generated/api/teams/createUser'; +import { EntityReference } from '../../generated/entity/type'; import { AuthProvider } from '../../generated/settings/settings'; import { checkEmailInUse, generateRandomPwd } from '../../rest/auth-API'; import { getJWTTokenExpiryOptions } from '../../utils/BotsUtils'; @@ -60,9 +61,9 @@ const CreateUser = ({ const { authConfig } = useAuthContext(); const [isAdmin, setIsAdmin] = useState(false); const [isBot, setIsBot] = useState(forceBot); - const [selectedTeams, setSelectedTeams] = useState>( - [] - ); + const [selectedTeams, setSelectedTeams] = useState< + Array + >([]); const [isPasswordGenerating, setIsPasswordGenerating] = useState(false); const isAuthProviderBasic = useMemo( @@ -105,9 +106,7 @@ const CreateUser = ({ const handleSave: FormProps['onFinish'] = (values) => { const isPasswordGenerated = passwordGenerator === CreatePasswordGenerator.AutomaticGenerate; - const validTeam = selectedTeams.filter( - (id) => !isUndefined(id) - ) as string[]; + const validTeam = compact(selectedTeams).map((team) => team.id); const { email, displayName, tokenExpiry, confirmPassword, description } = values; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataModels/ModelTab/ModelTab.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataModels/ModelTab/ModelTab.component.tsx index ab3f62788b08..92e8107d1c3f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataModels/ModelTab/ModelTab.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataModels/ModelTab/ModelTab.component.tsx @@ -10,7 +10,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Table, Typography } from 'antd'; +import { Typography } from 'antd'; import { ColumnsType } from 'antd/lib/table'; import { cloneDeep, isUndefined } from 'lodash'; import { EntityTags } from 'Models'; @@ -25,6 +25,7 @@ import { TagLabel, TagSource } from '../../../generated/type/tagLabel'; import { updateDataModelColumnDescription } from '../../../utils/DataModelsUtils'; import { getEntityName } from '../../../utils/EntityUtils'; import { updateFieldTags } from '../../../utils/TableUtils'; +import Table from '../../common/Table/Table'; import { ModelTabProps } from './ModelTab.interface'; const ModelTab = ({ diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Explore/ExploreQuickFilters.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Explore/ExploreQuickFilters.tsx index fd6c8fe34147..b0fd91f79ae4 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Explore/ExploreQuickFilters.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Explore/ExploreQuickFilters.tsx @@ -34,6 +34,7 @@ import { showErrorToast } from '../../utils/ToastUtils'; import SearchDropdown from '../SearchDropdown/SearchDropdown'; import { SearchDropdownOption } from '../SearchDropdown/SearchDropdown.interface'; import { useAdvanceSearch } from './AdvanceSearchProvider/AdvanceSearchProvider.component'; +import { ExploreSearchIndex } from './explore.interface'; import { ExploreQuickFiltersProps } from './ExploreQuickFilters.interface'; const ExploreQuickFilters: FC = ({ @@ -196,6 +197,7 @@ const ExploreQuickFilters: FC = ({ = forwardRef< }, ]; + if (source?.domain) { + const domain = getEntityName(source.domain); + const domainLink = getDomainPath(source.domain.fullyQualifiedName); + _otherDetails.push({ + key: 'Domain', + value: domainLink, + placeholderText: domain, + isLink: true, + openInNewTab: false, + }); + } + if ( source.entityType !== EntityType.GLOSSARY_TERM && source.entityType !== EntityType.TAG diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebar.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebar.component.tsx index a5a02dfdda3a..1d6f72b6fbeb 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebar.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyData/LeftSidebar/LeftSidebar.component.tsx @@ -49,7 +49,7 @@ const LeftSidebar = () => { label: ( {t('label.govern')} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyDataWidget/MyDataWidget.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyDataWidget/MyDataWidget.component.tsx index ae11fc22e676..b60d9ffc3dea 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyDataWidget/MyDataWidget.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyDataWidget/MyDataWidget.component.tsx @@ -146,10 +146,12 @@ const MyDataWidgetInternal = ({ ); }) ) : ( - } - /> + + } + /> + )}
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/NotificationBox/NotificationBox.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/NotificationBox/NotificationBox.component.tsx index 1754f07d1220..fd9096a21a0d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/NotificationBox/NotificationBox.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/NotificationBox/NotificationBox.component.tsx @@ -168,7 +168,7 @@ const NotificationBox = ({
) : ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/NotificationBox/notification-box.less b/openmetadata-ui/src/main/resources/ui/src/components/NotificationBox/notification-box.less index 44d4ce5b8fbf..f6c9842766fb 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/NotificationBox/notification-box.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/NotificationBox/notification-box.less @@ -26,3 +26,12 @@ } } } + +.notification-content-container { + min-height: 16rem; + + .ant-spin-nested-loading { + height: 200px; + overflow-y: scroll; + } +} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/SchemaTable/SchemaTable.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/SchemaTable/SchemaTable.component.tsx index 7f584f28384e..29927e8769d8 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/SchemaTable/SchemaTable.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/SchemaTable/SchemaTable.component.tsx @@ -315,22 +315,22 @@ const SchemaTable = ({ tableConstraints, })} {/* If we do not have displayName name only be shown in the bold from the below code */} - {!isEmpty(displayName) ? ( - - {name} - - ) : null} - {/* It will render displayName fallback to name */} + + {name} + + + {!isEmpty(displayName) ? ( + // It will render displayName fallback to name {getEntityName(record)} - + ) : null} { wrapper: MemoryRouter, }); - const columnNames = await screen.findAllByTestId('column-display-name'); + const columnNames = await screen.findAllByTestId('column-name'); expect(columnNames).toHaveLength(3); @@ -244,12 +244,12 @@ describe('Test EntityTable Component', () => { const columnDisplayName = await screen.findAllByTestId( 'column-display-name' ); - const columnName = await screen.findByTestId('column-name'); + const columnName = await screen.findAllByTestId('column-name'); expect(columnDisplayName[0]).toBeInTheDocument(); - expect(columnName).toBeInTheDocument(); + expect(columnName[0]).toBeInTheDocument(); expect(columnDisplayName[0].textContent).toBe('Comments'); - expect(columnName.textContent).toBe('comments'); + expect(columnName[0].textContent).toBe('comments'); }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.interface.ts index 655a7869ac0e..9309414a778a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.interface.ts @@ -11,6 +11,8 @@ * limitations under the License. */ +import { ExploreSearchIndex } from '../Explore/explore.interface'; + export interface SearchDropdownProps { label: string; isSuggestionsLoading?: boolean; @@ -20,6 +22,7 @@ export interface SearchDropdownProps { highlight?: boolean; showProfilePicture?: boolean; fixedOrderOptions?: boolean; + index?: ExploreSearchIndex; onChange: (values: SearchDropdownOption[], searchKey: string) => void; onGetInitialOptions?: (searchKey: string) => void; onSearch: (searchText: string, searchKey: string) => void; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.test.tsx index d4e12e13bb4f..e804b67fd901 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.test.tsx @@ -36,6 +36,7 @@ const mockProps: SearchDropdownProps = { selectedKeys: [{ key: 'User 1', label: 'User 1' }], onChange: mockOnChange, onSearch: mockOnSearch, + index: 'table_search_index' as SearchDropdownProps['index'], }; jest.mock('lodash', () => ({ diff --git a/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.tsx b/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.tsx index 46d88166b5f7..5c55fcb96f99 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/SearchDropdown/SearchDropdown.tsx @@ -37,6 +37,7 @@ import React, { } from 'react'; import { useTranslation } from 'react-i18next'; import { ReactComponent as DropDown } from '../../assets/svg/DropDown.svg'; +import { tabsInfo } from '../../constants/explore.constants'; import { generateSearchDropdownLabel, getSearchDropdownLabels, @@ -61,6 +62,7 @@ const SearchDropdown: FC = ({ onChange, onGetInitialOptions, onSearch, + index, }) => { const { t } = useTranslation(); @@ -170,6 +172,8 @@ const SearchDropdown: FC = ({ const getDropdownBody = useCallback( (menuNode: ReactNode) => { + const entityLabel = index && tabsInfo[index]?.label; + const isDomainKey = searchKey.startsWith('domain'); if (isSuggestionsLoading) { return ( @@ -185,12 +189,18 @@ const SearchDropdown: FC = ({ ) : ( - {t('message.no-data-available')} + + {isDomainKey && entityLabel + ? t('message.no-domain-assigned-to-entity', { + entity: entityLabel, + }) + : t('message.no-data-available')} + ); }, - [isSuggestionsLoading, options, selectedOptions] + [isSuggestionsLoading, options, selectedOptions, index, searchKey] ); const dropdownCardComponent = useCallback( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Services/Services.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Services/Services.tsx index 5e121bf9afaa..db017d75b861 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Services/Services.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Services/Services.tsx @@ -339,7 +339,7 @@ const Services = ({ serviceName }: ServicesProps) => { serviceName )}> {getEntityName(service)} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TeamsSelectable/TeamsSelectable.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/TeamsSelectable/TeamsSelectable.interface.ts index 4cd70ec21d35..fea4122a9c71 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TeamsSelectable/TeamsSelectable.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/TeamsSelectable/TeamsSelectable.interface.ts @@ -1,3 +1,5 @@ +import { EntityReference } from '../../generated/entity/type'; + /* * Copyright 2023 Collate. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,9 +14,9 @@ */ export interface TeamsSelectableProps { showTeamsAlert?: boolean; - onSelectionChange?: (teams: string[]) => void; + onSelectionChange?: (teams: EntityReference[]) => void; filterJoinable?: boolean; placeholder?: string; - selectedTeams?: string[]; + selectedTeams?: EntityReference[]; maxValueCount?: number; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TeamsSelectable/TeamsSelectable.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TeamsSelectable/TeamsSelectable.tsx index 2792dd607899..2c8198ee3118 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TeamsSelectable/TeamsSelectable.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TeamsSelectable/TeamsSelectable.tsx @@ -16,6 +16,7 @@ import { BaseOptionType } from 'antd/lib/select'; import { t } from 'i18next'; import React, { useEffect, useMemo, useState } from 'react'; import { TeamHierarchy } from '../../generated/entity/teams/teamHierarchy'; +import { EntityReference } from '../../generated/entity/type'; import { getTeamsHierarchy } from '../../rest/teamsAPI'; import { getEntityName } from '../../utils/EntityUtils'; import { showErrorToast } from '../../utils/ToastUtils'; @@ -31,19 +32,23 @@ const TeamsSelectable = ({ selectedTeams, maxValueCount, }: TeamsSelectableProps) => { - const [value, setValue] = useState>(); const [noTeam, setNoTeam] = useState(false); const [teams, setTeams] = useState>([]); - const onChange = (newValue: string[]) => { - onSelectionChange && onSelectionChange(newValue); - setValue(newValue); + const onChange = (newValue: { label: string; value: string }[]) => { + onSelectionChange && + onSelectionChange( + newValue.map( + (val) => + ({ + id: val.value, + displayName: val.label, + type: 'team', + } as EntityReference) + ) + ); }; - useEffect(() => { - setValue(selectedTeams ?? []); - }, [selectedTeams]); - const loadOptions = () => { getTeamsHierarchy(filterJoinable) .then((res) => { @@ -84,10 +89,18 @@ const TeamsSelectable = ({ }); }, [teams]); + const selectedTeamsInternal = useMemo(() => { + return selectedTeams?.map((selectedTeam) => ({ + label: getEntityName(selectedTeam), + value: selectedTeam.id, + })); + }, [selectedTeams]); + return ( <> {noTeam && ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Users/UserProfileIcon/UserProfileIcon.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Users/UserProfileIcon/UserProfileIcon.component.tsx index aa10cce7587b..8cf0eefc1d76 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Users/UserProfileIcon/UserProfileIcon.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Users/UserProfileIcon/UserProfileIcon.component.tsx @@ -11,7 +11,7 @@ * limitations under the License. */ import { CheckOutlined } from '@ant-design/icons'; -import { Dropdown, Tag, Typography } from 'antd'; +import { Dropdown, Tag, Tooltip, Typography } from 'antd'; import { ItemType } from 'antd/lib/menu/hooks/useItems'; import { isEmpty } from 'lodash'; import React, { @@ -293,21 +293,20 @@ export const UserProfileIcon = () => { {isImgUrlValid ? ( user ) : ( )} -
- - {getEntityName(currentUser)} - +
+ + + {getEntityName(currentUser)} + + diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Users/UsersProfile/UserProfileTeams/UserProfileTeams.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Users/UsersProfile/UserProfileTeams/UserProfileTeams.component.tsx index aaf52ac4c945..4f8bac01451f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Users/UsersProfile/UserProfileTeams/UserProfileTeams.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Users/UsersProfile/UserProfileTeams/UserProfileTeams.component.tsx @@ -23,6 +23,7 @@ import { DE_ACTIVE_COLOR, ICON_DIMENSION, } from '../../../../constants/constants'; +import { EntityReference } from '../../../../generated/entity/type'; import { useAuth } from '../../../../hooks/authHooks'; import { getNonDeletedTeams } from '../../../../utils/CommonUtils'; import { UserProfileTeamsProps } from './UserProfileTeams.interface'; @@ -35,11 +36,11 @@ const UserProfileTeams = ({ const { isAdminUser } = useAuth(); const [isTeamsEdit, setIsTeamsEdit] = useState(false); - const [selectedTeams, setSelectedTeams] = useState([]); + const [selectedTeams, setSelectedTeams] = useState([]); const handleTeamsSave = () => { updateUserDetails({ - teams: selectedTeams.map((teamId) => ({ id: teamId, type: 'team' })), + teams: selectedTeams.map((teamId) => ({ id: teamId.id, type: 'team' })), }); setIsTeamsEdit(false); @@ -57,7 +58,7 @@ const UserProfileTeams = ({ ); useEffect(() => { - setSelectedTeams(getNonDeletedTeams(teams ?? []).map((team) => team.id)); + setSelectedTeams(getNonDeletedTeams(teams ?? [])); }, [teams]); return ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/DomainSelectableList/DomainSelectableList.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/DomainSelectableList/DomainSelectableList.component.tsx index 51e0e1b15848..4cd615fb5e84 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/DomainSelectableList/DomainSelectableList.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/DomainSelectableList/DomainSelectableList.component.tsx @@ -113,6 +113,9 @@ const DomainSelectableList = ({ customTagRenderer={DomainListItemRenderer} fetchOptions={fetchOptions} multiSelect={false} + removeIconTooltipLabel={t('label.remove-entity', { + entity: t('label.domain-lowercase'), + })} searchPlaceholder={t('label.search-for-type', { type: t('label.domain'), })} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/EntitySummaryDetails/EntitySummaryDetails.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/EntitySummaryDetails/EntitySummaryDetails.tsx index a89a220abb4c..511fae173e57 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/EntitySummaryDetails/EntitySummaryDetails.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/EntitySummaryDetails/EntitySummaryDetails.tsx @@ -20,6 +20,7 @@ import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { ReactComponent as EditIcon } from '../../../assets/svg/edit-new.svg'; import { ReactComponent as IconExternalLink } from '../../../assets/svg/external-links.svg'; +import { ReactComponent as DomainIcon } from '../../../assets/svg/ic-domain.svg'; import { ReactComponent as IconTeamsGrey } from '../../../assets/svg/teams-grey.svg'; import { DE_ACTIVE_COLOR } from '../../../constants/constants'; import { Tag } from '../../../generated/entity/classification/tag'; @@ -186,6 +187,20 @@ const EntitySummaryDetails = ({ break; + case 'Domain': + { + retVal = ( + + ); + } + + break; default: { retVal = ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/SelectableList/SelectableList.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/SelectableList/SelectableList.component.tsx index 592e5548c4f0..eb8d3e53d903 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/SelectableList/SelectableList.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/SelectableList/SelectableList.component.tsx @@ -38,6 +38,7 @@ export const SelectableList = ({ searchPlaceholder, customTagRenderer, searchBarDataTestId, + removeIconTooltipLabel, }: SelectableListProps) => { const [uniqueOptions, setUniqueOptions] = useState([]); const [searchText, setSearchText] = useState(''); @@ -230,7 +231,10 @@ export const SelectableList = ({ ) : ( selectedItemsInternal.has(item.id) && ( - + ) ) } @@ -249,14 +253,23 @@ export const SelectableList = ({ ); }; -const RemoveIcon = ({ removeOwner }: { removeOwner?: () => void }) => { +const RemoveIcon = ({ + removeOwner, + removeIconTooltipLabel, +}: { + removeOwner?: () => void; + removeIconTooltipLabel?: string; +}) => { const { t } = useTranslation(); return ( + title={ + removeIconTooltipLabel ?? + t('label.remove-entity', { + entity: t('label.owner-lowercase'), + }) + }> ReactNode; searchBarDataTestId?: string; + removeIconTooltipLabel?: string; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/nav-bar/nav-bar.less b/openmetadata-ui/src/main/resources/ui/src/components/nav-bar/nav-bar.less index 0ffb6ee060d7..a27e1f12647d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/nav-bar/nav-bar.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/nav-bar/nav-bar.less @@ -23,7 +23,7 @@ align-items: center; cursor: pointer; - .usename { + .username { font-weight: 500; line-height: 21px; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/searched-data/SearchedData.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/searched-data/SearchedData.interface.ts index d0ff6cc45c62..92b14267adbd 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/searched-data/SearchedData.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/searched-data/SearchedData.interface.ts @@ -43,7 +43,8 @@ type Fields = | 'serviceType' | 'displayName' | 'deleted' - | 'service'; + | 'service' + | 'domain'; export type SourceType = ( | Pick< diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/constants.ts b/openmetadata-ui/src/main/resources/ui/src/constants/constants.ts index 51f2ae8de5a4..ac51042c7ad3 100644 --- a/openmetadata-ui/src/main/resources/ui/src/constants/constants.ts +++ b/openmetadata-ui/src/main/resources/ui/src/constants/constants.ts @@ -14,6 +14,7 @@ import { t } from 'i18next'; import { isUndefined } from 'lodash'; import Qs from 'qs'; +import { CSSProperties } from 'react'; import { COOKIE_VERSION } from '../components/Modals/WhatsNewModal/whatsNewData'; import { EntityTabs } from '../enums/entity.enum'; import { SearchIndex } from '../enums/search.enum'; @@ -835,3 +836,7 @@ export const ICON_DIMENSION = { with: 14, height: 14, }; + +export const COMMON_ICON_STYLES: CSSProperties = { + verticalAlign: 'middle', +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/explore.constants.ts b/openmetadata-ui/src/main/resources/ui/src/constants/explore.constants.ts index fad7fea2a6ae..61b96e112025 100644 --- a/openmetadata-ui/src/main/resources/ui/src/constants/explore.constants.ts +++ b/openmetadata-ui/src/main/resources/ui/src/constants/explore.constants.ts @@ -112,6 +112,12 @@ export const tabsInfo: { [K in ExploreSearchIndex]: ExploreTabInfo } = { sortField: INITIAL_SORT_FIELD, path: 'containers', }, + [SearchIndex.SEARCH_INDEX]: { + label: i18n.t('label.search-index-plural'), + sortingFields: entitySortingFields, + sortField: INITIAL_SORT_FIELD, + path: 'searchIndexes', + }, [SearchIndex.GLOSSARY]: { label: i18n.t('label.glossary-plural'), sortingFields: entitySortingFields, @@ -124,12 +130,6 @@ export const tabsInfo: { [K in ExploreSearchIndex]: ExploreTabInfo } = { sortField: INITIAL_SORT_FIELD, path: 'tags', }, - [SearchIndex.SEARCH_INDEX]: { - label: i18n.t('label.search-index-plural'), - sortingFields: entitySortingFields, - sortField: INITIAL_SORT_FIELD, - path: 'searchIndexes', - }, }; export const COMMON_FILTERS_FOR_DIFFERENT_TABS = [ diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json index aec467607a92..3f5a9128cd80 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json @@ -251,6 +251,7 @@ "data-model-type": "Datenmodelltyp", "data-product": "Datenprodukt", "data-product-plural": "Datenprodukte", + "data-profiler-metrics": "Data Profiler Metrics", "data-proportion-plural": "Datenverhältnisse", "data-quality": "Datenqualität", "data-quality-test": "Datenqualitätstest", @@ -1362,6 +1363,7 @@ "no-data": "Keine Daten", "no-data-available": "Keine Daten verfügbar.", "no-data-available-for-selected-filter": "Keine Daten gefunden. Versuchen Sie, die Filter zu ändern.", + "no-domain-assigned-to-entity": "No Domains are Assigned to {{entity}}", "no-entity-activity-message": "Es gibt noch keine Aktivität auf {{entity}}. Starten Sie ein Gespräch, indem Sie auf das", "no-entity-available-with-name": "Keine {{entity}} mit dem Namen verfügbar", "no-entity-data-available": "Keine {{entity}}-Daten verfügbar.", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json index 66334b62ec23..33ab31e4fce4 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json @@ -251,6 +251,7 @@ "data-model-type": "Data Model Type", "data-product": "Data Product", "data-product-plural": "Data Products", + "data-profiler-metrics": "Data Profiler Metrics", "data-proportion-plural": "Data Proportions", "data-quality": "Data Quality", "data-quality-test": "Data Quality Test", @@ -1362,6 +1363,7 @@ "no-data": "No data", "no-data-available": "No data available.", "no-data-available-for-selected-filter": "No data found. Try changing the filters.", + "no-domain-assigned-to-entity": "No Domains are Assigned to {{entity}}", "no-entity-activity-message": "There is no activity on the {{entity}} yet. Start a conversation by clicking on the", "no-entity-available-with-name": "No {{entity}} available with name", "no-entity-data-available": "No {{entity}} data available.", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json index 14a7a0a78329..2249d3760094 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json @@ -251,6 +251,7 @@ "data-model-type": "Data Model Type", "data-product": "Data Product", "data-product-plural": "Data Products", + "data-profiler-metrics": "Data Profiler Metrics", "data-proportion-plural": "Data Proportions", "data-quality": "Data Quality", "data-quality-test": "Prueba de calidad de datos", @@ -1362,6 +1363,7 @@ "no-data": "No hay datos", "no-data-available": "No hay datos disponibles.", "no-data-available-for-selected-filter": "No se encontraron datos. Intenta cambiar los filtros.", + "no-domain-assigned-to-entity": "No Domains are Assigned to {{entity}}", "no-entity-activity-message": "No hay actividad en {{entity}} todavía. Comienza una conversación haciendo clic en", "no-entity-available-with-name": "No hay {{entity}} disponible con el nombre", "no-entity-data-available": "No hay datos disponibles de {{entity}}.", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json index 20da144e3e51..dc6dc13fec3e 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json @@ -251,6 +251,7 @@ "data-model-type": "Type de Modèle de Données", "data-product": "Produit de Données", "data-product-plural": "Produits de Données", + "data-profiler-metrics": "Data Profiler Metrics", "data-proportion-plural": "Proportions des Données", "data-quality": "Qualité des Données", "data-quality-test": "Test de Qualité des Données", @@ -1362,6 +1363,7 @@ "no-data": "Aucune donnée", "no-data-available": "Aucune donnée disponible", "no-data-available-for-selected-filter": "Aucune donnée trouvée. Essayez de modifier les filtres.", + "no-domain-assigned-to-entity": "No Domains are Assigned to {{entity}}", "no-entity-activity-message": "Il n'y a aucune activité sur {{entity}} pour le moment. Démarrez une conversation en cliquant sur le bouton", "no-entity-available-with-name": "Aucun {{entity}} disponible avec le nom", "no-entity-data-available": "Aucun {{entity}} disponible.", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json index ded7dfd1c6b0..e04ddb4738bf 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json @@ -251,6 +251,7 @@ "data-model-type": "Data Model Type", "data-product": "Data Product", "data-product-plural": "Data Products", + "data-profiler-metrics": "Data Profiler Metrics", "data-proportion-plural": "Data Proportions", "data-quality": "Data Quality", "data-quality-test": "データ品質テスト", @@ -1362,6 +1363,7 @@ "no-data": "データがありません", "no-data-available": "利用できるデータがありません", "no-data-available-for-selected-filter": "No data found. Try changing the filters.", + "no-domain-assigned-to-entity": "No Domains are Assigned to {{entity}}", "no-entity-activity-message": "There is no activity on the {{entity}} yet. Start a conversation by clicking on the", "no-entity-available-with-name": "No {{entity}} available with name", "no-entity-data-available": "No {{entity}} data available.", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json index 8d991af301ef..ded879d8cb74 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json @@ -251,6 +251,7 @@ "data-model-type": "Data Model Type", "data-product": "Data Product", "data-product-plural": "Data Products", + "data-profiler-metrics": "Data Profiler Metrics", "data-proportion-plural": "Data Proportions", "data-quality": "Data Quality", "data-quality-test": "Teste de qualidade de dados", @@ -1362,6 +1363,7 @@ "no-data": "Nenhum dado", "no-data-available": "Nenhum dado disponível.", "no-data-available-for-selected-filter": "Nenhum dado encontrado. Tente alterar os filtros.", + "no-domain-assigned-to-entity": "No Domains are Assigned to {{entity}}", "no-entity-activity-message": "Não há atividade em {{entity}} ainda. Inicie uma conversa clicando em", "no-entity-available-with-name": "Não há {{entity}} disponível com o nome", "no-entity-data-available": "Nenhum dado disponível para {{entity}}.", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json index e90664cc53c1..26b73d4f13e6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json @@ -251,6 +251,7 @@ "data-model-type": "Тип модели данных", "data-product": "Data Product", "data-product-plural": "Data Products", + "data-profiler-metrics": "Data Profiler Metrics", "data-proportion-plural": "Распределение данных", "data-quality": "Качество данных", "data-quality-test": "Тест качества данных", @@ -1362,6 +1363,7 @@ "no-data": "Нет данных", "no-data-available": "Данные недоступны.", "no-data-available-for-selected-filter": "Данные не найдены. Попробуйте поменять фильтры.", + "no-domain-assigned-to-entity": "No Domains are Assigned to {{entity}}", "no-entity-activity-message": "В {{entity}} пока нет активности. Начните обсуждение, нажав на кнопку", "no-entity-available-with-name": "Нет доступного {{entity}} с именем", "no-entity-data-available": "Данные {{entity}} недоступны.", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json index e74336309980..3e4e9df34656 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json @@ -251,6 +251,7 @@ "data-model-type": "数据模型类型", "data-product": "数据产品", "data-product-plural": "数据产品", + "data-profiler-metrics": "Data Profiler Metrics", "data-proportion-plural": "数据比例", "data-quality": "数据质控", "data-quality-test": "数据质控测试", @@ -1362,6 +1363,7 @@ "no-data": "没有数据", "no-data-available": "没有可用的数据", "no-data-available-for-selected-filter": "未找到数据,请尝试更改筛选条件", + "no-domain-assigned-to-entity": "No Domains are Assigned to {{entity}}", "no-entity-activity-message": "{{entity}}上还没有任何活动,单击开始对话", "no-entity-available-with-name": "名称为{{entity}}不可用", "no-entity-data-available": "没有可用的{{entity}}数据。", diff --git a/openmetadata-ui/src/main/resources/ui/src/styles/app.less b/openmetadata-ui/src/main/resources/ui/src/styles/app.less index 8e40a89696cd..8522b2765ae9 100644 --- a/openmetadata-ui/src/main/resources/ui/src/styles/app.less +++ b/openmetadata-ui/src/main/resources/ui/src/styles/app.less @@ -738,3 +738,10 @@ a[href].link-text-grey, padding-left: 0.25rem; padding-right: 0.25rem; } + +.app-bar-user-avatar { + display: inline-block; + height: 36px; + width: 36px; + border-radius: 50%; +} diff --git a/openmetadata-ui/src/main/resources/ui/src/styles/components/button.less b/openmetadata-ui/src/main/resources/ui/src/styles/components/button.less index 71b7d9efb4b9..8223bc7d0151 100644 --- a/openmetadata-ui/src/main/resources/ui/src/styles/components/button.less +++ b/openmetadata-ui/src/main/resources/ui/src/styles/components/button.less @@ -65,3 +65,7 @@ button { .ant-btn-group .ant-btn-primary:first-child:not(:last-child) { border-right-color: #ffffff; } + +.ant-btn-primary { + box-shadow: none; +} diff --git a/openmetadata-ui/src/main/resources/ui/src/styles/components/size.less b/openmetadata-ui/src/main/resources/ui/src/styles/components/size.less index 308af9559e0e..f17b5a6a398f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/styles/components/size.less +++ b/openmetadata-ui/src/main/resources/ui/src/styles/components/size.less @@ -95,6 +95,9 @@ .w-max-90 { max-width: 90%; } +.w-max-112 { + max-width: 112px; +} .w-max-200 { max-width: 200px; } diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/DataInsightUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/DataInsightUtils.tsx index 0d19a15be2fa..d5d2ff9c4468 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/DataInsightUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/DataInsightUtils.tsx @@ -34,15 +34,15 @@ import React from 'react'; import { ListItem } from 'react-awesome-query-builder'; import { LegendProps, Surface } from 'recharts'; import { SearchDropdownOption } from '../components/SearchDropdown/SearchDropdown.interface'; -import { - ENTITIES_SUMMARY_LIST, - WEB_SUMMARY_LIST, -} from '../constants/DataInsight.constants'; import { GRAYED_OUT_COLOR, PLACEHOLDER_ROUTE_TAB, ROUTES, } from '../constants/constants'; +import { + ENTITIES_SUMMARY_LIST, + WEB_SUMMARY_LIST, +} from '../constants/DataInsight.constants'; import { KpiTargetType } from '../generated/api/dataInsight/kpi/createKpiRequest'; import { DataInsightChartResult, diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/GlobalSettingsUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/GlobalSettingsUtils.tsx index 4b32afacc26f..9a266dcd2f80 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/GlobalSettingsUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/GlobalSettingsUtils.tsx @@ -180,15 +180,6 @@ export const getGlobalSettingsMenuWithPermission = ( key: 'services.mlModels', icon: , }, - { - label: i18next.t('label.metadata'), - isProtected: userPermissions.hasViewPermissions( - ResourceEntity.METADATA_SERVICE, - permissions - ), - key: 'services.metadata', - icon: , - }, { label: i18next.t('label.storage-plural'), isProtected: userPermissions.hasViewPermissions( @@ -207,6 +198,15 @@ export const getGlobalSettingsMenuWithPermission = ( key: 'services.search', icon: , }, + { + label: i18next.t('label.metadata'), + isProtected: userPermissions.hasViewPermissions( + ResourceEntity.METADATA_SERVICE, + permissions + ), + key: 'services.metadata', + icon: , + }, ], },