diff --git a/datahub-web-react/src/App.tsx b/datahub-web-react/src/App.tsx index 7ea96f9ec1..153f6ab6ba 100644 --- a/datahub-web-react/src/App.tsx +++ b/datahub-web-react/src/App.tsx @@ -61,7 +61,19 @@ const errorLink = onError((error) => { const client = new ApolloClient({ connectToDevTools: true, link: errorLink.concat(httpLink), - cache: new InMemoryCache(), + cache: new InMemoryCache({ + typePolicies: { + Query: { + fields: { + dataset: { + merge: (oldObj, newObj) => { + return { ...oldObj, ...newObj }; + }, + }, + }, + }, + }, + }), credentials: 'include', defaultOptions: { watchQuery: { diff --git a/datahub-web-react/src/app/analytics/event.ts b/datahub-web-react/src/app/analytics/event.ts index 9ff9fb905e..a0ef6250f1 100644 --- a/datahub-web-react/src/app/analytics/event.ts +++ b/datahub-web-react/src/app/analytics/event.ts @@ -233,7 +233,6 @@ export interface BatchEntityActionEvent extends BaseEvent { export interface RecommendationImpressionEvent extends BaseEvent { type: EventType.RecommendationImpressionEvent; - renderId: string; // TODO : Determine whether we need a render id to join with click event. moduleId: string; renderType: RecommendationRenderType; scenarioType: ScenarioType; diff --git a/datahub-web-react/src/app/analyticsDashboard/components/AnalyticsPage.tsx b/datahub-web-react/src/app/analyticsDashboard/components/AnalyticsPage.tsx index 440d16f518..bf0e5af242 100644 --- a/datahub-web-react/src/app/analyticsDashboard/components/AnalyticsPage.tsx +++ b/datahub-web-react/src/app/analyticsDashboard/components/AnalyticsPage.tsx @@ -10,7 +10,7 @@ import { Message } from '../../shared/Message'; import { useListDomainsQuery } from '../../../graphql/domain.generated'; import filterSearchQuery from '../../search/utils/filterSearchQuery'; import { ANTD_GRAY } from '../../entity/shared/constants'; -import { useGetAuthenticatedUser } from '../../useGetAuthenticatedUser'; +import { useUserContext } from '../../context/useUserContext'; const HighlightGroup = styled.div` display: flex; @@ -47,7 +47,7 @@ const StyledSearchBar = styled(Input)` `; export const AnalyticsPage = () => { - const me = useGetAuthenticatedUser(); + const me = useUserContext(); const canManageDomains = me?.platformPrivileges?.createDomains; const { data: chartData, loading: chartLoading, error: chartError } = useGetAnalyticsChartsQuery(); const { data: highlightData, loading: highlightLoading, error: highlightError } = useGetHighlightsQuery(); diff --git a/datahub-web-react/src/app/context/useInitialRedirect.ts b/datahub-web-react/src/app/context/useInitialRedirect.ts index 6dc9aad3f9..63263d2f32 100644 --- a/datahub-web-react/src/app/context/useInitialRedirect.ts +++ b/datahub-web-react/src/app/context/useInitialRedirect.ts @@ -19,8 +19,8 @@ export function useInitialRedirect(state, localState, setState, setLocalState) { ...state, loadedInitialPath: true, }); - if (localState.selectedPath) { - history.push({ + if (localState.selectedPath && !localState.selectedPath.includes(PageRoutes.EMBED)) { + history.replace({ pathname: localState.selectedPath, search: localState.selectedSearch || '', }); @@ -40,7 +40,10 @@ export function useInitialRedirect(state, localState, setState, setLocalState) { * When the location of the browse changes, save the latest to local state. */ useEffect(() => { - if (localState.selectedPath !== location.pathname || localState.selectedSearch !== location.search) { + if ( + (localState.selectedPath !== location.pathname || localState.selectedSearch !== location.search) && + !location.pathname.includes(PageRoutes.EMBED) + ) { setLocalState({ ...localState, selectedPath: location.pathname, diff --git a/datahub-web-react/src/app/entity/EntityPage.tsx b/datahub-web-react/src/app/entity/EntityPage.tsx index 9f87197240..09233dbd89 100644 --- a/datahub-web-react/src/app/entity/EntityPage.tsx +++ b/datahub-web-react/src/app/entity/EntityPage.tsx @@ -7,12 +7,12 @@ import useIsLineageMode from '../lineage/utils/useIsLineageMode'; import { useEntityRegistry } from '../useEntityRegistry'; import analytics, { EventType } from '../analytics'; import { decodeUrn } from './shared/utils'; -import { useGetAuthenticatedUserUrn } from '../useGetAuthenticatedUser'; import { useGetGrantedPrivilegesQuery } from '../../graphql/policy.generated'; import { Message } from '../shared/Message'; import { UnauthorizedPage } from '../authorization/UnauthorizedPage'; import { ErrorSection } from '../shared/error/ErrorSection'; import { VIEW_ENTITY_PAGE } from './shared/constants'; +import { useUserContext } from '../context/useUserContext'; interface RouteParams { urn: string; @@ -33,14 +33,15 @@ export const EntityPage = ({ entityType }: Props) => { const isBrowsable = entity.isBrowseEnabled(); const isLineageSupported = entity.isLineageEnabled(); const isLineageMode = useIsLineageMode(); - const authenticatedUserUrn = useGetAuthenticatedUserUrn(); + const authenticatedUserUrn = useUserContext()?.user?.urn; const { loading, error, data } = useGetGrantedPrivilegesQuery({ variables: { input: { - actorUrn: authenticatedUserUrn, + actorUrn: authenticatedUserUrn as string, resourceSpec: { resourceType: entityType, resourceUrn: urn }, }, }, + skip: !authenticatedUserUrn, fetchPolicy: 'cache-first', }); const privileges = data?.getGrantedPrivileges?.privileges || []; diff --git a/datahub-web-react/src/app/entity/container/ContainerEntity.tsx b/datahub-web-react/src/app/entity/container/ContainerEntity.tsx index db4502afa9..4ae3cb55b4 100644 --- a/datahub-web-react/src/app/entity/container/ContainerEntity.tsx +++ b/datahub-web-react/src/app/entity/container/ContainerEntity.tsx @@ -10,7 +10,6 @@ import { SidebarOwnerSection } from '../shared/containers/profile/sidebar/Owners import { getDataForEntityType } from '../shared/containers/profile/utils'; import { useGetContainerQuery } from '../../../graphql/container.generated'; import { ContainerEntitiesTab } from './ContainerEntitiesTab'; -import { SidebarRecommendationsSection } from '../shared/containers/profile/sidebar/Recommendations/SidebarRecommendationsSection'; import { SidebarTagsSection } from '../shared/containers/profile/sidebar/SidebarTagsSection'; import { PropertiesTab } from '../shared/tabs/Properties/PropertiesTab'; import { SidebarDomainSection } from '../shared/containers/profile/sidebar/Domain/SidebarDomainSection'; @@ -99,9 +98,10 @@ export class ContainerEntity implements Entity { { component: SidebarDomainSection, }, - { - component: SidebarRecommendationsSection, - }, + // TODO: Add back once entity-level recommendations are complete. + // { + // component: SidebarRecommendationsSection, + // }, ]} /> ); diff --git a/datahub-web-react/src/app/entity/dataset/DatasetEntity.tsx b/datahub-web-react/src/app/entity/dataset/DatasetEntity.tsx index c389bb093f..f9278e6ebb 100644 --- a/datahub-web-react/src/app/entity/dataset/DatasetEntity.tsx +++ b/datahub-web-react/src/app/entity/dataset/DatasetEntity.tsx @@ -18,7 +18,6 @@ import { LineageTab } from '../shared/tabs/Lineage/LineageTab'; import { capitalizeFirstLetterOnly } from '../../shared/textUtil'; import ViewDefinitionTab from '../shared/tabs/Dataset/View/ViewDefinitionTab'; import { SidebarViewDefinitionSection } from '../shared/containers/profile/sidebar/Dataset/View/SidebarViewDefinitionSection'; -import { SidebarRecommendationsSection } from '../shared/containers/profile/sidebar/Recommendations/SidebarRecommendationsSection'; import { getDataForEntityType } from '../shared/containers/profile/utils'; import { SidebarDomainSection } from '../shared/containers/profile/sidebar/Domain/SidebarDomainSection'; import { ValidationsTab } from '../shared/tabs/Dataset/Validations/ValidationsTab'; @@ -209,9 +208,10 @@ export class DatasetEntity implements Entity { { component: SidebarDomainSection, }, - { - component: SidebarRecommendationsSection, - }, + // TODO: Add back once entity-level recommendations are complete. + // { + // component: SidebarRecommendationsSection, + // }, ]} /> ); diff --git a/datahub-web-react/src/app/entity/dataset/profile/__tests__/Properties.test.tsx b/datahub-web-react/src/app/entity/dataset/profile/__tests__/Properties.test.tsx index 83ff894b8e..4787efcc08 100644 --- a/datahub-web-react/src/app/entity/dataset/profile/__tests__/Properties.test.tsx +++ b/datahub-web-react/src/app/entity/dataset/profile/__tests__/Properties.test.tsx @@ -1,15 +1,19 @@ import React from 'react'; import { render } from '@testing-library/react'; +import { MockedProvider } from '@apollo/client/testing'; import { Properties } from '../../../shared/components/legacy/Properties'; import { sampleProperties } from '../stories/properties'; import TestPageContainer from '../../../../../utils/test-utils/TestPageContainer'; +import { mocks } from '../../../../../Mocks'; describe('Properties', () => { it('renders', () => { const { getByText } = render( - - , - , + + + , + + , ); expect(getByText('Properties')).toBeInTheDocument(); expect(getByText('Number of Partitions')).toBeInTheDocument(); diff --git a/datahub-web-react/src/app/entity/dataset/profile/__tests__/SchemaDescriptionField.test.tsx b/datahub-web-react/src/app/entity/dataset/profile/__tests__/SchemaDescriptionField.test.tsx index 5cebf0658b..30255bf9e8 100644 --- a/datahub-web-react/src/app/entity/dataset/profile/__tests__/SchemaDescriptionField.test.tsx +++ b/datahub-web-react/src/app/entity/dataset/profile/__tests__/SchemaDescriptionField.test.tsx @@ -1,14 +1,18 @@ import React from 'react'; import { fireEvent, render, waitFor } from '@testing-library/react'; +import { MockedProvider } from '@apollo/client/testing'; import SchemaDescriptionField from '../schema/components/SchemaDescriptionField'; import TestPageContainer from '../../../../../utils/test-utils/TestPageContainer'; +import { mocks } from '../../../../../Mocks'; describe('SchemaDescriptionField', () => { it('renders editable description', async () => { const { getByText, getByRole, queryByText } = render( - - {}} /> - , + + + {}} /> + + , ); expect(getByRole('img')).toBeInTheDocument(); expect(getByText('test description updated')).toBeInTheDocument(); @@ -17,14 +21,16 @@ describe('SchemaDescriptionField', () => { it('renders update description modal', async () => { const { getByText, getByRole, queryByText } = render( - - {}} - /> - , + + + {}} + /> + + , ); expect(queryByText('Update description')).not.toBeInTheDocument(); fireEvent.click(getByRole('img')); diff --git a/datahub-web-react/src/app/entity/dataset/profile/__tests__/Stats.test.tsx b/datahub-web-react/src/app/entity/dataset/profile/__tests__/Stats.test.tsx index 4af7bbb1ac..d5682a629b 100644 --- a/datahub-web-react/src/app/entity/dataset/profile/__tests__/Stats.test.tsx +++ b/datahub-web-react/src/app/entity/dataset/profile/__tests__/Stats.test.tsx @@ -1,15 +1,19 @@ import React from 'react'; import { render } from '@testing-library/react'; +import { MockedProvider } from '@apollo/client/testing'; import SnapshotStatsView from '../stats/snapshot/SnapshotStatsView'; import TestPageContainer from '../../../../../utils/test-utils/TestPageContainer'; import { completeSampleProfile, missingFieldStatsProfile, missingTableStatsProfile } from '../stories/stats'; +import { mocks } from '../../../../../Mocks'; describe('SnapshotStatsView', () => { it('renders complete profile', () => { const { getByText } = render( - - - , + + + + + , ); // Row Count @@ -53,9 +57,11 @@ describe('SnapshotStatsView', () => { it('renders profile without field stats', () => { const { getByText, queryByText } = render( - - - , + + + + + , ); // Row Count @@ -99,9 +105,11 @@ describe('SnapshotStatsView', () => { it('renders profile without table stats', () => { const { getByText, queryByText } = render( - - - , + + + + + , ); // Row Count diff --git a/datahub-web-react/src/app/entity/glossaryTerm/profile/__tests__/GlossaryTermHeader.test.tsx b/datahub-web-react/src/app/entity/glossaryTerm/profile/__tests__/GlossaryTermHeader.test.tsx index c4751f2a9d..192e66285e 100644 --- a/datahub-web-react/src/app/entity/glossaryTerm/profile/__tests__/GlossaryTermHeader.test.tsx +++ b/datahub-web-react/src/app/entity/glossaryTerm/profile/__tests__/GlossaryTermHeader.test.tsx @@ -1,5 +1,7 @@ +import { MockedProvider } from '@apollo/client/testing'; import { render } from '@testing-library/react'; import React from 'react'; +import { mocks } from '../../../../../Mocks'; import TestPageContainer from '../../../../../utils/test-utils/TestPageContainer'; import GlossaryTermHeader from '../GlossaryTermHeader'; @@ -13,14 +15,16 @@ const glossaryTermHeaderData = { describe('Glossary Term Header', () => { it('renders', () => { const { getByText } = render( - - - , + + + + + , ); expect(getByText(glossaryTermHeaderData.definition)).toBeInTheDocument(); }); diff --git a/datahub-web-react/src/app/entity/group/GroupEditModal.tsx b/datahub-web-react/src/app/entity/group/GroupEditModal.tsx index 66173f40e8..9db52c7598 100644 --- a/datahub-web-react/src/app/entity/group/GroupEditModal.tsx +++ b/datahub-web-react/src/app/entity/group/GroupEditModal.tsx @@ -44,11 +44,7 @@ export default function GroupEditModal({ visible, onClose, onSave, editModalData }, }, }) - .catch((e) => { - message.destroy(); - message.error({ content: `Failed to Save changes!: \n ${e.message || ''}`, duration: 3 }); - }) - .finally(() => { + .then(() => { message.success({ content: `Changes saved.`, duration: 3, @@ -60,6 +56,10 @@ export default function GroupEditModal({ visible, onClose, onSave, editModalData slack: '', urn: '', }); + }) + .catch((e) => { + message.destroy(); + message.error({ content: `Failed to Save changes!: \n ${e.message || ''}`, duration: 3 }); }); onClose(); }; diff --git a/datahub-web-react/src/app/entity/group/GroupInfoSideBar.tsx b/datahub-web-react/src/app/entity/group/GroupInfoSideBar.tsx index f128c7b513..d9eaed2682 100644 --- a/datahub-web-react/src/app/entity/group/GroupInfoSideBar.tsx +++ b/datahub-web-react/src/app/entity/group/GroupInfoSideBar.tsx @@ -21,7 +21,7 @@ import { GroupsSection, } from '../shared/SidebarStyledComponents'; import GroupMembersSideBarSection from './GroupMembersSideBarSection'; -import { useGetAuthenticatedUser } from '../../useGetAuthenticatedUser'; +import { useUserContext } from '../../context/useUserContext'; const { Paragraph } = Typography; @@ -103,8 +103,8 @@ export default function GroupInfoSidebar({ sideBarData, refetch }: Props) { /* eslint-disable @typescript-eslint/no-unused-vars */ const [editGroupModal, showEditGroupModal] = useState(false); - const me = useGetAuthenticatedUser(); - const canEditGroup = me?.platformPrivileges.manageIdentities; + const me = useUserContext(); + const canEditGroup = me?.platformPrivileges?.manageIdentities; const [groupTitle, setGroupTitle] = useState(name); const [updateName] = useUpdateNameMutation(); @@ -145,16 +145,16 @@ export default function GroupInfoSidebar({ sideBarData, refetch }: Props) { }, }, }) - .catch((e) => { - message.destroy(); - message.error({ content: `Failed to Save changes!: \n ${e.message || ''}`, duration: 3 }); - }) - .finally(() => { + .then(() => { message.success({ content: `Changes saved.`, duration: 3, }); refetch(); + }) + .catch((e) => { + message.destroy(); + message.error({ content: `Failed to Save changes!: \n ${e.message || ''}`, duration: 3 }); }); }; return ( @@ -220,7 +220,7 @@ export default function GroupInfoSidebar({ sideBarData, refetch }: Props) { history.push(`${url}/members`)} + onSeeMore={() => history.replace(`${url}/members`)} /> diff --git a/datahub-web-react/src/app/entity/shared/components/styled/AddLinkModal.tsx b/datahub-web-react/src/app/entity/shared/components/styled/AddLinkModal.tsx index 5225c1f42c..34d4f0cb3f 100644 --- a/datahub-web-react/src/app/entity/shared/components/styled/AddLinkModal.tsx +++ b/datahub-web-react/src/app/entity/shared/components/styled/AddLinkModal.tsx @@ -1,10 +1,10 @@ import React, { useState } from 'react'; import { message, Modal, Button, Form, Input } from 'antd'; import { PlusOutlined } from '@ant-design/icons'; -import { useGetAuthenticatedUser } from '../../../../useGetAuthenticatedUser'; import { useEntityData, useMutationUrn } from '../../EntityContext'; import { useAddLinkMutation } from '../../../../../graphql/mutations.generated'; import analytics, { EventType, EntityActionType } from '../../../../analytics'; +import { useUserContext } from '../../../../context/useUserContext'; type AddLinkProps = { buttonProps?: Record; @@ -14,7 +14,7 @@ type AddLinkProps = { export const AddLinkModal = ({ buttonProps, refetch }: AddLinkProps) => { const [isModalVisible, setIsModalVisible] = useState(false); const mutationUrn = useMutationUrn(); - const user = useGetAuthenticatedUser(); + const user = useUserContext(); const { entityType } = useEntityData(); const [addLinkMutation] = useAddLinkMutation(); @@ -30,7 +30,7 @@ export const AddLinkModal = ({ buttonProps, refetch }: AddLinkProps) => { }; const handleAdd = async (formData: any) => { - if (user?.corpUser.urn) { + if (user?.urn) { try { await addLinkMutation({ variables: { input: { linkUrl: formData.url, label: formData.label, resourceUrn: mutationUrn } }, diff --git a/datahub-web-react/src/app/entity/shared/components/styled/search/navigateToEntitySearchUrl.ts b/datahub-web-react/src/app/entity/shared/components/styled/search/navigateToEntitySearchUrl.ts index ac5440401c..44459e590b 100644 --- a/datahub-web-react/src/app/entity/shared/components/styled/search/navigateToEntitySearchUrl.ts +++ b/datahub-web-react/src/app/entity/shared/components/styled/search/navigateToEntitySearchUrl.ts @@ -39,7 +39,7 @@ export const navigateToEntitySearchUrl = ({ { arrayFormat: 'comma' }, ); - history.push({ + history.replace({ pathname: `${baseUrl}`, search, }); diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx b/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx index f3a8f043da..3c3bdb018f 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx +++ b/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx @@ -182,7 +182,7 @@ export const EntityProfile = ({ ({ tabName, tabParams, - method = 'push', + method = 'replace', }: { tabName: string; tabParams?: Record; diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/header/EntityHeader.tsx b/datahub-web-react/src/app/entity/shared/containers/profile/header/EntityHeader.tsx index ebeb80f385..3aaef6db0f 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/header/EntityHeader.tsx +++ b/datahub-web-react/src/app/entity/shared/containers/profile/header/EntityHeader.tsx @@ -5,7 +5,6 @@ import { EntityHealthStatus } from './EntityHealthStatus'; import EntityDropdown, { EntityMenuItems } from '../../../EntityDropdown/EntityDropdown'; import PlatformContent from './PlatformContent'; import { getPlatformName } from '../../../utils'; -import { useGetAuthenticatedUser } from '../../../../../useGetAuthenticatedUser'; import { EntityType, PlatformPrivileges } from '../../../../../../types.generated'; import EntityCount from './EntityCount'; import EntityName from './EntityName'; @@ -16,6 +15,7 @@ import EntityActions, { EntityActionItem } from '../../../entity/EntityActions'; import ExternalUrlButton from '../../../ExternalUrlButton'; import ShareButton from '../../../../../shared/share/ShareButton'; import { capitalizeFirstLetterOnly } from '../../../../../shared/textUtil'; +import { useUserContext } from '../../../../../context/useUserContext'; const TitleWrapper = styled.div` display: flex; @@ -81,7 +81,7 @@ type Props = { export const EntityHeader = ({ headerDropdownItems, headerActionItems, isNameEditable, subHeader }: Props) => { const { urn, entityType, entityData } = useEntityData(); const refetch = useRefetch(); - const me = useGetAuthenticatedUser(); + const me = useUserContext(); const platformName = getPlatformName(entityData); const externalUrl = entityData?.externalUrl || undefined; const entityCount = entityData?.entityCount; diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Recommendations/SidebarRecommendationsSection.tsx b/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Recommendations/SidebarRecommendationsSection.tsx index db84950ecc..002db71f22 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Recommendations/SidebarRecommendationsSection.tsx +++ b/datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Recommendations/SidebarRecommendationsSection.tsx @@ -1,6 +1,6 @@ import React from 'react'; import styled from 'styled-components'; -import { useGetAuthenticatedUser } from '../../../../../../useGetAuthenticatedUser'; +import { useUserContext } from '../../../../../../context/useUserContext'; import { useEntityData } from '../../../../EntityContext'; import { SidebarEntityRecommendations } from './SidebarEntityRecommendations'; @@ -8,7 +8,7 @@ const RecommendationsContainer = styled.div``; export const SidebarRecommendationsSection = () => { const { urn, entityType } = useEntityData(); - const authenticatedUserUrn = useGetAuthenticatedUser()?.corpUser?.urn; + const authenticatedUserUrn = useUserContext()?.user?.urn; return ( {authenticatedUserUrn && ( diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/SchemaTab.tsx b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/SchemaTab.tsx index c10274d8d1..4bdb2dac03 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/SchemaTab.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/SchemaTab.tsx @@ -109,7 +109,7 @@ export const SchemaTab = ({ properties }: { properties?: any }) => { } const { data: getSchemaBlameData } = useGetSchemaBlameQuery({ - skip: !datasetUrn, + skip: !datasetUrn || !selectedVersion, variables: { input: { datasetUrn, diff --git a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/utils/updateSchemaFilterQueryString.ts b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/utils/updateSchemaFilterQueryString.ts index 7e205b0985..336a365818 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/utils/updateSchemaFilterQueryString.ts +++ b/datahub-web-react/src/app/entity/shared/tabs/Dataset/Schema/utils/updateSchemaFilterQueryString.ts @@ -13,7 +13,7 @@ export default function useUpdateSchemaFilterQueryString(filterText: string) { const stringifiedParams = QueryString.stringify(newParams, { arrayFormat: 'comma' }); useEffect(() => { - history.push({ + history.replace({ pathname: location.pathname, search: stringifiedParams, }); diff --git a/datahub-web-react/src/app/entity/shared/tabs/Lineage/generateUseSearchResultsViaRelationshipHook.ts b/datahub-web-react/src/app/entity/shared/tabs/Lineage/generateUseSearchResultsViaRelationshipHook.ts index 0c6b31f5fa..f3b904956b 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Lineage/generateUseSearchResultsViaRelationshipHook.ts +++ b/datahub-web-react/src/app/entity/shared/tabs/Lineage/generateUseSearchResultsViaRelationshipHook.ts @@ -3,6 +3,10 @@ import { useSearchAcrossLineageQuery } from '../../../../../graphql/search.gener import { LineageDirection } from '../../../../../types.generated'; import { GetSearchResultsParams } from '../../components/styled/search/types'; +const filtersExist = (filters, orFilters) => { + return filters?.length || orFilters?.length; +}; + export default function generateUseSearchResultsViaRelationshipHook({ urn, direction, @@ -41,6 +45,7 @@ export default function generateUseSearchResultsViaRelationshipHook({ variables: { input: inputFields, }, + skip: !filtersExist(filters, orFilters), // If you don't include any filters, we shound't return anything :). Might as well skip! }); useEffect(() => { diff --git a/datahub-web-react/src/app/entity/user/UserEditProfileModal.tsx b/datahub-web-react/src/app/entity/user/UserEditProfileModal.tsx index f8077ece8d..56839ef3eb 100644 --- a/datahub-web-react/src/app/entity/user/UserEditProfileModal.tsx +++ b/datahub-web-react/src/app/entity/user/UserEditProfileModal.tsx @@ -59,11 +59,7 @@ export default function UserEditProfileModal({ visible, onClose, onSave, editMod }, }, }) - .catch((e) => { - message.destroy(); - message.error({ content: `Failed to Save changes!: \n ${e.message || ''}`, duration: 3 }); - }) - .finally(() => { + .then(() => { message.success({ content: `Changes saved.`, duration: 3, @@ -80,6 +76,10 @@ export default function UserEditProfileModal({ visible, onClose, onSave, editMod phone: '', urn: '', }); + }) + .catch((e) => { + message.destroy(); + message.error({ content: `Failed to Save changes!: \n ${e.message || ''}`, duration: 3 }); }); onClose(); }; diff --git a/datahub-web-react/src/app/entity/user/UserInfoSideBar.tsx b/datahub-web-react/src/app/entity/user/UserInfoSideBar.tsx index a987ee1399..c01dd3a635 100644 --- a/datahub-web-react/src/app/entity/user/UserInfoSideBar.tsx +++ b/datahub-web-react/src/app/entity/user/UserInfoSideBar.tsx @@ -5,7 +5,6 @@ import { useUpdateCorpUserPropertiesMutation } from '../../../graphql/user.gener import { EntityRelationship, DataHubRole } from '../../../types.generated'; import UserEditProfileModal from './UserEditProfileModal'; import CustomAvatar from '../../shared/avatar/CustomAvatar'; -import { useGetAuthenticatedUser } from '../../useGetAuthenticatedUser'; import { SideBar, SideBarSubSection, @@ -21,6 +20,7 @@ import { } from '../shared/SidebarStyledComponents'; import EntityGroups from '../shared/EntityGroups'; import { mapRoleIcon } from '../../identity/user/UserUtils'; +import { useUserContext } from '../../context/useUserContext'; const { Paragraph } = Typography; @@ -58,8 +58,8 @@ export default function UserInfoSideBar({ sideBarData, refetch }: Props) { const [groupSectionExpanded, setGroupSectionExpanded] = useState(false); const [editProfileModal, showEditProfileModal] = useState(false); /* eslint-disable @typescript-eslint/no-unused-vars */ - const me = useGetAuthenticatedUser(); - const isProfileOwner = me?.corpUser?.urn === urn; + const me = useUserContext(); + const isProfileOwner = me?.user?.urn === urn; const getEditModalData = { urn, @@ -82,16 +82,16 @@ export default function UserInfoSideBar({ sideBarData, refetch }: Props) { }, }, }) - .catch((e) => { - message.destroy(); - message.error({ content: `Failed to Save changes!: \n ${e.message || ''}`, duration: 3 }); - }) - .finally(() => { + .then(() => { message.success({ content: `Changes saved.`, duration: 3, }); refetch(); + }) + .catch((e) => { + message.destroy(); + message.error({ content: `Failed to Save changes!: \n ${e.message || ''}`, duration: 3 }); }); }; const dataHubRoleName = dataHubRoles && dataHubRoles.length > 0 && (dataHubRoles[0]?.entity as DataHubRole).name; diff --git a/datahub-web-react/src/app/glossary/BusinessGlossaryPage.tsx b/datahub-web-react/src/app/glossary/BusinessGlossaryPage.tsx index e464766c1b..2adeb6b168 100644 --- a/datahub-web-react/src/app/glossary/BusinessGlossaryPage.tsx +++ b/datahub-web-react/src/app/glossary/BusinessGlossaryPage.tsx @@ -12,7 +12,6 @@ import { Message } from '../shared/Message'; import { sortGlossaryTerms } from '../entity/glossaryTerm/utils'; import { useEntityRegistry } from '../useEntityRegistry'; import { sortGlossaryNodes } from '../entity/glossaryNode/utils'; -import { useGetAuthenticatedUser } from '../useGetAuthenticatedUser'; import { BUSINESS_GLOSSARY_INTRO_ID, BUSINESS_GLOSSARY_CREATE_TERM_ID, @@ -20,6 +19,7 @@ import { } from '../onboarding/config/BusinessGlossaryOnboardingConfig'; import { OnboardingTour } from '../onboarding/OnboardingTour'; import { useGlossaryEntityData } from '../entity/shared/GlossaryEntityContext'; +import { useUserContext } from '../context/useUserContext'; export const HeaderWrapper = styled(TabToolbar)` padding: 15px 45px 10px 24px; @@ -79,7 +79,7 @@ function BusinessGlossaryPage() { const [isCreateTermModalVisible, setIsCreateTermModalVisible] = useState(false); const [isCreateNodeModalVisible, setIsCreateNodeModalVisible] = useState(false); - const user = useGetAuthenticatedUser(); + const user = useUserContext(); const canManageGlossaries = user?.platformPrivileges?.manageGlossaries; return ( diff --git a/datahub-web-react/src/app/glossary/EmptyGlossarySection.tsx b/datahub-web-react/src/app/glossary/EmptyGlossarySection.tsx index deaad2463d..033739e8d0 100644 --- a/datahub-web-react/src/app/glossary/EmptyGlossarySection.tsx +++ b/datahub-web-react/src/app/glossary/EmptyGlossarySection.tsx @@ -4,8 +4,8 @@ import React, { useState } from 'react'; import styled from 'styled-components/macro'; import { EntityType } from '../../types.generated'; import { useEntityData } from '../entity/shared/EntityContext'; -import { useGetAuthenticatedUser } from '../useGetAuthenticatedUser'; import CreateGlossaryEntityModal from '../entity/shared/EntityDropdown/CreateGlossaryEntityModal'; +import { useUserContext } from '../context/useUserContext'; const StyledEmpty = styled(Empty)` padding: 80px 40px; @@ -33,7 +33,7 @@ function EmptyGlossarySection(props: Props) { const [isCreateTermModalVisible, setIsCreateTermModalVisible] = useState(false); const [isCreateNodeModalVisible, setIsCreateNodeModalVisible] = useState(false); - const user = useGetAuthenticatedUser(); + const user = useUserContext(); const canManageGlossaries = user?.platformPrivileges?.manageGlossaries; const { entityData } = useEntityData(); const canCreateGlossaryEntity = !!entityData?.privileges?.canManageChildren || canManageGlossaries; diff --git a/datahub-web-react/src/app/home/HomePage.tsx b/datahub-web-react/src/app/home/HomePage.tsx index eb19134e68..c840a69350 100644 --- a/datahub-web-react/src/app/home/HomePage.tsx +++ b/datahub-web-react/src/app/home/HomePage.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { HomePageHeader } from './HomePageHeader'; import { HomePageBody } from './HomePageBody'; import analytics, { EventType } from '../analytics'; @@ -13,7 +13,9 @@ import { } from '../onboarding/config/HomePageOnboardingConfig'; export const HomePage = () => { - analytics.event({ type: EventType.HomePageViewEvent }); + useEffect(() => { + analytics.event({ type: EventType.HomePageViewEvent }); + }, []); return ( <> { - const user: CorpUser = useGetAuthenticatedUser()?.corpUser as CorpUser; + const user = useUserContext()?.user; return {user && }; }; diff --git a/datahub-web-react/src/app/home/HomePageHeader.tsx b/datahub-web-react/src/app/home/HomePageHeader.tsx index b51adc2f31..4e16c2e28e 100644 --- a/datahub-web-react/src/app/home/HomePageHeader.tsx +++ b/datahub-web-react/src/app/home/HomePageHeader.tsx @@ -4,7 +4,6 @@ import { Typography, Image, Row, Button, Tag } from 'antd'; import styled, { useTheme } from 'styled-components/macro'; import { RightOutlined } from '@ant-design/icons'; import { ManageAccount } from '../shared/ManageAccount'; -import { useGetAuthenticatedUser } from '../useGetAuthenticatedUser'; import { useEntityRegistry } from '../useEntityRegistry'; import { navigateToSearchUrl } from '../search/utils/navigateToSearchUrl'; import { SearchBar } from '../search/SearchBar'; @@ -20,6 +19,7 @@ import { ANTD_GRAY } from '../entity/shared/constants'; import { useAppConfig } from '../useAppConfig'; import { DEFAULT_APP_CONFIG } from '../../appConfigContext'; import { HOME_PAGE_SEARCH_BAR_ID } from '../onboarding/config/HomePageOnboardingConfig'; +import { useUserContext } from '../context/useUserContext'; const Background = styled.div` width: 100%; @@ -140,7 +140,7 @@ export const HomePageHeader = () => { const history = useHistory(); const entityRegistry = useEntityRegistry(); const [getAutoCompleteResultsForMultiple, { data: suggestionsData }] = useGetAutoCompleteMultipleResultsLazyQuery(); - const user = useGetAuthenticatedUser()?.corpUser; + const user = useUserContext()?.user; const themeConfig = useTheme(); const appConfig = useAppConfig(); const [newSuggestionData, setNewSuggestionData] = useState(); diff --git a/datahub-web-react/src/app/identity/user/UserList.tsx b/datahub-web-react/src/app/identity/user/UserList.tsx index 1b75eebbc0..55ef27b845 100644 --- a/datahub-web-react/src/app/identity/user/UserList.tsx +++ b/datahub-web-react/src/app/identity/user/UserList.tsx @@ -12,7 +12,6 @@ import TabToolbar from '../../entity/shared/components/styled/TabToolbar'; import { SearchBar } from '../../search/SearchBar'; import { useEntityRegistry } from '../../useEntityRegistry'; import ViewInviteTokenModal from './ViewInviteTokenModal'; -import { useGetAuthenticatedUser } from '../../useGetAuthenticatedUser'; import { useListRolesQuery } from '../../../graphql/role.generated'; import { scrollToTop } from '../../shared/searchUtils'; import { OnboardingTour } from '../../onboarding/OnboardingTour'; @@ -24,6 +23,7 @@ import { } from '../../onboarding/config/UsersOnboardingConfig'; import { useUpdateEducationStepIdsAllowlist } from '../../onboarding/useUpdateEducationStepIdsAllowlist'; import { DEFAULT_USER_LIST_PAGE_SIZE, removeUserFromListUsersCache } from './cacheUtils'; +import { useUserContext } from '../../context/useUserContext'; const UserContainer = styled.div``; @@ -50,8 +50,8 @@ export const UserList = () => { const [page, setPage] = useState(1); const [isViewingInviteToken, setIsViewingInviteToken] = useState(false); - const authenticatedUser = useGetAuthenticatedUser(); - const canManagePolicies = authenticatedUser?.platformPrivileges.managePolicies || false; + const authenticatedUser = useUserContext(); + const canManagePolicies = authenticatedUser?.platformPrivileges?.managePolicies || false; const pageSize = DEFAULT_USER_LIST_PAGE_SIZE; const start = (page - 1) * pageSize; diff --git a/datahub-web-react/src/app/lineage/__tests__/LineageTree.test.tsx b/datahub-web-react/src/app/lineage/__tests__/LineageTree.test.tsx index f6a53a09d9..ece4450558 100644 --- a/datahub-web-react/src/app/lineage/__tests__/LineageTree.test.tsx +++ b/datahub-web-react/src/app/lineage/__tests__/LineageTree.test.tsx @@ -1,8 +1,14 @@ import React from 'react'; import { render } from '@testing-library/react'; import { Zoom } from '@vx/zoom'; - -import { dataset3WithLineage, dataset4WithLineage, dataset5WithLineage, dataset6WithLineage } from '../../../Mocks'; +import { MockedProvider } from '@apollo/client/testing'; +import { + dataset3WithLineage, + dataset4WithLineage, + dataset5WithLineage, + dataset6WithLineage, + mocks, +} from '../../../Mocks'; import { Direction, FetchedEntities } from '../types'; import constructTree from '../utils/constructTree'; import LineageTree from '../LineageTree'; @@ -62,38 +68,40 @@ describe('LineageTree', () => { ); const { getByTestId } = render( - - - {(zoom) => ( - - - - )} - - , + + + + {(zoom) => ( + + + + )} + + + , ); expect(getByTestId('edge-urn:li:dataset:6-urn:li:dataset:5-Upstream')).toBeInTheDocument(); diff --git a/datahub-web-react/src/app/lineage/utils/navigateToLineageUrl.ts b/datahub-web-react/src/app/lineage/utils/navigateToLineageUrl.ts index 40b0351871..86b3ef6464 100644 --- a/datahub-web-react/src/app/lineage/utils/navigateToLineageUrl.ts +++ b/datahub-web-react/src/app/lineage/utils/navigateToLineageUrl.ts @@ -44,7 +44,7 @@ export const navigateToLineageUrl = ({ } const newSearchStringified = QueryString.stringify(newSearch, { arrayFormat: 'comma' }); - history.push({ + history.replace({ pathname: location.pathname, search: newSearchStringified, }); diff --git a/datahub-web-react/src/app/onboarding/OnboardingTour.tsx b/datahub-web-react/src/app/onboarding/OnboardingTour.tsx index 5a046971fe..ebdcb8453f 100644 --- a/datahub-web-react/src/app/onboarding/OnboardingTour.tsx +++ b/datahub-web-react/src/app/onboarding/OnboardingTour.tsx @@ -4,7 +4,7 @@ import Tour from 'reactour'; import { useBatchUpdateStepStatesMutation } from '../../graphql/step.generated'; import { EducationStepsContext } from '../../providers/EducationStepsContext'; import { StepStateResult } from '../../types.generated'; -import { useGetAuthenticatedUser } from '../useGetAuthenticatedUser'; +import { useUserContext } from '../context/useUserContext'; import { convertStepId, getStepsToRender } from './utils'; type Props = { @@ -13,7 +13,7 @@ type Props = { export const OnboardingTour = ({ stepIds }: Props) => { const { educationSteps, setEducationSteps, educationStepIdsAllowlist } = useContext(EducationStepsContext); - const userUrn = useGetAuthenticatedUser()?.corpUser.urn; + const userUrn = useUserContext()?.user?.urn; const [isOpen, setIsOpen] = useState(true); const [reshow, setReshow] = useState(false); const accentColor = '#5cb7b7'; diff --git a/datahub-web-react/src/app/recommendations/RecommendationModule.tsx b/datahub-web-react/src/app/recommendations/RecommendationModule.tsx index 098c46c49d..6efe3158d4 100644 --- a/datahub-web-react/src/app/recommendations/RecommendationModule.tsx +++ b/datahub-web-react/src/app/recommendations/RecommendationModule.tsx @@ -1,5 +1,5 @@ import { Typography } from 'antd'; -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { RecommendationModule as RecommendationModuleType, ScenarioType } from '../../types.generated'; import analytics, { EventType } from '../analytics'; @@ -16,18 +16,19 @@ type Props = { export const RecommendationModule = ({ module, scenarioType, displayType, showTitle }: Props) => { const finalDisplayType = displayType || RecommendationDisplayType.DEFAULT; const renderId = useMemo(() => uuidv4(), []); + useEffect(() => { + analytics.event({ + type: EventType.RecommendationImpressionEvent, + moduleId: module.moduleId, + renderType: module.renderType, + scenarioType, + }); + }, [module, scenarioType]); const RecommendationRenderer = renderTypeToRenderer.get(module.renderType); if (!RecommendationRenderer) { console.error(`Failed to find renderer corresponding to renderType ${module.renderType}`); return null; } - analytics.event({ - type: EventType.RecommendationImpressionEvent, - renderId, - moduleId: module.moduleId, - renderType: module.renderType, - scenarioType, - }); return ( <> {showTitle && {module.title}} diff --git a/datahub-web-react/src/app/recommendations/__tests__/Recommendations.test.tsx b/datahub-web-react/src/app/recommendations/__tests__/Recommendations.test.tsx index edec199def..9e1453ee47 100644 --- a/datahub-web-react/src/app/recommendations/__tests__/Recommendations.test.tsx +++ b/datahub-web-react/src/app/recommendations/__tests__/Recommendations.test.tsx @@ -7,11 +7,6 @@ import { mocks } from '../../../Mocks'; import TestPageContainer from '../../../utils/test-utils/TestPageContainer'; import { PageRoutes } from '../../../conf/Global'; import { SearchPage } from '../../search/SearchPage'; -import { EntityType } from '../../../types.generated'; -import { useGetDatasetQuery, useUpdateDatasetMutation } from '../../../graphql/dataset.generated'; -import { EntityProfile } from '../../entity/shared/containers/profile/EntityProfile'; -import { SchemaTab } from '../../entity/shared/tabs/Dataset/Schema/SchemaTab'; -import { SidebarRecommendationsSection } from '../../entity/shared/containers/profile/sidebar/Recommendations/SidebarRecommendationsSection'; describe('Recommendations', () => { it('home renders recommendations', async () => { @@ -63,45 +58,46 @@ describe('Recommendations', () => { await waitFor(() => expect(getByText('Some Other Dataset')).toBeInTheDocument()); }); - it('renders entity page sidebar recommendations', async () => { - const { getByText } = render( - - - ({})} - tabs={[ - { - name: 'Schema', - component: SchemaTab, - }, - ]} - sidebarSections={[ - { - component: SidebarRecommendationsSection, - }, - ]} - /> - - , - ); + // TODO: Uncomment once entity sidebar recs are fully supported. + // it('renders entity page sidebar recommendations', async () => { + // const { getByText } = render( + // + // + // ({})} + // tabs={[ + // { + // name: 'Schema', + // component: SchemaTab, + // }, + // ]} + // sidebarSections={[ + // { + // component: SidebarRecommendationsSection, + // }, + // ]} + // /> + // + // , + // ); - // find recommendation modules - await waitFor(() => expect(getByText('Top Platforms')).toBeInTheDocument()); - await waitFor(() => expect(getByText('Snowflake')).toBeInTheDocument()); - await waitFor(() => expect(getByText('Popular Tags')).toBeInTheDocument()); - await waitFor(() => expect(getByText('TestTag')).toBeInTheDocument()); - await waitFor(() => expect(getByText('Most Popular')).toBeInTheDocument()); - await waitFor(() => expect(getByText('Some Other Dataset')).toBeInTheDocument()); - }); + // // find recommendation modules + // await waitFor(() => expect(getByText('Top Platforms')).toBeInTheDocument()); + // await waitFor(() => expect(getByText('Snowflake')).toBeInTheDocument()); + // await waitFor(() => expect(getByText('Popular Tags')).toBeInTheDocument()); + // await waitFor(() => expect(getByText('TestTag')).toBeInTheDocument()); + // await waitFor(() => expect(getByText('Most Popular')).toBeInTheDocument()); + // await waitFor(() => expect(getByText('Some Other Dataset')).toBeInTheDocument()); + // }); }); diff --git a/datahub-web-react/src/app/search/SearchBar.tsx b/datahub-web-react/src/app/search/SearchBar.tsx index 51816f50ad..c80ea05a89 100644 --- a/datahub-web-react/src/app/search/SearchBar.tsx +++ b/datahub-web-react/src/app/search/SearchBar.tsx @@ -13,8 +13,8 @@ import { EXACT_SEARCH_PREFIX } from './utils/constants'; import { CustomAvatar } from '../shared/avatar'; import { StyledTag } from '../entity/shared/components/styled/StyledTag'; import { useListRecommendationsQuery } from '../../graphql/recommendations.generated'; -import { useGetAuthenticatedUserUrn } from '../useGetAuthenticatedUser'; import { getPlatformName } from '../entity/shared/utils'; +import { useUserContext } from '../context/useUserContext'; const SuggestionContainer = styled.div` display: flex; @@ -205,19 +205,19 @@ export const SearchBar = ({ useEffect(() => setSelected(initialQuery), [initialQuery]); const searchEntityTypes = entityRegistry.getSearchEntityTypes(); - const userUrn = useGetAuthenticatedUserUrn(); + const userUrn = useUserContext().user?.urn; const { data } = useListRecommendationsQuery({ variables: { input: { - userUrn, + userUrn: userUrn as string, requestContext: { scenario: ScenarioType.SearchBar, }, limit: 1, }, }, - skip: hideRecommendations, + skip: hideRecommendations || !userUrn, }); const effectiveQuery = searchQuery !== undefined ? searchQuery : initialQuery || ''; diff --git a/datahub-web-react/src/app/search/SearchResults.tsx b/datahub-web-react/src/app/search/SearchResults.tsx index c95feeec52..e9c1fd3f5e 100644 --- a/datahub-web-react/src/app/search/SearchResults.tsx +++ b/datahub-web-react/src/app/search/SearchResults.tsx @@ -13,7 +13,6 @@ import { } from '../../types.generated'; import { SearchCfg } from '../../conf'; import { SearchResultsRecommendations } from './SearchResultsRecommendations'; -import { useGetAuthenticatedUser } from '../useGetAuthenticatedUser'; import SearchExtendedMenu from '../entity/shared/components/styled/search/SearchExtendedMenu'; import { combineSiblingsInSearchResults } from '../entity/shared/siblingUtils'; import { SearchSelectBar } from '../entity/shared/components/styled/search/SearchSelectBar'; @@ -26,6 +25,7 @@ import { UnionType } from './utils/constants'; import { SearchFiltersSection } from './SearchFiltersSection'; import { generateOrFilters } from './utils/generateOrFilters'; import { SEARCH_RESULTS_FILTERS_ID } from '../onboarding/config/SearchOnboardingConfig'; +import { useUserContext } from '../context/useUserContext'; const SearchBody = styled.div` display: flex; @@ -132,7 +132,7 @@ export const SearchResults = ({ const pageSize = searchResponse?.count || 0; const totalResults = searchResponse?.total || 0; const lastResultIndex = pageStart + pageSize > totalResults ? totalResults : pageStart + pageSize; - const authenticatedUserUrn = useGetAuthenticatedUser()?.corpUser?.urn; + const authenticatedUserUrn = useUserContext().user?.urn; const combinedSiblingSearchResults = combineSiblingsInSearchResults(searchResponse?.searchResults); const searchResultUrns = combinedSiblingSearchResults.map((result) => result.entity.urn) || []; diff --git a/datahub-web-react/src/app/search/SearchablePage.tsx b/datahub-web-react/src/app/search/SearchablePage.tsx index f703bcbe89..ab822815bc 100644 --- a/datahub-web-react/src/app/search/SearchablePage.tsx +++ b/datahub-web-react/src/app/search/SearchablePage.tsx @@ -10,10 +10,10 @@ import { useGetAutoCompleteMultipleResultsLazyQuery, } from '../../graphql/search.generated'; import { navigateToSearchUrl } from './utils/navigateToSearchUrl'; -import { useGetAuthenticatedUser } from '../useGetAuthenticatedUser'; import analytics, { EventType } from '../analytics'; import useFilters from './utils/useFilters'; import { PageRoutes } from '../../conf/Global'; +import { useUserContext } from '../context/useUserContext'; const styles = { children: { @@ -56,7 +56,7 @@ export const SearchablePage = ({ onSearch, onAutoComplete, children }: Props) => const themeConfig = useTheme(); const [getAutoCompleteResults, { data: suggestionsData }] = useGetAutoCompleteMultipleResultsLazyQuery(); - const user = useGetAuthenticatedUser()?.corpUser; + const user = useUserContext()?.user; const [newSuggestionData, setNewSuggestionData] = useState(); useEffect(() => { diff --git a/datahub-web-react/src/app/settings/AccessTokens.tsx b/datahub-web-react/src/app/settings/AccessTokens.tsx index 0a360138df..02ff3f1cd3 100644 --- a/datahub-web-react/src/app/settings/AccessTokens.tsx +++ b/datahub-web-react/src/app/settings/AccessTokens.tsx @@ -9,12 +9,12 @@ import { useListAccessTokensQuery, useRevokeAccessTokenMutation } from '../../gr import { Message } from '../shared/Message'; import TabToolbar from '../entity/shared/components/styled/TabToolbar'; import { StyledTable } from '../entity/shared/components/styled/StyledTable'; -import { useGetAuthenticatedUser } from '../useGetAuthenticatedUser'; import CreateTokenModal from './CreateTokenModal'; -import { useAppConfigQuery } from '../../graphql/app.generated'; import { getLocaleTimezone } from '../shared/time/timeUtils'; import { scrollToTop } from '../shared/searchUtils'; import analytics, { EventType } from '../analytics'; +import { useUserContext } from '../context/useUserContext'; +import { useAppConfig } from '../useAppConfig'; const SourceContainer = styled.div` width: 100%; @@ -78,12 +78,12 @@ export const AccessTokens = () => { const [removedTokens, setRemovedTokens] = useState([]); // Current User Urn - const authenticatedUser = useGetAuthenticatedUser(); - const currentUserUrn = authenticatedUser?.corpUser.urn || ''; + const authenticatedUser = useUserContext(); + const currentUserUrn = authenticatedUser?.user?.urn || ''; - const isTokenAuthEnabled = useAppConfigQuery().data?.appConfig?.authConfig?.tokenAuthEnabled; + const isTokenAuthEnabled = useAppConfig().config?.authConfig?.tokenAuthEnabled; const canGeneratePersonalAccessTokens = - isTokenAuthEnabled && authenticatedUser?.platformPrivileges.generatePersonalAccessTokens; + isTokenAuthEnabled && authenticatedUser?.platformPrivileges?.generatePersonalAccessTokens; // Access Tokens list paging. const [page, setPage] = useState(1); diff --git a/datahub-web-react/src/app/settings/Preferences.tsx b/datahub-web-react/src/app/settings/Preferences.tsx index 5842a51a13..6bba1b1829 100644 --- a/datahub-web-react/src/app/settings/Preferences.tsx +++ b/datahub-web-react/src/app/settings/Preferences.tsx @@ -2,10 +2,11 @@ import React from 'react'; import styled from 'styled-components'; import { Divider, Typography, Switch, Card, message } from 'antd'; -import { useGetMeQuery, useUpdateUserSettingMutation } from '../../graphql/me.generated'; +import { useUpdateUserSettingMutation } from '../../graphql/me.generated'; import { UserSetting } from '../../types.generated'; import { ANTD_GRAY } from '../entity/shared/constants'; import analytics, { EventType } from '../analytics'; +import { useUserContext } from '../context/useUserContext'; const Page = styled.div` width: 100%; @@ -52,9 +53,9 @@ const SettingText = styled(Typography.Text)` export const Preferences = () => { // Current User Urn - const { data, refetch } = useGetMeQuery({ fetchPolicy: 'no-cache' }); + const { user, refetchUser } = useUserContext(); - const showSimplifiedHomepage = !!data?.me?.corpUser?.settings?.appearance?.showSimplifiedHomepage; + const showSimplifiedHomepage = !!user?.settings?.appearance?.showSimplifiedHomepage; const [updateUserSettingMutation] = useUpdateUserSettingMutation(); return ( @@ -95,7 +96,7 @@ export const Preferences = () => { : EventType.ShowSimplifiedHomepageEvent, }); message.success({ content: 'Setting updated!', duration: 2 }); - refetch?.(); + refetchUser?.(); }} /> diff --git a/datahub-web-react/src/app/settings/SettingsPage.tsx b/datahub-web-react/src/app/settings/SettingsPage.tsx index bde73e98dd..4f5bc771d4 100644 --- a/datahub-web-react/src/app/settings/SettingsPage.tsx +++ b/datahub-web-react/src/app/settings/SettingsPage.tsx @@ -13,10 +13,10 @@ import { ANTD_GRAY } from '../entity/shared/constants'; import { ManageIdentities } from '../identity/ManageIdentities'; import { ManagePermissions } from '../permissions/ManagePermissions'; import { useAppConfig } from '../useAppConfig'; -import { useGetAuthenticatedUser } from '../useGetAuthenticatedUser'; import { AccessTokens } from './AccessTokens'; import { Preferences } from './Preferences'; import { ManageViews } from '../entity/view/ManageViews'; +import { useUserContext } from '../context/useUserContext'; const PageContainer = styled.div` display: flex; @@ -77,15 +77,15 @@ export const SettingsPage = () => { const providedPath = splitPathName[1]; const activePath = subRoutes.includes(providedPath) ? providedPath : DEFAULT_PATH.path.replace('/', ''); - const me = useGetAuthenticatedUser(); + const me = useUserContext(); const { config } = useAppConfig(); const isPoliciesEnabled = config?.policiesConfig.enabled; const isIdentityManagementEnabled = config?.identityManagementConfig.enabled; const isViewsEnabled = config?.viewsConfig.enabled; - const showPolicies = (isPoliciesEnabled && me && me.platformPrivileges.managePolicies) || false; - const showUsersGroups = (isIdentityManagementEnabled && me && me.platformPrivileges.manageIdentities) || false; + const showPolicies = (isPoliciesEnabled && me && me?.platformPrivileges?.managePolicies) || false; + const showUsersGroups = (isIdentityManagementEnabled && me && me?.platformPrivileges?.manageIdentities) || false; const showViews = isViewsEnabled || false; return ( @@ -102,7 +102,7 @@ export const SettingsPage = () => { style={{ width: 256, marginTop: 8 }} selectedKeys={[activePath]} onClick={(newPath) => { - history.push(`${url}/${newPath.key}`); + history.replace(`${url}/${newPath.key}`); }} > diff --git a/datahub-web-react/src/app/shared/NoPageFound.tsx b/datahub-web-react/src/app/shared/NoPageFound.tsx index 897af56c62..8d0d9883ea 100644 --- a/datahub-web-react/src/app/shared/NoPageFound.tsx +++ b/datahub-web-react/src/app/shared/NoPageFound.tsx @@ -53,7 +53,7 @@ export const NoPageFound = () => { const history = useHistory(); const goToHomepage = () => { - history.push('/'); + history.replace('/'); }; return ( diff --git a/datahub-web-react/src/app/shared/RoutedTabs.tsx b/datahub-web-react/src/app/shared/RoutedTabs.tsx index b1c0749a91..b349ef7599 100644 --- a/datahub-web-react/src/app/shared/RoutedTabs.tsx +++ b/datahub-web-react/src/app/shared/RoutedTabs.tsx @@ -39,7 +39,7 @@ export const RoutedTabs = ({ defaultPath, tabs, onTabChange, ...props }: Props) activeKey={activePath} size="large" onTabClick={(tab: string) => onTabChange && onTabChange(tab)} - onChange={(newPath) => history.push(`${url}/${newPath}`)} + onChange={(newPath) => history.replace(`${url}/${newPath}`)} {...props} > {tabs.map((tab) => { diff --git a/datahub-web-react/src/app/shared/admin/HeaderLinks.tsx b/datahub-web-react/src/app/shared/admin/HeaderLinks.tsx index 7049bc3324..39035d5bff 100644 --- a/datahub-web-react/src/app/shared/admin/HeaderLinks.tsx +++ b/datahub-web-react/src/app/shared/admin/HeaderLinks.tsx @@ -12,10 +12,10 @@ import { import { Link } from 'react-router-dom'; import { Button, Dropdown, Menu, Tooltip } from 'antd'; import { useAppConfig } from '../../useAppConfig'; -import { useGetAuthenticatedUser } from '../../useGetAuthenticatedUser'; import { ANTD_GRAY } from '../../entity/shared/constants'; import { HOME_PAGE_INGESTION_ID } from '../../onboarding/config/HomePageOnboardingConfig'; import { useUpdateEducationStepIdsAllowlist } from '../../onboarding/useUpdateEducationStepIdsAllowlist'; +import { useUserContext } from '../../context/useUserContext'; const LinkWrapper = styled.span` margin-right: 0px; @@ -63,17 +63,17 @@ interface Props { export function HeaderLinks(props: Props) { const { areLinksHidden } = props; - const me = useGetAuthenticatedUser(); + const me = useUserContext(); const { config } = useAppConfig(); const isAnalyticsEnabled = config?.analyticsConfig.enabled; const isIngestionEnabled = config?.managedIngestionConfig.enabled; - const showAnalytics = (isAnalyticsEnabled && me && me.platformPrivileges.viewAnalytics) || false; + const showAnalytics = (isAnalyticsEnabled && me && me?.platformPrivileges?.viewAnalytics) || false; const showSettings = true; const showIngestion = - isIngestionEnabled && me && me.platformPrivileges.manageIngestion && me.platformPrivileges.manageSecrets; - const showDomains = me?.platformPrivileges.createDomains || me?.platformPrivileges.manageDomains; + isIngestionEnabled && me && me.platformPrivileges?.manageIngestion && me.platformPrivileges?.manageSecrets; + const showDomains = me?.platformPrivileges?.createDomains || me?.platformPrivileges?.manageDomains; useUpdateEducationStepIdsAllowlist(!!showIngestion, HOME_PAGE_INGESTION_ID); diff --git a/datahub-web-react/src/app/shared/updateQueryParams.ts b/datahub-web-react/src/app/shared/updateQueryParams.ts index 85eeb2748e..52b654075f 100644 --- a/datahub-web-react/src/app/shared/updateQueryParams.ts +++ b/datahub-web-react/src/app/shared/updateQueryParams.ts @@ -13,7 +13,7 @@ export default function updateQueryParams(newParams: QueryParam, location: Locat }; const stringifiedParams = QueryString.stringify(updatedParams, { arrayFormat: 'comma' }); - history.push({ + history.replace({ pathname: location.pathname, search: stringifiedParams, }); diff --git a/datahub-web-react/src/providers/EducationStepsProvider.tsx b/datahub-web-react/src/providers/EducationStepsProvider.tsx index 1b3ab6f359..28dc6b91e0 100644 --- a/datahub-web-react/src/providers/EducationStepsProvider.tsx +++ b/datahub-web-react/src/providers/EducationStepsProvider.tsx @@ -1,13 +1,13 @@ import React, { useEffect, useState } from 'react'; -import { useGetAuthenticatedUser } from '../app/useGetAuthenticatedUser'; import { getStepIds } from '../app/onboarding/utils'; import { useBatchGetStepStatesQuery } from '../graphql/step.generated'; import { EducationStepsContext } from './EducationStepsContext'; import { StepStateResult } from '../types.generated'; import { CURRENT_ONBOARDING_IDS } from '../app/onboarding/OnboardingConfig'; +import { useUserContext } from '../app/context/useUserContext'; export function EducationStepsProvider({ children }: { children: React.ReactNode }) { - const userUrn = useGetAuthenticatedUser()?.corpUser.urn; + const userUrn = useUserContext()?.user?.urn; const stepIds = getStepIds(userUrn || ''); const { data } = useBatchGetStepStatesQuery({ skip: !userUrn, variables: { input: { ids: stepIds } } }); const results = data?.batchGetStepStates.results; diff --git a/datahub-web-react/src/utils/test-utils/TestPageContainer.tsx b/datahub-web-react/src/utils/test-utils/TestPageContainer.tsx index 253933d400..412f3b7508 100644 --- a/datahub-web-react/src/utils/test-utils/TestPageContainer.tsx +++ b/datahub-web-react/src/utils/test-utils/TestPageContainer.tsx @@ -20,6 +20,7 @@ import { MLModelGroupEntity } from '../../app/entity/mlModelGroup/MLModelGroupEn import { ChartEntity } from '../../app/entity/chart/ChartEntity'; import { DashboardEntity } from '../../app/entity/dashboard/DashboardEntity'; import { LineageExplorerContext } from '../../app/lineage/utils/LineageExplorerContext'; +import UserContextProvider from '../../app/context/UserContextProvider'; type Props = { children: React.ReactNode; @@ -55,26 +56,28 @@ export default ({ children, initialEntries }: Props) => { - {}, - highlightedEdges: [], - setHighlightedEdges: () => {}, - visibleColumnsByUrn: {}, - setVisibleColumnsByUrn: () => {}, - columnsByUrn: {}, - setColumnsByUrn: () => {}, - refetchCenterNode: () => {}, - }} - > - {children} - + + {}, + highlightedEdges: [], + setHighlightedEdges: () => {}, + visibleColumnsByUrn: {}, + setVisibleColumnsByUrn: () => {}, + columnsByUrn: {}, + setColumnsByUrn: () => {}, + refetchCenterNode: () => {}, + }} + > + {children} + +