mirror of
				https://github.com/open-metadata/OpenMetadata.git
				synced 2025-11-03 20:19:31 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									8e8cc3c614
								
							
						
					
					
						commit
						6495c0f0f2
					
				@ -32,10 +32,6 @@
 | 
			
		||||
    margin-bottom: 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .service-icon {
 | 
			
		||||
    height: 16px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .entity-summary-details {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,20 +35,42 @@ export const CustomizablePageHeader = ({
 | 
			
		||||
  const { fqn: personaFqn } = useFqn();
 | 
			
		||||
  const { currentPageType } = useCustomizeStore();
 | 
			
		||||
  const history = useHistory();
 | 
			
		||||
  const [isResetModalOpen, setIsResetModalOpen] = 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 = () => {
 | 
			
		||||
    // Go back in history
 | 
			
		||||
    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(() => {
 | 
			
		||||
    setIsResetModalOpen(true);
 | 
			
		||||
    setConfirmationModalType('reset');
 | 
			
		||||
    setConfirmationModalOpen(true);
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  const handleCloseResetModal = useCallback(() => {
 | 
			
		||||
    setIsResetModalOpen(false);
 | 
			
		||||
    setConfirmationModalOpen(false);
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  const handleSave = useCallback(async () => {
 | 
			
		||||
@ -58,9 +80,10 @@ export const CustomizablePageHeader = ({
 | 
			
		||||
  }, [onSave]);
 | 
			
		||||
 | 
			
		||||
  const handleReset = useCallback(async () => {
 | 
			
		||||
    onReset();
 | 
			
		||||
    setIsResetModalOpen(false);
 | 
			
		||||
  }, [onReset]);
 | 
			
		||||
    confirmationModalType === 'reset' ? onReset() : handleCancel();
 | 
			
		||||
    setConfirmationModalOpen(false);
 | 
			
		||||
  }, [onReset, confirmationModalType, handleCancel]);
 | 
			
		||||
 | 
			
		||||
  const i18Values = useMemo(
 | 
			
		||||
    () => ({
 | 
			
		||||
      persona: personaName,
 | 
			
		||||
@ -72,6 +95,11 @@ export const CustomizablePageHeader = ({
 | 
			
		||||
    [personaName]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const handleClose = useCallback(() => {
 | 
			
		||||
    setConfirmationModalType('close');
 | 
			
		||||
    setConfirmationModalOpen(true);
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Card
 | 
			
		||||
      className="customize-page-header"
 | 
			
		||||
@ -99,8 +127,8 @@ export const CustomizablePageHeader = ({
 | 
			
		||||
            data-testid="cancel-button"
 | 
			
		||||
            disabled={saving}
 | 
			
		||||
            icon={<CloseOutlined />}
 | 
			
		||||
            onClick={handleCancel}>
 | 
			
		||||
            {t('label.cancel')}
 | 
			
		||||
            onClick={handleClose}>
 | 
			
		||||
            {t('label.close')}
 | 
			
		||||
          </Button>
 | 
			
		||||
          <Button
 | 
			
		||||
            data-testid="reset-button"
 | 
			
		||||
@ -119,17 +147,18 @@ export const CustomizablePageHeader = ({
 | 
			
		||||
          </Button>
 | 
			
		||||
        </Space>
 | 
			
		||||
      </div>
 | 
			
		||||
      {isResetModalOpen && (
 | 
			
		||||
 | 
			
		||||
      {confirmationModalOpen && (
 | 
			
		||||
        <Modal
 | 
			
		||||
          centered
 | 
			
		||||
          cancelText={t('label.no')}
 | 
			
		||||
          data-testid="reset-layout-modal"
 | 
			
		||||
          okText={t('label.yes')}
 | 
			
		||||
          open={isResetModalOpen}
 | 
			
		||||
          title={t('label.reset-default-layout')}
 | 
			
		||||
          open={confirmationModalOpen}
 | 
			
		||||
          title={modalTitle}
 | 
			
		||||
          onCancel={handleCloseResetModal}
 | 
			
		||||
          onOk={handleReset}>
 | 
			
		||||
          {t('message.reset-layout-confirmation')}
 | 
			
		||||
          {modalDescription}
 | 
			
		||||
        </Modal>
 | 
			
		||||
      )}
 | 
			
		||||
    </Card>
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@
 | 
			
		||||
 */
 | 
			
		||||
import { Col, Row } from 'antd';
 | 
			
		||||
import { isEmpty } from 'lodash';
 | 
			
		||||
import React, { useEffect, useMemo } from 'react';
 | 
			
		||||
import React, { useCallback, useEffect, useMemo } from 'react';
 | 
			
		||||
import { useHistory } from 'react-router-dom';
 | 
			
		||||
import { FQN_SEPARATOR_CHAR } from '../../../../constants/char.constants';
 | 
			
		||||
import useCustomLocation from '../../../../hooks/useCustomLocation/useCustomLocation';
 | 
			
		||||
@ -30,24 +30,29 @@ export const CustomizeUI = () => {
 | 
			
		||||
  const history = useHistory();
 | 
			
		||||
  const location = useCustomLocation();
 | 
			
		||||
  const { fqn: personaFQN } = useFqn();
 | 
			
		||||
  const activeCat = useMemo(
 | 
			
		||||
    () => (location.hash?.replace('#', '') || '').split('.')[1] ?? '',
 | 
			
		||||
    [location]
 | 
			
		||||
  );
 | 
			
		||||
  const { activeCat, fullHash } = useMemo(() => {
 | 
			
		||||
    const activeCat =
 | 
			
		||||
      (location.hash?.replace('#', '') || '').split('.')[1] ?? '';
 | 
			
		||||
 | 
			
		||||
    return { activeCat, fullHash: location.hash?.replace('#', '') };
 | 
			
		||||
  }, [location.hash]);
 | 
			
		||||
 | 
			
		||||
  const [items, setItems] = React.useState(categories);
 | 
			
		||||
 | 
			
		||||
  const handleCustomizeItemClick = (category: string) => {
 | 
			
		||||
    const nestedItems = getCustomizePageOptions(category);
 | 
			
		||||
  const handleCustomizeItemClick = useCallback(
 | 
			
		||||
    (category: string) => {
 | 
			
		||||
      const nestedItems = getCustomizePageOptions(category);
 | 
			
		||||
 | 
			
		||||
    if (isEmpty(nestedItems)) {
 | 
			
		||||
      history.push(getCustomizePagePath(personaFQN, category));
 | 
			
		||||
    } else {
 | 
			
		||||
      history.push({
 | 
			
		||||
        hash: location.hash + FQN_SEPARATOR_CHAR + category,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
      if (isEmpty(nestedItems)) {
 | 
			
		||||
        history.push(getCustomizePagePath(personaFQN, category));
 | 
			
		||||
      } else {
 | 
			
		||||
        history.push({
 | 
			
		||||
          hash: fullHash + FQN_SEPARATOR_CHAR + category,
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    [history, fullHash, personaFQN]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (!activeCat) {
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,10 @@ const SettingItemCard = ({
 | 
			
		||||
  className,
 | 
			
		||||
}: SettingMenuItemProps) => {
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  const handleOnClick = useCallback(() => onClick(data.key), []);
 | 
			
		||||
  const handleOnClick = useCallback(
 | 
			
		||||
    () => onClick(data.key),
 | 
			
		||||
    [onClick, data.key]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Card
 | 
			
		||||
 | 
			
		||||
@ -152,7 +152,7 @@ export const UserProfileIcon = () => {
 | 
			
		||||
      inheritedRoles: currentUser?.inheritedRoles,
 | 
			
		||||
      personas: currentUser?.personas,
 | 
			
		||||
    };
 | 
			
		||||
  }, [currentUser]);
 | 
			
		||||
  }, [currentUser, currentUser?.personas]);
 | 
			
		||||
 | 
			
		||||
  const personaLabelRenderer = useCallback(
 | 
			
		||||
    (item: EntityReference) => (
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@ import React, {
 | 
			
		||||
import { Link } from 'react-router-dom';
 | 
			
		||||
import { BREADCRUMB_SEPARATOR } from '../../../constants/constants';
 | 
			
		||||
import TitleBreadcrumbSkeleton from '../Skeleton/BreadCrumb/TitleBreadcrumbSkeleton.component';
 | 
			
		||||
import './title-breadcrumb.less';
 | 
			
		||||
import { TitleBreadcrumbProps, TitleLink } from './TitleBreadcrumb.interface';
 | 
			
		||||
 | 
			
		||||
const TitleBreadcrumb: FunctionComponent<TitleBreadcrumbProps> = ({
 | 
			
		||||
@ -95,7 +96,9 @@ const TitleBreadcrumb: FunctionComponent<TitleBreadcrumbProps> = ({
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <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">
 | 
			
		||||
          {titleLinks.map((link, index) => {
 | 
			
		||||
            const classes =
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -43,7 +43,7 @@ export const useApplicationStore = create<ApplicationStore>()((set, get) => ({
 | 
			
		||||
  jwtPrincipalClaimsMapping: [],
 | 
			
		||||
  userProfilePics: {},
 | 
			
		||||
  cachedEntityData: {},
 | 
			
		||||
  selectedPersona: {} as EntityReference,
 | 
			
		||||
  selectedPersona: undefined,
 | 
			
		||||
  searchCriteria: '',
 | 
			
		||||
  inlineAlertDetails: undefined,
 | 
			
		||||
  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
 | 
			
		||||
  },
 | 
			
		||||
  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 });
 | 
			
		||||
  },
 | 
			
		||||
  updateUserProfilePics: ({ id, user }: { id: string; user: User }) => {
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@ export const useCustomPages = (pageType: PageType | 'Navigation') => {
 | 
			
		||||
  const [isLoading, setIsLoading] = useState(true);
 | 
			
		||||
 | 
			
		||||
  const fetchDocument = useCallback(async () => {
 | 
			
		||||
    const pageFQN = `${EntityType.PERSONA}${FQN_SEPARATOR_CHAR}${selectedPersona.fullyQualifiedName}`;
 | 
			
		||||
    const pageFQN = `${EntityType.PERSONA}${FQN_SEPARATOR_CHAR}${selectedPersona?.fullyQualifiedName}`;
 | 
			
		||||
    try {
 | 
			
		||||
      const doc = await getDocumentByFQN(pageFQN);
 | 
			
		||||
      setCustomizedPage(
 | 
			
		||||
@ -37,7 +37,7 @@ export const useCustomPages = (pageType: PageType | 'Navigation') => {
 | 
			
		||||
    } finally {
 | 
			
		||||
      setIsLoading(false);
 | 
			
		||||
    }
 | 
			
		||||
  }, [selectedPersona.fullyQualifiedName, pageType]);
 | 
			
		||||
  }, [selectedPersona?.fullyQualifiedName, pageType]);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (selectedPersona?.fullyQualifiedName) {
 | 
			
		||||
 | 
			
		||||
@ -53,7 +53,7 @@ export interface ApplicationStore
 | 
			
		||||
  setApplicationLoading: (loading: boolean) => void;
 | 
			
		||||
  userProfilePics: Record<string, User>;
 | 
			
		||||
  cachedEntityData: Record<string, EntityUnion>;
 | 
			
		||||
  selectedPersona: EntityReference;
 | 
			
		||||
  selectedPersona?: EntityReference;
 | 
			
		||||
  authConfig?: AuthenticationConfigurationWithScope;
 | 
			
		||||
  applicationConfig?: UIThemePreference;
 | 
			
		||||
  searchCriteria: ExploreSearchIndex | '';
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "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.",
 | 
			
		||||
    "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-displayName-entity": "Aktualisieren Sie die Anzeigenamen für das {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "Profiler Einstellungen updaten.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "We are unable to {{error}} Elasticsearch for entity indexes.",
 | 
			
		||||
    "uninstall-app": "Uninstalling this {{app}} application will remove it from OpenMetaData",
 | 
			
		||||
    "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-displayName-entity": "Update Display Name for the {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "Update profiler setting.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "No podemos {{error}} Elasticsearch para los índices de entidades.",
 | 
			
		||||
    "uninstall-app": "Desinstalar esta aplicación {{app}} la eliminará de OpenMetaData",
 | 
			
		||||
    "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-displayName-entity": "Actualizar el nombre visualizado para el {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "Actualizar la configuración del perfilador.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "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",
 | 
			
		||||
    "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-displayName-entity": "Mettre à Jour le Nom d'Affichage de {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "Mettre à jour les réglages du profiler.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "Non podemos {{error}} Elasticsearch para os índices de entidade.",
 | 
			
		||||
    "uninstall-app": "Desinstalar esta aplicación {{app}} eliminaráa de OpenMetadata",
 | 
			
		||||
    "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-displayName-entity": "Actualizar o Nome de Visualización para {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "Actualizar a configuración do perfilador.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "אנו לא יכולים ל{{error}} לאלסטיקסרץ' שלך עבור אינדקסים של ישויות.",
 | 
			
		||||
    "uninstall-app": "הסרת התקנת {{app}} תסיר אותו מ-OpenMetadata",
 | 
			
		||||
    "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
 | 
			
		||||
    "unsaved-changes-warning": "ייתכן שיש לך שינויים שלא נשמרו שיימחקו בעת הסגירה.",
 | 
			
		||||
    "update-description-message": "Request to update description for",
 | 
			
		||||
    "update-displayName-entity": "עדכן את השם המוצג עבור {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "עדכן הגדרות הפרופיילר.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "We are unable to {{error}} Elasticsearch for entity indexes.",
 | 
			
		||||
    "uninstall-app": "Uninstalling this {{app}} application will remove it from OpenMetaData",
 | 
			
		||||
    "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-displayName-entity": "Update Display Name for the {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "Update profiler setting.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "엔터티 인덱스를 위해 Elasticsearch에서 {{error}}할 수 없습니다.",
 | 
			
		||||
    "uninstall-app": "이 {{app}} 애플리케이션을 제거하면 OpenMetadata에서 삭제됩니다.",
 | 
			
		||||
    "unix-epoch-time-in-ms": "{{prefix}} 밀리초 단위의 Unix 에포크 시간",
 | 
			
		||||
    "unsaved-changes-warning": "저장되지 않은 변경 사항이 있을 수 있으며, <20><>으면 폐기됩니다.",
 | 
			
		||||
    "update-description-message": "설명을 업데이트하라는 요청:",
 | 
			
		||||
    "update-displayName-entity": "{{entity}}의 표시 이름을 업데이트하세요.",
 | 
			
		||||
    "update-profiler-settings": "프로파일러 설정을 업데이트하세요.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "आम्ही घटक अनुक्रमणिकांसाठी Elasticsearch {{error}} करण्यात अक्षम आहोत.",
 | 
			
		||||
    "uninstall-app": "हा {{app}} अनुप्रयोग अनइंस्टॉल केल्याने तो OpenMetaData मधून काढला जाईल",
 | 
			
		||||
    "unix-epoch-time-in-ms": "{{prefix}} मिलीसेकंदात युनिक्स युग वेळ",
 | 
			
		||||
    "unsaved-changes-warning": "तुमच्याकडे जतन न केलेले बदल असू शकतात जे बंद केल्यावर रद्द केले जातील.",
 | 
			
		||||
    "update-description-message": "साठी वर्णन अद्यतनित करण्याची विनंती",
 | 
			
		||||
    "update-displayName-entity": "{{entity}} साठी प्रदर्शन नाव अद्यतनित करा.",
 | 
			
		||||
    "update-profiler-settings": "प्रोफाइलर सेटिंग अद्यतनित करा.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "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",
 | 
			
		||||
    "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-displayName-entity": "Update de weergavenaam voor de {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "Profielinstellingen updaten.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "ما نمیتوانیم به Elasticsearch برای ایندکسهای موجودیت {{error}} دسترسی پیدا کنیم.",
 | 
			
		||||
    "uninstall-app": "حذف این برنامه {{app}} آن را از OpenMetaData حذف خواهد کرد.",
 | 
			
		||||
    "unix-epoch-time-in-ms": "{{prefix}} زمان Unix epoch به میلیثانیه",
 | 
			
		||||
    "unsaved-changes-warning": "ممکن است تغییرات ذخیره نشدهای داشته باشید که با بستن از بین خواهند رفت.",
 | 
			
		||||
    "update-description-message": "درخواست برای بهروزرسانی توضیحات برای",
 | 
			
		||||
    "update-displayName-entity": "بهروزرسانی نام نمایشی برای {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "بهروزرسانی تنظیمات پروفایلر.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "Não é possível {{error}} Elasticsearch para índices de entidade.",
 | 
			
		||||
    "uninstall-app": "Desinstalar este aplicativo {{app}} removerá ele do OpenMetaData",
 | 
			
		||||
    "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-displayName-entity": "Atualizar o Nome de Exibição para {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "Atualizar configurações do examinador.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "Não é possível {{error}} Elasticsearch para índices de entidade.",
 | 
			
		||||
    "uninstall-app": "Desinstalar este aplicativo {{app}} removerá ele do OpenMetaData",
 | 
			
		||||
    "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-displayName-entity": "Atualizar o Nome de Exibição para {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "Atualizar configurações do examinador.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "Мы не можем выполнить {{error}} Elasticsearch для индексов сущностей.",
 | 
			
		||||
    "uninstall-app": "Uninstalling this {{app}} application will remove it from OpenMetaData",
 | 
			
		||||
    "unix-epoch-time-in-ms": "{{prefix}} Unix epoch time in milliseconds",
 | 
			
		||||
    "unsaved-changes-warning": "У вас могут быть несохраненные изменения, которые будут потеряны при закрытии.",
 | 
			
		||||
    "update-description-message": "Request to update description for",
 | 
			
		||||
    "update-displayName-entity": "Обновите отображаемое имя для {{entity}}.",
 | 
			
		||||
    "update-profiler-settings": "Update profiler setting.",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "เราไม่สามารถ {{error}} Elasticsearch สำหรับดัชนีเอนทิตีได้",
 | 
			
		||||
    "uninstall-app": "การถอนการติดตั้งแอปพลิเคชัน {{app}} นี้จะลบออกจาก OpenMetaData",
 | 
			
		||||
    "unix-epoch-time-in-ms": "{{prefix}} เวลายุค Unix ในมิลลิวินาที",
 | 
			
		||||
    "unsaved-changes-warning": "คุณอาจมีการเปลี่ยนแปลงที่ยังไม่ได้บันทึกซึ่งจะถูกยกเลิกเมื่อปิด",
 | 
			
		||||
    "update-description-message": "คำขอเพื่ออัปเดตคำอธิบายสำหรับ",
 | 
			
		||||
    "update-displayName-entity": "อัปเดตชื่อแสดงสำหรับ {{entity}}",
 | 
			
		||||
    "update-profiler-settings": "อัปเดตการตั้งค่าโปรไฟล์เลอร์",
 | 
			
		||||
 | 
			
		||||
@ -2129,6 +2129,7 @@
 | 
			
		||||
    "unable-to-error-elasticsearch": "无法为 Elasticsearch 进行实体索引{{error}}",
 | 
			
		||||
    "uninstall-app": "卸载此 {{app}} 应用会将其从 OpenMetaData 中移除",
 | 
			
		||||
    "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-displayName-entity": "更改{{entity}}的显示名",
 | 
			
		||||
    "update-profiler-settings": "更新分析器设置",
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ const MyDataPage = () => {
 | 
			
		||||
  const fetchDocument = async () => {
 | 
			
		||||
    try {
 | 
			
		||||
      setIsLoading(true);
 | 
			
		||||
      if (!isEmpty(selectedPersona)) {
 | 
			
		||||
      if (selectedPersona) {
 | 
			
		||||
        const pageFQN = `${EntityType.PERSONA}.${selectedPersona.fullyQualifiedName}`;
 | 
			
		||||
        const docData = await getDocumentByFQN(pageFQN);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -68,7 +68,7 @@ jest.mock(
 | 
			
		||||
  }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
let mockSelectedPersona: Record<string, string> = {
 | 
			
		||||
let mockSelectedPersona: Record<string, string> | null = {
 | 
			
		||||
  fullyQualifiedName: mockPersonaName,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -262,7 +262,7 @@ describe('MyDataPage component', () => {
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('MyDataPage should render default widgets when there is no selected persona', async () => {
 | 
			
		||||
    mockSelectedPersona = {};
 | 
			
		||||
    mockSelectedPersona = null;
 | 
			
		||||
    await act(async () => {
 | 
			
		||||
      render(<MyDataPage />);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@ -54,10 +54,16 @@ export const PersonaDetailsPage = () => {
 | 
			
		||||
    DEFAULT_ENTITY_PERMISSION
 | 
			
		||||
  );
 | 
			
		||||
  const location = useCustomLocation();
 | 
			
		||||
  const activeKey = useMemo(
 | 
			
		||||
    () => (location.hash?.replace('#', '') || 'users').split('.')[0],
 | 
			
		||||
    [location]
 | 
			
		||||
  );
 | 
			
		||||
  const { activeKey, fullHash } = useMemo(() => {
 | 
			
		||||
    const activeKey = (location.hash?.replace('#', '') || 'users').split(
 | 
			
		||||
      '.'
 | 
			
		||||
    )[0];
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      activeKey,
 | 
			
		||||
      fullHash: location.hash?.replace('#', ''),
 | 
			
		||||
    };
 | 
			
		||||
  }, [location.hash]);
 | 
			
		||||
 | 
			
		||||
  const { getEntityPermissionByFqn } = usePermissionProvider();
 | 
			
		||||
 | 
			
		||||
@ -161,11 +167,18 @@ export const PersonaDetailsPage = () => {
 | 
			
		||||
    history.push(getSettingPath(GlobalSettingsMenuCategory.PERSONA));
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const handleTabChange = (activeKey: string) => {
 | 
			
		||||
    history.push({
 | 
			
		||||
      hash: activeKey,
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
  const handleTabClick = useCallback(
 | 
			
		||||
    (key: string) => {
 | 
			
		||||
      if (fullHash === key) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      history.push({
 | 
			
		||||
        hash: key,
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
    [history, fullHash]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const tabItems = useMemo(() => {
 | 
			
		||||
    return [
 | 
			
		||||
@ -264,7 +277,7 @@ export const PersonaDetailsPage = () => {
 | 
			
		||||
                </UserSelectableList>
 | 
			
		||||
              )
 | 
			
		||||
            }
 | 
			
		||||
            onChange={handleTabChange}
 | 
			
		||||
            onTabClick={handleTabClick}
 | 
			
		||||
          />
 | 
			
		||||
        </Col>
 | 
			
		||||
      </Row>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user