mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-26 09:22:14 +00:00
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 <ashish@getcollate.io> Co-authored-by: Sachin Chaurasiya <sachinchaurasiyachotey87@gmail.com>
This commit is contained in:
parent
753e182e21
commit
7c25b5fddd
@ -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"],
|
||||
|
@ -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"],
|
||||
|
@ -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: (
|
||||
<div className="d-flex justify-between">
|
||||
<Space align="center" size="small">
|
||||
<AllActivityIcon {...ICON_DIMENSION} />
|
||||
<AllActivityIcon
|
||||
style={COMMON_ICON_STYLES}
|
||||
{...ICON_DIMENSION}
|
||||
/>
|
||||
<span>{t('label.all')}</span>
|
||||
</Space>
|
||||
|
||||
@ -316,7 +322,7 @@ export const ActivityFeedTab = ({
|
||||
{
|
||||
label: (
|
||||
<Space align="center" size="small">
|
||||
<MentionIcon {...ICON_DIMENSION} />
|
||||
<MentionIcon style={COMMON_ICON_STYLES} {...ICON_DIMENSION} />
|
||||
<span>{t('label.mention-plural')}</span>
|
||||
</Space>
|
||||
),
|
||||
@ -326,7 +332,10 @@ export const ActivityFeedTab = ({
|
||||
label: (
|
||||
<div className="d-flex justify-between">
|
||||
<Space align="center" size="small">
|
||||
<TaskListIcon {...ICON_DIMENSION} />
|
||||
<TaskListIcon
|
||||
style={COMMON_ICON_STYLES}
|
||||
{...ICON_DIMENSION}
|
||||
/>
|
||||
<span>{t('label.task-plural')}</span>
|
||||
</Space>
|
||||
<span>{getCountBadge(tasksCount, '', isTaskActiveTab)}</span>
|
||||
|
@ -293,7 +293,7 @@ const AddDataQualityTestV1: React.FC<AddDataQualityTestProps> = ({
|
||||
flex: 0.4,
|
||||
overlay: {
|
||||
displayThreshold: 200,
|
||||
header: t('label.setup-guide'),
|
||||
header: t('label.data-profiler-metrics'),
|
||||
rotation: 'counter-clockwise',
|
||||
},
|
||||
}}
|
||||
|
@ -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<Array<string | undefined>>(
|
||||
[]
|
||||
);
|
||||
const [selectedTeams, setSelectedTeams] = useState<
|
||||
Array<EntityReference | undefined>
|
||||
>([]);
|
||||
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;
|
||||
|
@ -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 = ({
|
||||
|
@ -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<ExploreQuickFiltersProps> = ({
|
||||
@ -196,6 +197,7 @@ const ExploreQuickFilters: FC<ExploreQuickFiltersProps> = ({
|
||||
<SearchDropdown
|
||||
highlight
|
||||
fixedOrderOptions={field.key === TIER_FQN_KEY}
|
||||
index={index as ExploreSearchIndex}
|
||||
isSuggestionsLoading={isOptionsLoading}
|
||||
key={field.key}
|
||||
label={field.label}
|
||||
|
@ -30,6 +30,7 @@ import {
|
||||
getEntityLinkFromType,
|
||||
getEntityName,
|
||||
} from '../../../utils/EntityUtils';
|
||||
import { getDomainPath } from '../../../utils/RouterUtils';
|
||||
import { stringToHTML } from '../../../utils/StringsUtils';
|
||||
import { getServiceIcon, getUsagePercentile } from '../../../utils/TableUtils';
|
||||
import TitleBreadcrumb from '../../common/title-breadcrumb/title-breadcrumb.component';
|
||||
@ -81,6 +82,18 @@ const ExploreSearchCard: React.FC<ExploreSearchCardProps> = 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
|
||||
|
@ -49,7 +49,7 @@ const LeftSidebar = () => {
|
||||
label: (
|
||||
<Tooltip
|
||||
overlayClassName="left-panel-tooltip"
|
||||
placement="right"
|
||||
placement="topLeft"
|
||||
title={
|
||||
<Typography.Text className="left-panel-label">
|
||||
{t('label.govern')}
|
||||
|
@ -146,10 +146,12 @@ const MyDataWidgetInternal = ({
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<Transi18next
|
||||
i18nKey="message.no-owned-data"
|
||||
renderElement={<Link to={ROUTES.EXPLORE} />}
|
||||
/>
|
||||
<span className="text-sm">
|
||||
<Transi18next
|
||||
i18nKey="message.no-owned-data"
|
||||
renderElement={<Link to={ROUTES.EXPLORE} />}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
@ -168,7 +168,7 @@ const NotificationBox = ({
|
||||
</div>
|
||||
) : (
|
||||
<List
|
||||
className="h-min-64"
|
||||
className="notification-content-container"
|
||||
dataSource={notificationDropDownList}
|
||||
footer={
|
||||
<Button block href={viewAllPath} type="link">
|
||||
|
@ -26,3 +26,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notification-content-container {
|
||||
min-height: 16rem;
|
||||
|
||||
.ant-spin-nested-loading {
|
||||
height: 200px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
@ -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) ? (
|
||||
<Typography.Text
|
||||
className="m-b-0 d-block text-grey-muted"
|
||||
data-testid="column-name">
|
||||
{name}
|
||||
</Typography.Text>
|
||||
) : null}
|
||||
|
||||
{/* It will render displayName fallback to name */}
|
||||
<Typography.Text
|
||||
className="m-b-0 d-block text-grey-muted"
|
||||
data-testid="column-name">
|
||||
{name}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
{!isEmpty(displayName) ? (
|
||||
// It will render displayName fallback to name
|
||||
<Typography.Text
|
||||
className="m-b-0 d-block"
|
||||
data-testid="column-display-name"
|
||||
ellipsis={{ tooltip: true }}>
|
||||
{getEntityName(record)}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
) : null}
|
||||
<Icon
|
||||
className="hover-cell-icon text-left m-t-xss"
|
||||
component={IconEdit}
|
||||
|
@ -221,7 +221,7 @@ describe('Test EntityTable Component', () => {
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -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', () => ({
|
||||
|
@ -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<SearchDropdownProps> = ({
|
||||
onChange,
|
||||
onGetInitialOptions,
|
||||
onSearch,
|
||||
index,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -170,6 +172,8 @@ const SearchDropdown: FC<SearchDropdownProps> = ({
|
||||
|
||||
const getDropdownBody = useCallback(
|
||||
(menuNode: ReactNode) => {
|
||||
const entityLabel = index && tabsInfo[index]?.label;
|
||||
const isDomainKey = searchKey.startsWith('domain');
|
||||
if (isSuggestionsLoading) {
|
||||
return (
|
||||
<Row align="middle" className="p-y-sm" justify="center">
|
||||
@ -185,12 +189,18 @@ const SearchDropdown: FC<SearchDropdownProps> = ({
|
||||
) : (
|
||||
<Row align="middle" className="m-y-sm" justify="center">
|
||||
<Col>
|
||||
<Typography.Text>{t('message.no-data-available')}</Typography.Text>
|
||||
<Typography.Text className="m-x-sm">
|
||||
{isDomainKey && entityLabel
|
||||
? t('message.no-domain-assigned-to-entity', {
|
||||
entity: entityLabel,
|
||||
})
|
||||
: t('message.no-data-available')}
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
},
|
||||
[isSuggestionsLoading, options, selectedOptions]
|
||||
[isSuggestionsLoading, options, selectedOptions, index, searchKey]
|
||||
);
|
||||
|
||||
const dropdownCardComponent = useCallback(
|
||||
|
@ -339,7 +339,7 @@ const Services = ({ serviceName }: ServicesProps) => {
|
||||
serviceName
|
||||
)}>
|
||||
<Typography.Text
|
||||
className="text-base text-grey-body font-medium truncate w-48"
|
||||
className="text-base text-grey-body font-medium truncate w-48 d-inline-block"
|
||||
data-testid={`service-name-${service.name}`}
|
||||
title={getEntityName(service)}>
|
||||
{getEntityName(service)}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<Array<string>>();
|
||||
const [noTeam, setNoTeam] = useState<boolean>(false);
|
||||
const [teams, setTeams] = useState<Array<TeamHierarchy>>([]);
|
||||
|
||||
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 (
|
||||
<>
|
||||
<TreeSelect
|
||||
allowClear
|
||||
labelInValue
|
||||
multiple
|
||||
showSearch
|
||||
treeDefaultExpandAll
|
||||
@ -100,7 +113,7 @@ const TeamsSelectable = ({
|
||||
treeData={teamsTree}
|
||||
treeLine={{ showLeafIcon }}
|
||||
treeNodeFilterProp="title"
|
||||
value={value}
|
||||
value={selectedTeamsInternal}
|
||||
onChange={onChange}
|
||||
/>
|
||||
{noTeam && (
|
||||
|
@ -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 ? (
|
||||
<img
|
||||
alt="user"
|
||||
className="profile-image circle"
|
||||
className="app-bar-user-avatar"
|
||||
referrerPolicy="no-referrer"
|
||||
src={profilePicture ?? ''}
|
||||
width={36}
|
||||
onError={handleOnImageError}
|
||||
/>
|
||||
) : (
|
||||
<Avatar name={userName} type="circle" width="36" />
|
||||
)}
|
||||
<div className="d-flex flex-col flex-1">
|
||||
<Typography.Text
|
||||
className="usename w-28"
|
||||
ellipsis={{ tooltip: true }}>
|
||||
{getEntityName(currentUser)}
|
||||
</Typography.Text>
|
||||
<div className="d-flex flex-col">
|
||||
<Tooltip title={getEntityName(currentUser)}>
|
||||
<Typography.Text className="username truncate w-max-112">
|
||||
{getEntityName(currentUser)}
|
||||
</Typography.Text>
|
||||
</Tooltip>
|
||||
<Typography.Text
|
||||
className="text-grey-muted text-xs w-28"
|
||||
ellipsis={{ tooltip: true }}>
|
||||
|
@ -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<string[]>([]);
|
||||
const [selectedTeams, setSelectedTeams] = useState<EntityReference[]>([]);
|
||||
|
||||
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 (
|
||||
|
@ -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'),
|
||||
})}
|
||||
|
@ -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 = (
|
||||
<DomainIcon
|
||||
className="d-flex"
|
||||
color={DE_ACTIVE_COLOR}
|
||||
height={16}
|
||||
name="folder"
|
||||
width={16}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
{
|
||||
retVal = (
|
||||
|
@ -38,6 +38,7 @@ export const SelectableList = ({
|
||||
searchPlaceholder,
|
||||
customTagRenderer,
|
||||
searchBarDataTestId,
|
||||
removeIconTooltipLabel,
|
||||
}: SelectableListProps) => {
|
||||
const [uniqueOptions, setUniqueOptions] = useState<EntityReference[]>([]);
|
||||
const [searchText, setSearchText] = useState('');
|
||||
@ -230,7 +231,10 @@ export const SelectableList = ({
|
||||
<Checkbox checked={selectedItemsInternal.has(item.id)} />
|
||||
) : (
|
||||
selectedItemsInternal.has(item.id) && (
|
||||
<RemoveIcon removeOwner={handleRemoveClick} />
|
||||
<RemoveIcon
|
||||
removeIconTooltipLabel={removeIconTooltipLabel}
|
||||
removeOwner={handleRemoveClick}
|
||||
/>
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -249,14 +253,23 @@ export const SelectableList = ({
|
||||
);
|
||||
};
|
||||
|
||||
const RemoveIcon = ({ removeOwner }: { removeOwner?: () => void }) => {
|
||||
const RemoveIcon = ({
|
||||
removeOwner,
|
||||
removeIconTooltipLabel,
|
||||
}: {
|
||||
removeOwner?: () => void;
|
||||
removeIconTooltipLabel?: string;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
title={t('label.remove-entity', {
|
||||
entity: t('label.owner-lowercase'),
|
||||
})}>
|
||||
title={
|
||||
removeIconTooltipLabel ??
|
||||
t('label.remove-entity', {
|
||||
entity: t('label.owner-lowercase'),
|
||||
})
|
||||
}>
|
||||
<SVGIcons
|
||||
data-testid="remove-owner"
|
||||
icon={Icons.ICON_REMOVE_COLORED}
|
||||
|
@ -26,4 +26,5 @@ export interface SelectableListProps {
|
||||
searchPlaceholder?: string;
|
||||
customTagRenderer?: (props: EntityReference) => ReactNode;
|
||||
searchBarDataTestId?: string;
|
||||
removeIconTooltipLabel?: string;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
.usename {
|
||||
.username {
|
||||
font-weight: 500;
|
||||
line-height: 21px;
|
||||
}
|
||||
|
@ -43,7 +43,8 @@ type Fields =
|
||||
| 'serviceType'
|
||||
| 'displayName'
|
||||
| 'deleted'
|
||||
| 'service';
|
||||
| 'service'
|
||||
| 'domain';
|
||||
|
||||
export type SourceType = (
|
||||
| Pick<
|
||||
|
@ -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',
|
||||
};
|
||||
|
@ -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 = [
|
||||
|
@ -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.",
|
||||
|
@ -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.",
|
||||
|
@ -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}}.",
|
||||
|
@ -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.",
|
||||
|
@ -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.",
|
||||
|
@ -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}}.",
|
||||
|
@ -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}} недоступны.",
|
||||
|
@ -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}}数据。",
|
||||
|
@ -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%;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -95,6 +95,9 @@
|
||||
.w-max-90 {
|
||||
max-width: 90%;
|
||||
}
|
||||
.w-max-112 {
|
||||
max-width: 112px;
|
||||
}
|
||||
.w-max-200 {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -180,15 +180,6 @@ export const getGlobalSettingsMenuWithPermission = (
|
||||
key: 'services.mlModels',
|
||||
icon: <MlModelIcon className="side-panel-icons" />,
|
||||
},
|
||||
{
|
||||
label: i18next.t('label.metadata'),
|
||||
isProtected: userPermissions.hasViewPermissions(
|
||||
ResourceEntity.METADATA_SERVICE,
|
||||
permissions
|
||||
),
|
||||
key: 'services.metadata',
|
||||
icon: <OMLogo className="side-panel-icons w-4 h-4" />,
|
||||
},
|
||||
{
|
||||
label: i18next.t('label.storage-plural'),
|
||||
isProtected: userPermissions.hasViewPermissions(
|
||||
@ -207,6 +198,15 @@ export const getGlobalSettingsMenuWithPermission = (
|
||||
key: 'services.search',
|
||||
icon: <SearchOutlined className="side-panel-icons w-4 h-4" />,
|
||||
},
|
||||
{
|
||||
label: i18next.t('label.metadata'),
|
||||
isProtected: userPermissions.hasViewPermissions(
|
||||
ResourceEntity.METADATA_SERVICE,
|
||||
permissions
|
||||
),
|
||||
key: 'services.metadata',
|
||||
icon: <OMLogo className="side-panel-icons w-4 h-4" />,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user