fix(ui): address persona related feedbacks (#20833)

* fix(ui): address persona related feedbacks

* fix test and address comments

* fix minor ui fixes

* fix tests
This commit is contained in:
Chirag Madlani 2025-04-15 18:41:31 +05:30 committed by GitHub
parent 8e8cc3c614
commit 6495c0f0f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 150 additions and 51 deletions

View File

@ -32,10 +32,6 @@
margin-bottom: 0; margin-bottom: 0;
} }
.service-icon {
height: 16px;
}
.entity-summary-details { .entity-summary-details {
font-size: 12px; font-size: 12px;

View File

@ -35,20 +35,42 @@ export const CustomizablePageHeader = ({
const { fqn: personaFqn } = useFqn(); const { fqn: personaFqn } = useFqn();
const { currentPageType } = useCustomizeStore(); const { currentPageType } = useCustomizeStore();
const history = useHistory(); const history = useHistory();
const [isResetModalOpen, setIsResetModalOpen] = React.useState(false);
const [saving, setSaving] = React.useState(false); const [saving, setSaving] = React.useState(false);
const [confirmationModalOpen, setConfirmationModalOpen] =
React.useState(false);
const [confirmationModalType, setConfirmationModalType] = React.useState<
'reset' | 'close'
>('close');
const handleCancel = () => { const handleCancel = () => {
// Go back in history // Go back in history
history.goBack(); history.goBack();
}; };
const { modalTitle, modalDescription } = useMemo(() => {
if (confirmationModalType === 'reset') {
return {
modalTitle: t('label.reset-default-layout'),
modalDescription: t('message.reset-layout-confirmation'),
};
}
return {
modalTitle: t('message.are-you-sure-want-to-text', {
text: t('label.close'),
}),
modalDescription: t('message.unsaved-changes-warning'),
};
}, [confirmationModalType]);
const handleOpenResetModal = useCallback(() => { const handleOpenResetModal = useCallback(() => {
setIsResetModalOpen(true); setConfirmationModalType('reset');
setConfirmationModalOpen(true);
}, []); }, []);
const handleCloseResetModal = useCallback(() => { const handleCloseResetModal = useCallback(() => {
setIsResetModalOpen(false); setConfirmationModalOpen(false);
}, []); }, []);
const handleSave = useCallback(async () => { const handleSave = useCallback(async () => {
@ -58,9 +80,10 @@ export const CustomizablePageHeader = ({
}, [onSave]); }, [onSave]);
const handleReset = useCallback(async () => { const handleReset = useCallback(async () => {
onReset(); confirmationModalType === 'reset' ? onReset() : handleCancel();
setIsResetModalOpen(false); setConfirmationModalOpen(false);
}, [onReset]); }, [onReset, confirmationModalType, handleCancel]);
const i18Values = useMemo( const i18Values = useMemo(
() => ({ () => ({
persona: personaName, persona: personaName,
@ -72,6 +95,11 @@ export const CustomizablePageHeader = ({
[personaName] [personaName]
); );
const handleClose = useCallback(() => {
setConfirmationModalType('close');
setConfirmationModalOpen(true);
}, []);
return ( return (
<Card <Card
className="customize-page-header" className="customize-page-header"
@ -99,8 +127,8 @@ export const CustomizablePageHeader = ({
data-testid="cancel-button" data-testid="cancel-button"
disabled={saving} disabled={saving}
icon={<CloseOutlined />} icon={<CloseOutlined />}
onClick={handleCancel}> onClick={handleClose}>
{t('label.cancel')} {t('label.close')}
</Button> </Button>
<Button <Button
data-testid="reset-button" data-testid="reset-button"
@ -119,17 +147,18 @@ export const CustomizablePageHeader = ({
</Button> </Button>
</Space> </Space>
</div> </div>
{isResetModalOpen && (
{confirmationModalOpen && (
<Modal <Modal
centered centered
cancelText={t('label.no')} cancelText={t('label.no')}
data-testid="reset-layout-modal" data-testid="reset-layout-modal"
okText={t('label.yes')} okText={t('label.yes')}
open={isResetModalOpen} open={confirmationModalOpen}
title={t('label.reset-default-layout')} title={modalTitle}
onCancel={handleCloseResetModal} onCancel={handleCloseResetModal}
onOk={handleReset}> onOk={handleReset}>
{t('message.reset-layout-confirmation')} {modalDescription}
</Modal> </Modal>
)} )}
</Card> </Card>

View File

@ -12,7 +12,7 @@
*/ */
import { Col, Row } from 'antd'; import { Col, Row } from 'antd';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import React, { useEffect, useMemo } from 'react'; import React, { useCallback, useEffect, useMemo } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { FQN_SEPARATOR_CHAR } from '../../../../constants/char.constants'; import { FQN_SEPARATOR_CHAR } from '../../../../constants/char.constants';
import useCustomLocation from '../../../../hooks/useCustomLocation/useCustomLocation'; import useCustomLocation from '../../../../hooks/useCustomLocation/useCustomLocation';
@ -30,24 +30,29 @@ export const CustomizeUI = () => {
const history = useHistory(); const history = useHistory();
const location = useCustomLocation(); const location = useCustomLocation();
const { fqn: personaFQN } = useFqn(); const { fqn: personaFQN } = useFqn();
const activeCat = useMemo( const { activeCat, fullHash } = useMemo(() => {
() => (location.hash?.replace('#', '') || '').split('.')[1] ?? '', const activeCat =
[location] (location.hash?.replace('#', '') || '').split('.')[1] ?? '';
);
return { activeCat, fullHash: location.hash?.replace('#', '') };
}, [location.hash]);
const [items, setItems] = React.useState(categories); const [items, setItems] = React.useState(categories);
const handleCustomizeItemClick = (category: string) => { const handleCustomizeItemClick = useCallback(
const nestedItems = getCustomizePageOptions(category); (category: string) => {
const nestedItems = getCustomizePageOptions(category);
if (isEmpty(nestedItems)) { if (isEmpty(nestedItems)) {
history.push(getCustomizePagePath(personaFQN, category)); history.push(getCustomizePagePath(personaFQN, category));
} else { } else {
history.push({ history.push({
hash: location.hash + FQN_SEPARATOR_CHAR + category, hash: fullHash + FQN_SEPARATOR_CHAR + category,
}); });
} }
}; },
[history, fullHash, personaFQN]
);
useEffect(() => { useEffect(() => {
if (!activeCat) { if (!activeCat) {

View File

@ -30,7 +30,10 @@ const SettingItemCard = ({
className, className,
}: SettingMenuItemProps) => { }: SettingMenuItemProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const handleOnClick = useCallback(() => onClick(data.key), []); const handleOnClick = useCallback(
() => onClick(data.key),
[onClick, data.key]
);
return ( return (
<Card <Card

View File

@ -152,7 +152,7 @@ export const UserProfileIcon = () => {
inheritedRoles: currentUser?.inheritedRoles, inheritedRoles: currentUser?.inheritedRoles,
personas: currentUser?.personas, personas: currentUser?.personas,
}; };
}, [currentUser]); }, [currentUser, currentUser?.personas]);
const personaLabelRenderer = useCallback( const personaLabelRenderer = useCallback(
(item: EntityReference) => ( (item: EntityReference) => (

View File

@ -22,6 +22,7 @@ import React, {
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { BREADCRUMB_SEPARATOR } from '../../../constants/constants'; import { BREADCRUMB_SEPARATOR } from '../../../constants/constants';
import TitleBreadcrumbSkeleton from '../Skeleton/BreadCrumb/TitleBreadcrumbSkeleton.component'; import TitleBreadcrumbSkeleton from '../Skeleton/BreadCrumb/TitleBreadcrumbSkeleton.component';
import './title-breadcrumb.less';
import { TitleBreadcrumbProps, TitleLink } from './TitleBreadcrumb.interface'; import { TitleBreadcrumbProps, TitleLink } from './TitleBreadcrumb.interface';
const TitleBreadcrumb: FunctionComponent<TitleBreadcrumbProps> = ({ const TitleBreadcrumb: FunctionComponent<TitleBreadcrumbProps> = ({
@ -95,7 +96,9 @@ const TitleBreadcrumb: FunctionComponent<TitleBreadcrumbProps> = ({
return ( return (
<TitleBreadcrumbSkeleton loading={loading}> <TitleBreadcrumbSkeleton loading={loading}>
<nav className={className} data-testid="breadcrumb"> <nav
className={classNames('breadcrumb-container', className)}
data-testid="breadcrumb">
<ol className="rounded-4 text-sm font-regular d-flex flex-wrap"> <ol className="rounded-4 text-sm font-regular d-flex flex-wrap">
{titleLinks.map((link, index) => { {titleLinks.map((link, index) => {
const classes = const classes =

View File

@ -0,0 +1,20 @@
/*
* Copyright 2025 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.breadcrumb-container {
ol,
ul {
list-style: none;
padding: 0;
margin: 0;
}
}

View File

@ -43,7 +43,7 @@ export const useApplicationStore = create<ApplicationStore>()((set, get) => ({
jwtPrincipalClaimsMapping: [], jwtPrincipalClaimsMapping: [],
userProfilePics: {}, userProfilePics: {},
cachedEntityData: {}, cachedEntityData: {},
selectedPersona: {} as EntityReference, selectedPersona: undefined,
searchCriteria: '', searchCriteria: '',
inlineAlertDetails: undefined, inlineAlertDetails: undefined,
applications: [], applications: [],
@ -121,6 +121,20 @@ export const useApplicationStore = create<ApplicationStore>()((set, get) => ({
// This is a placeholder function that will be replaced by the actual function // This is a placeholder function that will be replaced by the actual function
}, },
updateCurrentUser: (user) => { updateCurrentUser: (user) => {
const { personas, defaultPersona } = user;
const { selectedPersona } = get();
// Update selected Persona to fetch the customized pages
if (defaultPersona && personas?.find((p) => p.id === defaultPersona.id)) {
set({ selectedPersona: defaultPersona });
}
// Update selected Persona if Persona is not in the list of personas
if (
selectedPersona &&
!personas?.find((p) => p.id === selectedPersona.id)
) {
set({ selectedPersona: undefined });
}
set({ currentUser: user }); set({ currentUser: user });
}, },
updateUserProfilePics: ({ id, user }: { id: string; user: User }) => { updateUserProfilePics: ({ id, user }: { id: string; user: User }) => {

View File

@ -25,7 +25,7 @@ export const useCustomPages = (pageType: PageType | 'Navigation') => {
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const fetchDocument = useCallback(async () => { const fetchDocument = useCallback(async () => {
const pageFQN = `${EntityType.PERSONA}${FQN_SEPARATOR_CHAR}${selectedPersona.fullyQualifiedName}`; const pageFQN = `${EntityType.PERSONA}${FQN_SEPARATOR_CHAR}${selectedPersona?.fullyQualifiedName}`;
try { try {
const doc = await getDocumentByFQN(pageFQN); const doc = await getDocumentByFQN(pageFQN);
setCustomizedPage( setCustomizedPage(
@ -37,7 +37,7 @@ export const useCustomPages = (pageType: PageType | 'Navigation') => {
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }
}, [selectedPersona.fullyQualifiedName, pageType]); }, [selectedPersona?.fullyQualifiedName, pageType]);
useEffect(() => { useEffect(() => {
if (selectedPersona?.fullyQualifiedName) { if (selectedPersona?.fullyQualifiedName) {

View File

@ -53,7 +53,7 @@ export interface ApplicationStore
setApplicationLoading: (loading: boolean) => void; setApplicationLoading: (loading: boolean) => void;
userProfilePics: Record<string, User>; userProfilePics: Record<string, User>;
cachedEntityData: Record<string, EntityUnion>; cachedEntityData: Record<string, EntityUnion>;
selectedPersona: EntityReference; selectedPersona?: EntityReference;
authConfig?: AuthenticationConfigurationWithScope; authConfig?: AuthenticationConfigurationWithScope;
applicationConfig?: UIThemePreference; applicationConfig?: UIThemePreference;
searchCriteria: ExploreSearchIndex | ''; searchCriteria: ExploreSearchIndex | '';

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "Wir können {{error}} Elasticsearch für Entität-Indizes nicht durchführen.", "unable-to-error-elasticsearch": "Wir können {{error}} Elasticsearch für Entität-Indizes nicht durchführen.",
"uninstall-app": "Durch die Deinstallation dieser {{app}}-Anwendung wird sie aus OpenMetadata entfernt.", "uninstall-app": "Durch die Deinstallation dieser {{app}}-Anwendung wird sie aus OpenMetadata entfernt.",
"unix-epoch-time-in-ms": "{{prefix}} Unix-Epochenzeit in Millisekunden.", "unix-epoch-time-in-ms": "{{prefix}} Unix-Epochenzeit in Millisekunden.",
"unsaved-changes-warning": "Sie haben möglicherweise ungespeicherte Änderungen, die beim Schließen verworfen werden.",
"update-description-message": "Anfrage zur Aktualisierung der Beschreibung für", "update-description-message": "Anfrage zur Aktualisierung der Beschreibung für",
"update-displayName-entity": "Aktualisieren Sie die Anzeigenamen für das {{entity}}.", "update-displayName-entity": "Aktualisieren Sie die Anzeigenamen für das {{entity}}.",
"update-profiler-settings": "Profiler Einstellungen updaten.", "update-profiler-settings": "Profiler Einstellungen updaten.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "We are unable to {{error}} Elasticsearch for entity indexes.", "unable-to-error-elasticsearch": "We are unable to {{error}} Elasticsearch for entity indexes.",
"uninstall-app": "Uninstalling this {{app}} application will remove it from OpenMetaData", "uninstall-app": "Uninstalling this {{app}} application will remove it from OpenMetaData",
"unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds", "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
"unsaved-changes-warning": "You may have unsaved changes which will be discarded upon close.",
"update-description-message": "Request to update description for", "update-description-message": "Request to update description for",
"update-displayName-entity": "Update Display Name for the {{entity}}.", "update-displayName-entity": "Update Display Name for the {{entity}}.",
"update-profiler-settings": "Update profiler setting.", "update-profiler-settings": "Update profiler setting.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "No podemos {{error}} Elasticsearch para los índices de entidades.", "unable-to-error-elasticsearch": "No podemos {{error}} Elasticsearch para los índices de entidades.",
"uninstall-app": "Desinstalar esta aplicación {{app}} la eliminará de OpenMetaData", "uninstall-app": "Desinstalar esta aplicación {{app}} la eliminará de OpenMetaData",
"unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds", "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
"unsaved-changes-warning": "Puede que tengas cambios no guardados que se descartarán al cerrar.",
"update-description-message": "Solicitud para actualizar la descripción de", "update-description-message": "Solicitud para actualizar la descripción de",
"update-displayName-entity": "Actualizar el nombre visualizado para el {{entity}}.", "update-displayName-entity": "Actualizar el nombre visualizado para el {{entity}}.",
"update-profiler-settings": "Actualizar la configuración del perfilador.", "update-profiler-settings": "Actualizar la configuración del perfilador.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "Nous ne sommes pas en mesure de {{error}} Elasticsearch pour les index d'entités.", "unable-to-error-elasticsearch": "Nous ne sommes pas en mesure de {{error}} Elasticsearch pour les index d'entités.",
"uninstall-app": "Désinstaller l'application {{app}} la retirera d'OpenMetaData", "uninstall-app": "Désinstaller l'application {{app}} la retirera d'OpenMetaData",
"unix-epoch-time-in-ms": "{{prefix}} temps Unix (epoch) en millisecondes", "unix-epoch-time-in-ms": "{{prefix}} temps Unix (epoch) en millisecondes",
"unsaved-changes-warning": "Vous pourriez avoir des modifications non enregistrées qui seront perdues à la fermeture.",
"update-description-message": "demander la mise à jour de la description pour", "update-description-message": "demander la mise à jour de la description pour",
"update-displayName-entity": "Mettre à Jour le Nom d'Affichage de {{entity}}.", "update-displayName-entity": "Mettre à Jour le Nom d'Affichage de {{entity}}.",
"update-profiler-settings": "Mettre à jour les réglages du profiler.", "update-profiler-settings": "Mettre à jour les réglages du profiler.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "Non podemos {{error}} Elasticsearch para os índices de entidade.", "unable-to-error-elasticsearch": "Non podemos {{error}} Elasticsearch para os índices de entidade.",
"uninstall-app": "Desinstalar esta aplicación {{app}} eliminaráa de OpenMetadata", "uninstall-app": "Desinstalar esta aplicación {{app}} eliminaráa de OpenMetadata",
"unix-epoch-time-in-ms": "{{prefix}} Tempo Unix epoch en milisegundos", "unix-epoch-time-in-ms": "{{prefix}} Tempo Unix epoch en milisegundos",
"unsaved-changes-warning": "Podes ter cambios non gardados que se descartarán ao pechar.",
"update-description-message": "Solicitude de actualización de descrición para", "update-description-message": "Solicitude de actualización de descrición para",
"update-displayName-entity": "Actualizar o Nome de Visualización para {{entity}}.", "update-displayName-entity": "Actualizar o Nome de Visualización para {{entity}}.",
"update-profiler-settings": "Actualizar a configuración do perfilador.", "update-profiler-settings": "Actualizar a configuración do perfilador.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "אנו לא יכולים ל{{error}} לאלסטיקסרץ' שלך עבור אינדקסים של ישויות.", "unable-to-error-elasticsearch": "אנו לא יכולים ל{{error}} לאלסטיקסרץ' שלך עבור אינדקסים של ישויות.",
"uninstall-app": "הסרת התקנת {{app}} תסיר אותו מ-OpenMetadata", "uninstall-app": "הסרת התקנת {{app}} תסיר אותו מ-OpenMetadata",
"unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds", "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
"unsaved-changes-warning": "ייתכן שיש לך שינויים שלא נשמרו שיימחקו בעת הסגירה.",
"update-description-message": "Request to update description for", "update-description-message": "Request to update description for",
"update-displayName-entity": "עדכן את השם המוצג עבור {{entity}}.", "update-displayName-entity": "עדכן את השם המוצג עבור {{entity}}.",
"update-profiler-settings": "עדכן הגדרות הפרופיילר.", "update-profiler-settings": "עדכן הגדרות הפרופיילר.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "We are unable to {{error}} Elasticsearch for entity indexes.", "unable-to-error-elasticsearch": "We are unable to {{error}} Elasticsearch for entity indexes.",
"uninstall-app": "Uninstalling this {{app}} application will remove it from OpenMetaData", "uninstall-app": "Uninstalling this {{app}} application will remove it from OpenMetaData",
"unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds", "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
"unsaved-changes-warning": "保存されていない変更があるかもしれません。閉じると破<E381A8><E7A0B4>されます。",
"update-description-message": "Request to update description for", "update-description-message": "Request to update description for",
"update-displayName-entity": "Update Display Name for the {{entity}}.", "update-displayName-entity": "Update Display Name for the {{entity}}.",
"update-profiler-settings": "Update profiler setting.", "update-profiler-settings": "Update profiler setting.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "엔터티 인덱스를 위해 Elasticsearch에서 {{error}}할 수 없습니다.", "unable-to-error-elasticsearch": "엔터티 인덱스를 위해 Elasticsearch에서 {{error}}할 수 없습니다.",
"uninstall-app": "이 {{app}} 애플리케이션을 제거하면 OpenMetadata에서 삭제됩니다.", "uninstall-app": "이 {{app}} 애플리케이션을 제거하면 OpenMetadata에서 삭제됩니다.",
"unix-epoch-time-in-ms": "{{prefix}} 밀리초 단위의 Unix 에포크 시간", "unix-epoch-time-in-ms": "{{prefix}} 밀리초 단위의 Unix 에포크 시간",
"unsaved-changes-warning": "저장되지 않은 변경 사항이 있을 수 있으며, <20><>으면 폐기됩니다.",
"update-description-message": "설명을 업데이트하라는 요청:", "update-description-message": "설명을 업데이트하라는 요청:",
"update-displayName-entity": "{{entity}}의 표시 이름을 업데이트하세요.", "update-displayName-entity": "{{entity}}의 표시 이름을 업데이트하세요.",
"update-profiler-settings": "프로파일러 설정을 업데이트하세요.", "update-profiler-settings": "프로파일러 설정을 업데이트하세요.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "आम्ही घटक अनुक्रमणिकांसाठी Elasticsearch {{error}} करण्यात अक्षम आहोत.", "unable-to-error-elasticsearch": "आम्ही घटक अनुक्रमणिकांसाठी Elasticsearch {{error}} करण्यात अक्षम आहोत.",
"uninstall-app": "हा {{app}} अनुप्रयोग अनइंस्टॉल केल्याने तो OpenMetaData मधून काढला जाईल", "uninstall-app": "हा {{app}} अनुप्रयोग अनइंस्टॉल केल्याने तो OpenMetaData मधून काढला जाईल",
"unix-epoch-time-in-ms": "{{prefix}} मिलीसेकंदात युनिक्स युग वेळ", "unix-epoch-time-in-ms": "{{prefix}} मिलीसेकंदात युनिक्स युग वेळ",
"unsaved-changes-warning": "तुमच्याकडे जतन न केलेले बदल असू शकतात जे बंद केल्यावर रद्द केले जातील.",
"update-description-message": "साठी वर्णन अद्यतनित करण्याची विनंती", "update-description-message": "साठी वर्णन अद्यतनित करण्याची विनंती",
"update-displayName-entity": "{{entity}} साठी प्रदर्शन नाव अद्यतनित करा.", "update-displayName-entity": "{{entity}} साठी प्रदर्शन नाव अद्यतनित करा.",
"update-profiler-settings": "प्रोफाइलर सेटिंग अद्यतनित करा.", "update-profiler-settings": "प्रोफाइलर सेटिंग अद्यतनित करा.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "We kunnen geen connectie maken met Elasticsearch voor entiteitsindexen.", "unable-to-error-elasticsearch": "We kunnen geen connectie maken met Elasticsearch voor entiteitsindexen.",
"uninstall-app": "Het verwijderen van deze {{app}}-toepassing verwijdert deze uit OpenMetaData", "uninstall-app": "Het verwijderen van deze {{app}}-toepassing verwijdert deze uit OpenMetaData",
"unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds", "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
"unsaved-changes-warning": "Je hebt mogelijk niet-opgeslagen wijzigingen die worden verwijderd bij het sluiten.",
"update-description-message": "Verzoek om de beschrijving aan te passen voor", "update-description-message": "Verzoek om de beschrijving aan te passen voor",
"update-displayName-entity": "Update de weergavenaam voor de {{entity}}.", "update-displayName-entity": "Update de weergavenaam voor de {{entity}}.",
"update-profiler-settings": "Profielinstellingen updaten.", "update-profiler-settings": "Profielinstellingen updaten.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "ما نمی‌توانیم به Elasticsearch برای ایندکس‌های موجودیت {{error}} دسترسی پیدا کنیم.", "unable-to-error-elasticsearch": "ما نمی‌توانیم به Elasticsearch برای ایندکس‌های موجودیت {{error}} دسترسی پیدا کنیم.",
"uninstall-app": "حذف این برنامه {{app}} آن را از OpenMetaData حذف خواهد کرد.", "uninstall-app": "حذف این برنامه {{app}} آن را از OpenMetaData حذف خواهد کرد.",
"unix-epoch-time-in-ms": "{{prefix}} زمان Unix epoch به میلی‌ثانیه", "unix-epoch-time-in-ms": "{{prefix}} زمان Unix epoch به میلی‌ثانیه",
"unsaved-changes-warning": "ممکن است تغییرات ذخیره نشده‌ای داشته باشید که با بستن از بین خواهند رفت.",
"update-description-message": "درخواست برای به‌روزرسانی توضیحات برای", "update-description-message": "درخواست برای به‌روزرسانی توضیحات برای",
"update-displayName-entity": "به‌روزرسانی نام نمایشی برای {{entity}}.", "update-displayName-entity": "به‌روزرسانی نام نمایشی برای {{entity}}.",
"update-profiler-settings": "به‌روزرسانی تنظیمات پروفایلر.", "update-profiler-settings": "به‌روزرسانی تنظیمات پروفایلر.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "Não é possível {{error}} Elasticsearch para índices de entidade.", "unable-to-error-elasticsearch": "Não é possível {{error}} Elasticsearch para índices de entidade.",
"uninstall-app": "Desinstalar este aplicativo {{app}} removerá ele do OpenMetaData", "uninstall-app": "Desinstalar este aplicativo {{app}} removerá ele do OpenMetaData",
"unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds", "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
"unsaved-changes-warning": "Você pode ter alterações não salvas que serão descartadas ao fechar.",
"update-description-message": "Solicitar atualização de descrição para", "update-description-message": "Solicitar atualização de descrição para",
"update-displayName-entity": "Atualizar o Nome de Exibição para {{entity}}.", "update-displayName-entity": "Atualizar o Nome de Exibição para {{entity}}.",
"update-profiler-settings": "Atualizar configurações do examinador.", "update-profiler-settings": "Atualizar configurações do examinador.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "Não é possível {{error}} Elasticsearch para índices de entidade.", "unable-to-error-elasticsearch": "Não é possível {{error}} Elasticsearch para índices de entidade.",
"uninstall-app": "Desinstalar este aplicativo {{app}} removerá ele do OpenMetaData", "uninstall-app": "Desinstalar este aplicativo {{app}} removerá ele do OpenMetaData",
"unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds", "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
"unsaved-changes-warning": "Você pode ter alterações não salvas que serão descartadas ao fechar.",
"update-description-message": "Solicitar atualização de descrição para", "update-description-message": "Solicitar atualização de descrição para",
"update-displayName-entity": "Atualizar o Nome de Exibição para {{entity}}.", "update-displayName-entity": "Atualizar o Nome de Exibição para {{entity}}.",
"update-profiler-settings": "Atualizar configurações do examinador.", "update-profiler-settings": "Atualizar configurações do examinador.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "Мы не можем выполнить {{error}} Elasticsearch для индексов сущностей.", "unable-to-error-elasticsearch": "Мы не можем выполнить {{error}} Elasticsearch для индексов сущностей.",
"uninstall-app": "Uninstalling this {{app}} application will remove it from OpenMetaData", "uninstall-app": "Uninstalling this {{app}} application will remove it from OpenMetaData",
"unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds", "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
"unsaved-changes-warning": "У вас могут быть несохраненные изменения, которые будут потеряны при закрытии.",
"update-description-message": "Request to update description for", "update-description-message": "Request to update description for",
"update-displayName-entity": "Обновите отображаемое имя для {{entity}}.", "update-displayName-entity": "Обновите отображаемое имя для {{entity}}.",
"update-profiler-settings": "Update profiler setting.", "update-profiler-settings": "Update profiler setting.",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "เราไม่สามารถ {{error}} Elasticsearch สำหรับดัชนีเอนทิตีได้", "unable-to-error-elasticsearch": "เราไม่สามารถ {{error}} Elasticsearch สำหรับดัชนีเอนทิตีได้",
"uninstall-app": "การถอนการติดตั้งแอปพลิเคชัน {{app}} นี้จะลบออกจาก OpenMetaData", "uninstall-app": "การถอนการติดตั้งแอปพลิเคชัน {{app}} นี้จะลบออกจาก OpenMetaData",
"unix-epoch-time-in-ms": "{{prefix}} เวลายุค Unix ในมิลลิวินาที", "unix-epoch-time-in-ms": "{{prefix}} เวลายุค Unix ในมิลลิวินาที",
"unsaved-changes-warning": "คุณอาจมีการเปลี่ยนแปลงที่ยังไม่ได้บันทึกซึ่งจะถูกยกเลิกเมื่อปิด",
"update-description-message": "คำขอเพื่ออัปเดตคำอธิบายสำหรับ", "update-description-message": "คำขอเพื่ออัปเดตคำอธิบายสำหรับ",
"update-displayName-entity": "อัปเดตชื่อแสดงสำหรับ {{entity}}", "update-displayName-entity": "อัปเดตชื่อแสดงสำหรับ {{entity}}",
"update-profiler-settings": "อัปเดตการตั้งค่าโปรไฟล์เลอร์", "update-profiler-settings": "อัปเดตการตั้งค่าโปรไฟล์เลอร์",

View File

@ -2129,6 +2129,7 @@
"unable-to-error-elasticsearch": "无法为 Elasticsearch 进行实体索引{{error}}", "unable-to-error-elasticsearch": "无法为 Elasticsearch 进行实体索引{{error}}",
"uninstall-app": "卸载此 {{app}} 应用会将其从 OpenMetaData 中移除", "uninstall-app": "卸载此 {{app}} 应用会将其从 OpenMetaData 中移除",
"unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds", "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
"unsaved-changes-warning": "您可能有未保存的更改关闭时将被<E5B086><E8A2AB>弃。",
"update-description-message": "Request to update description for", "update-description-message": "Request to update description for",
"update-displayName-entity": "更改{{entity}}的显示名", "update-displayName-entity": "更改{{entity}}的显示名",
"update-profiler-settings": "更新分析器设置", "update-profiler-settings": "更新分析器设置",

View File

@ -73,7 +73,7 @@ const MyDataPage = () => {
const fetchDocument = async () => { const fetchDocument = async () => {
try { try {
setIsLoading(true); setIsLoading(true);
if (!isEmpty(selectedPersona)) { if (selectedPersona) {
const pageFQN = `${EntityType.PERSONA}.${selectedPersona.fullyQualifiedName}`; const pageFQN = `${EntityType.PERSONA}.${selectedPersona.fullyQualifiedName}`;
const docData = await getDocumentByFQN(pageFQN); const docData = await getDocumentByFQN(pageFQN);

View File

@ -68,7 +68,7 @@ jest.mock(
} }
); );
let mockSelectedPersona: Record<string, string> = { let mockSelectedPersona: Record<string, string> | null = {
fullyQualifiedName: mockPersonaName, fullyQualifiedName: mockPersonaName,
}; };
@ -262,7 +262,7 @@ describe('MyDataPage component', () => {
}); });
it('MyDataPage should render default widgets when there is no selected persona', async () => { it('MyDataPage should render default widgets when there is no selected persona', async () => {
mockSelectedPersona = {}; mockSelectedPersona = null;
await act(async () => { await act(async () => {
render(<MyDataPage />); render(<MyDataPage />);
}); });

View File

@ -54,10 +54,16 @@ export const PersonaDetailsPage = () => {
DEFAULT_ENTITY_PERMISSION DEFAULT_ENTITY_PERMISSION
); );
const location = useCustomLocation(); const location = useCustomLocation();
const activeKey = useMemo( const { activeKey, fullHash } = useMemo(() => {
() => (location.hash?.replace('#', '') || 'users').split('.')[0], const activeKey = (location.hash?.replace('#', '') || 'users').split(
[location] '.'
); )[0];
return {
activeKey,
fullHash: location.hash?.replace('#', ''),
};
}, [location.hash]);
const { getEntityPermissionByFqn } = usePermissionProvider(); const { getEntityPermissionByFqn } = usePermissionProvider();
@ -161,11 +167,18 @@ export const PersonaDetailsPage = () => {
history.push(getSettingPath(GlobalSettingsMenuCategory.PERSONA)); history.push(getSettingPath(GlobalSettingsMenuCategory.PERSONA));
}; };
const handleTabChange = (activeKey: string) => { const handleTabClick = useCallback(
history.push({ (key: string) => {
hash: activeKey, if (fullHash === key) {
}); return;
}; }
history.push({
hash: key,
});
},
[history, fullHash]
);
const tabItems = useMemo(() => { const tabItems = useMemo(() => {
return [ return [
@ -264,7 +277,7 @@ export const PersonaDetailsPage = () => {
</UserSelectableList> </UserSelectableList>
) )
} }
onChange={handleTabChange} onTabClick={handleTabClick}
/> />
</Col> </Col>
</Row> </Row>