refactor(ui): Make Navigating DataHub UI easier, fix duplicate tracking, duplicate networks calls, + misc optimizations (#7592)

Co-authored-by: david-leifker <114954101+david-leifker@users.noreply.github.com>
This commit is contained in:
John Joyce 2023-03-21 18:36:21 -07:00 committed by GitHub
parent bd76183b00
commit 4da49fb1b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 296 additions and 244 deletions

View File

@ -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: {

View File

@ -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;

View File

@ -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();

View File

@ -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,

View File

@ -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 || [];

View File

@ -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<Container> {
{
component: SidebarDomainSection,
},
{
component: SidebarRecommendationsSection,
},
// TODO: Add back once entity-level recommendations are complete.
// {
// component: SidebarRecommendationsSection,
// },
]}
/>
);

View File

@ -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<Dataset> {
{
component: SidebarDomainSection,
},
{
component: SidebarRecommendationsSection,
},
// TODO: Add back once entity-level recommendations are complete.
// {
// component: SidebarRecommendationsSection,
// },
]}
/>
);

View File

@ -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(
<TestPageContainer>
<Properties properties={sampleProperties} />,
</TestPageContainer>,
<MockedProvider mocks={mocks} addTypename={false}>
<TestPageContainer>
<Properties properties={sampleProperties} />,
</TestPageContainer>
</MockedProvider>,
);
expect(getByText('Properties')).toBeInTheDocument();
expect(getByText('Number of Partitions')).toBeInTheDocument();

View File

@ -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(
<TestPageContainer>
<SchemaDescriptionField description="test description updated" isEdited onUpdate={async () => {}} />
</TestPageContainer>,
<MockedProvider mocks={mocks} addTypename={false}>
<TestPageContainer>
<SchemaDescriptionField description="test description updated" isEdited onUpdate={async () => {}} />
</TestPageContainer>
</MockedProvider>,
);
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(
<TestPageContainer>
<SchemaDescriptionField
description="test description"
original="test description"
isEdited
onUpdate={async () => {}}
/>
</TestPageContainer>,
<MockedProvider mocks={mocks} addTypename={false}>
<TestPageContainer>
<SchemaDescriptionField
description="test description"
original="test description"
isEdited
onUpdate={async () => {}}
/>
</TestPageContainer>
</MockedProvider>,
);
expect(queryByText('Update description')).not.toBeInTheDocument();
fireEvent.click(getByRole('img'));

View File

@ -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(
<TestPageContainer>
<SnapshotStatsView profile={completeSampleProfile} />
</TestPageContainer>,
<MockedProvider mocks={mocks}>
<TestPageContainer>
<SnapshotStatsView profile={completeSampleProfile} />
</TestPageContainer>
</MockedProvider>,
);
// Row Count
@ -53,9 +57,11 @@ describe('SnapshotStatsView', () => {
it('renders profile without field stats', () => {
const { getByText, queryByText } = render(
<TestPageContainer>
<SnapshotStatsView profile={missingFieldStatsProfile} />
</TestPageContainer>,
<MockedProvider mocks={mocks}>
<TestPageContainer>
<SnapshotStatsView profile={missingFieldStatsProfile} />
</TestPageContainer>
</MockedProvider>,
);
// Row Count
@ -99,9 +105,11 @@ describe('SnapshotStatsView', () => {
it('renders profile without table stats', () => {
const { getByText, queryByText } = render(
<TestPageContainer>
<SnapshotStatsView profile={missingTableStatsProfile} />
</TestPageContainer>,
<MockedProvider mocks={mocks}>
<TestPageContainer>
<SnapshotStatsView profile={missingTableStatsProfile} />
</TestPageContainer>
</MockedProvider>,
);
// Row Count

View File

@ -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(
<TestPageContainer>
<GlossaryTermHeader
definition={glossaryTermHeaderData.definition}
termSource={glossaryTermHeaderData.termSource}
sourceRef={glossaryTermHeaderData.sourceRef}
fqdn={glossaryTermHeaderData.fqdn}
/>
</TestPageContainer>,
<MockedProvider mocks={mocks}>
<TestPageContainer>
<GlossaryTermHeader
definition={glossaryTermHeaderData.definition}
termSource={glossaryTermHeaderData.termSource}
sourceRef={glossaryTermHeaderData.sourceRef}
fqdn={glossaryTermHeaderData.fqdn}
/>
</TestPageContainer>
</MockedProvider>,
);
expect(getByText(glossaryTermHeaderData.definition)).toBeInTheDocument();
});

View File

@ -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();
};

View File

@ -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) {
<GroupMembersSideBarSection
total={groupMemberRelationships?.total || 0}
relationships={groupMemberRelationships?.relationships || []}
onSeeMore={() => history.push(`${url}/members`)}
onSeeMore={() => history.replace(`${url}/members`)}
/>
</GroupsSection>
</SideBarSubSection>

View File

@ -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<string, unknown>;
@ -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 } },

View File

@ -39,7 +39,7 @@ export const navigateToEntitySearchUrl = ({
{ arrayFormat: 'comma' },
);
history.push({
history.replace({
pathname: `${baseUrl}`,
search,
});

View File

@ -182,7 +182,7 @@ export const EntityProfile = <T, U>({
({
tabName,
tabParams,
method = 'push',
method = 'replace',
}: {
tabName: string;
tabParams?: Record<string, any>;

View File

@ -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;

View File

@ -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 (
<RecommendationsContainer>
{authenticatedUserUrn && (

View File

@ -109,7 +109,7 @@ export const SchemaTab = ({ properties }: { properties?: any }) => {
}
const { data: getSchemaBlameData } = useGetSchemaBlameQuery({
skip: !datasetUrn,
skip: !datasetUrn || !selectedVersion,
variables: {
input: {
datasetUrn,

View File

@ -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,
});

View File

@ -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(() => {

View File

@ -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();
};

View File

@ -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;

View File

@ -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 (

View File

@ -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;

View File

@ -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 (
<>
<OnboardingTour

View File

@ -1,7 +1,6 @@
import React from 'react';
import styled from 'styled-components';
import { CorpUser } from '../../types.generated';
import { useGetAuthenticatedUser } from '../useGetAuthenticatedUser';
import { useUserContext } from '../context/useUserContext';
import { HomePageRecommendations } from './HomePageRecommendations';
const BodyContainer = styled.div`
@ -18,6 +17,6 @@ const BodyContainer = styled.div`
`;
export const HomePageBody = () => {
const user: CorpUser = useGetAuthenticatedUser()?.corpUser as CorpUser;
const user = useUserContext()?.user;
return <BodyContainer>{user && <HomePageRecommendations user={user} />}</BodyContainer>;
};

View File

@ -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<GetAutoCompleteMultipleResultsQuery | undefined>();

View File

@ -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;

View File

@ -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(
<TestPageContainer>
<Zoom
width={width}
height={height}
scaleXMin={1 / 8}
scaleXMax={2}
scaleYMin={1 / 8}
scaleYMax={2}
transformMatrix={initialTransform}
>
{(zoom) => (
<svg>
<LineageTree
upstreamData={upstreamData}
downstreamData={downstreamData}
zoom={zoom}
onEntityClick={jest.fn()}
onLineageExpand={jest.fn()}
canvasHeight={yMax}
margin={margin}
direction={Direction.Upstream}
setIsDraggingNode={jest.fn()}
draggedNodes={{}}
setDraggedNodes={jest.fn()}
onEntityCenter={jest.fn()}
setHoveredEntity={jest.fn()}
fetchedEntities={mockFetchedEntities}
/>
</svg>
)}
</Zoom>
</TestPageContainer>,
<MockedProvider mocks={mocks}>
<TestPageContainer>
<Zoom
width={width}
height={height}
scaleXMin={1 / 8}
scaleXMax={2}
scaleYMin={1 / 8}
scaleYMax={2}
transformMatrix={initialTransform}
>
{(zoom) => (
<svg>
<LineageTree
upstreamData={upstreamData}
downstreamData={downstreamData}
zoom={zoom}
onEntityClick={jest.fn()}
onLineageExpand={jest.fn()}
canvasHeight={yMax}
margin={margin}
direction={Direction.Upstream}
setIsDraggingNode={jest.fn()}
draggedNodes={{}}
setDraggedNodes={jest.fn()}
onEntityCenter={jest.fn()}
setHoveredEntity={jest.fn()}
fetchedEntities={mockFetchedEntities}
/>
</svg>
)}
</Zoom>
</TestPageContainer>
</MockedProvider>,
);
expect(getByTestId('edge-urn:li:dataset:6-urn:li:dataset:5-Upstream')).toBeInTheDocument();

View File

@ -44,7 +44,7 @@ export const navigateToLineageUrl = ({
}
const newSearchStringified = QueryString.stringify(newSearch, { arrayFormat: 'comma' });
history.push({
history.replace({
pathname: location.pathname,
search: newSearchStringified,
});

View File

@ -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';

View File

@ -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 && <Typography.Title level={4}>{module.title}</Typography.Title>}

View File

@ -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(
<MockedProvider
mocks={mocks}
addTypename={false}
defaultOptions={{
watchQuery: { fetchPolicy: 'no-cache' },
query: { fetchPolicy: 'no-cache' },
}}
>
<TestPageContainer initialEntries={['/dataset/urn:li:dataset:3']}>
<EntityProfile
urn="urn:li:dataset:3"
entityType={EntityType.Dataset}
useEntityQuery={useGetDatasetQuery}
useUpdateQuery={useUpdateDatasetMutation}
getOverrideProperties={() => ({})}
tabs={[
{
name: 'Schema',
component: SchemaTab,
},
]}
sidebarSections={[
{
component: SidebarRecommendationsSection,
},
]}
/>
</TestPageContainer>
</MockedProvider>,
);
// TODO: Uncomment once entity sidebar recs are fully supported.
// it('renders entity page sidebar recommendations', async () => {
// const { getByText } = render(
// <MockedProvider
// mocks={mocks}
// addTypename={false}
// defaultOptions={{
// watchQuery: { fetchPolicy: 'no-cache' },
// query: { fetchPolicy: 'no-cache' },
// }}
// >
// <TestPageContainer initialEntries={['/dataset/urn:li:dataset:3']}>
// <EntityProfile
// urn="urn:li:dataset:3"
// entityType={EntityType.Dataset}
// useEntityQuery={useGetDatasetQuery}
// useUpdateQuery={useUpdateDatasetMutation}
// getOverrideProperties={() => ({})}
// tabs={[
// {
// name: 'Schema',
// component: SchemaTab,
// },
// ]}
// sidebarSections={[
// {
// component: SidebarRecommendationsSection,
// },
// ]}
// />
// </TestPageContainer>
// </MockedProvider>,
// );
// 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());
// });
});

View File

@ -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 || '';

View File

@ -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) || [];

View File

@ -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<GetAutoCompleteMultipleResultsQuery | undefined>();
useEffect(() => {

View File

@ -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<string[]>([]);
// 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);

View File

@ -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?.();
}}
/>
</UserSettingRow>

View File

@ -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}`);
}}
>
<Menu.ItemGroup title="Developer">

View File

@ -53,7 +53,7 @@ export const NoPageFound = () => {
const history = useHistory();
const goToHomepage = () => {
history.push('/');
history.replace('/');
};
return (

View File

@ -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) => {

View File

@ -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);

View File

@ -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,
});

View File

@ -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;

View File

@ -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) => {
<ThemeProvider theme={defaultThemeConfig}>
<MemoryRouter initialEntries={initialEntries}>
<EntityRegistryContext.Provider value={entityRegistry}>
<LineageExplorerContext.Provider
value={{
expandTitles: false,
showColumns: false,
collapsedColumnsNodes: {},
setCollapsedColumnsNodes: null,
fineGrainedMap: {},
selectedField: null,
setSelectedField: () => {},
highlightedEdges: [],
setHighlightedEdges: () => {},
visibleColumnsByUrn: {},
setVisibleColumnsByUrn: () => {},
columnsByUrn: {},
setColumnsByUrn: () => {},
refetchCenterNode: () => {},
}}
>
{children}
</LineageExplorerContext.Provider>
<UserContextProvider>
<LineageExplorerContext.Provider
value={{
expandTitles: false,
showColumns: false,
collapsedColumnsNodes: {},
setCollapsedColumnsNodes: null,
fineGrainedMap: {},
selectedField: null,
setSelectedField: () => {},
highlightedEdges: [],
setHighlightedEdges: () => {},
visibleColumnsByUrn: {},
setVisibleColumnsByUrn: () => {},
columnsByUrn: {},
setColumnsByUrn: () => {},
refetchCenterNode: () => {},
}}
>
{children}
</LineageExplorerContext.Provider>
</UserContextProvider>
</EntityRegistryContext.Provider>
</MemoryRouter>
</ThemeProvider>