Skip to content

Commit

Permalink
H-3609: Reduce cost of polling for notification and draft entities co…
Browse files Browse the repository at this point in the history
…unts (#5838)
  • Loading branch information
CiaranMn authored Dec 11, 2024
1 parent e453b1b commit cc36894
Show file tree
Hide file tree
Showing 24 changed files with 998 additions and 917 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const getEntitySubgraphQuery = gql`
) {
getEntitySubgraph(request: $request) {
closedMultiEntityTypes
count
definitions
userPermissionsOnEntities @include(if: $includePermissions)
subgraph {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { useRouter } from "next/router";
import type { ReactNode } from "react";
import { useContext } from "react";

import { NotificationsWithLinksContextProvider } from "../../../../shared/notifications-with-links-context";
import { TopContextBar } from "../../../../shared/top-context-bar";
import { WorkspaceContext } from "../../../../shared/workspace-context";
import { EntityEditorTabs } from "../shared/entity-editor-tabs";
Expand Down Expand Up @@ -84,19 +83,17 @@ export const EntityPageHeader = ({
/>

{entity && entitySubgraph ? (
<NotificationsWithLinksContextProvider>
<Collapse
in={!!extractDraftIdFromEntityId(entity.metadata.recordId.entityId)}
>
<DraftEntityBanner
draftEntity={entity}
draftEntitySubgraph={entitySubgraph}
isModifyingEntity={isModifyingEntity}
onAcceptedEntity={onEntityUpdated}
owningShortname={shortname}
/>
</Collapse>
</NotificationsWithLinksContextProvider>
<Collapse
in={!!extractDraftIdFromEntityId(entity.metadata.recordId.entityId)}
>
<DraftEntityBanner
draftEntity={entity}
draftEntitySubgraph={entitySubgraph}
isModifyingEntity={isModifyingEntity}
onAcceptedEntity={onEntityUpdated}
owningShortname={shortname}
/>
</Collapse>
) : null}

{editBar}
Expand Down
12 changes: 6 additions & 6 deletions apps/hash-frontend/src/pages/_app.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ import { hasAccessToHashQuery, meQuery } from "../graphql/queries/user.queries";
import { apolloClient } from "../lib/apollo-client";
import type { MinimalUser } from "../lib/user-and-org";
import { constructMinimalUser } from "../lib/user-and-org";
import { DraftEntitiesContextProvider } from "../shared/draft-entities-context";
import { DraftEntitiesCountContextProvider } from "../shared/draft-entities-count-context";
import { EntityTypesContextProvider } from "../shared/entity-types-context/provider";
import { FileUploadsProvider } from "../shared/file-upload-context";
import { KeyboardShortcutsContextProvider } from "../shared/keyboard-shortcuts-context";
import type { NextPageWithLayout } from "../shared/layout";
import { getLayoutWithSidebar, getPlainLayout } from "../shared/layout";
import { SidebarContextProvider } from "../shared/layout/layout-with-sidebar/sidebar-context";
import { NotificationEntitiesContextProvider } from "../shared/notification-entities-context";
import { NotificationCountContextProvider } from "../shared/notification-count-context";
import { PropertyTypesContextProvider } from "../shared/property-types-context";
import { RoutePageInfoProvider } from "../shared/routing";
import { ErrorFallback } from "./_app.page/error-fallback";
Expand Down Expand Up @@ -108,8 +108,8 @@ const App: FunctionComponent<AppProps> = ({
<WorkspaceContextProvider>
<KeyboardShortcutsContextProvider>
<SnackbarProvider maxSnack={3}>
<NotificationEntitiesContextProvider>
<DraftEntitiesContextProvider>
<NotificationCountContextProvider>
<DraftEntitiesCountContextProvider>
<EntityTypesContextProvider>
<PropertyTypesContextProvider includeArchived>
<DataTypesContextProvider>
Expand All @@ -132,8 +132,8 @@ const App: FunctionComponent<AppProps> = ({
</DataTypesContextProvider>
</PropertyTypesContextProvider>
</EntityTypesContextProvider>
</DraftEntitiesContextProvider>
</NotificationEntitiesContextProvider>
</DraftEntitiesCountContextProvider>
</NotificationCountContextProvider>
</SnackbarProvider>
</KeyboardShortcutsContextProvider>
</WorkspaceContextProvider>
Expand Down
24 changes: 17 additions & 7 deletions apps/hash-frontend/src/pages/actions.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,26 @@ import type {
GetEntitySubgraphQueryVariables,
} from "../graphql/api-types.gen";
import { getEntitySubgraphQuery } from "../graphql/queries/knowledge/entity.queries";
import { useDraftEntities } from "../shared/draft-entities-context";
import { BarsSortRegularIcon } from "../shared/icons/bars-sort-regular-icon";
import type { NextPageWithLayout } from "../shared/layout";
import { getLayoutWithSidebar } from "../shared/layout";
import { MenuItem } from "../shared/ui";
import type { SortOrder } from "./actions.page/draft-entities";
import { DraftEntities } from "./actions.page/draft-entities";
import { DraftEntitiesBulkActionsDropdown } from "./actions.page/draft-entities-bulk-actions-dropdown";
import {
DraftEntitiesContextProvider,
useDraftEntities,
} from "./actions.page/draft-entities-context";
import { InlineSelect } from "./shared/inline-select";
import { NotificationsWithLinksContextProvider } from "./shared/notifications-with-links-context";
import { TopContextBar } from "./shared/top-context-bar";

const sortOrderHumanReadable: Record<SortOrder, string> = {
"created-at-asc": "creation date/time (oldest first)",
"created-at-desc": "creation date/time (newest first)",
};

const ActionsPage: NextPageWithLayout = () => {
const ActionsPage = () => {
const [selectedDraftEntityIds, setSelectedDraftEntityIds] = useState<
EntityId[]
>([]);
Expand Down Expand Up @@ -117,7 +119,7 @@ const ActionsPage: NextPageWithLayout = () => {
);

return (
<NotificationsWithLinksContextProvider>
<>
<NextSeo title="Actions" />
<TopContextBar
defaultCrumbIcon={null}
Expand Down Expand Up @@ -201,13 +203,21 @@ const ActionsPage: NextPageWithLayout = () => {
draftEntitiesWithLinkedDataSubgraph
}
/>
</NotificationsWithLinksContextProvider>
</>
);
};

const ActionsPageOuter: NextPageWithLayout = () => {
return (
<DraftEntitiesContextProvider>
<ActionsPage />
</DraftEntitiesContextProvider>
);
};

ActionsPage.getLayout = (page) =>
ActionsPageOuter.getLayout = (page) =>
getLayoutWithSidebar(page, {
fullWidth: true,
});

export default ActionsPage;
export default ActionsPageOuter;
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ import {
archiveEntitiesMutation,
updateEntitiesMutation,
} from "../../graphql/queries/knowledge/entity.queries";
import { useDraftEntities } from "../../shared/draft-entities-context";
import { LayerGroupLightIcon } from "../../shared/icons/layer-group-light-icon";
import { useNotificationEntities } from "../../shared/notification-entities-context";
import { useNotificationCount } from "../../shared/notification-count-context";
import { Button, MenuItem } from "../../shared/ui";
import { useNotificationsWithLinks } from "../shared/notifications-with-links-context";
import { useDraftEntities } from "./draft-entities-context";

export const DraftEntitiesBulkActionsDropdown: FunctionComponent<{
selectedDraftEntityIds: EntityId[];
Expand All @@ -44,9 +43,8 @@ export const DraftEntitiesBulkActionsDropdown: FunctionComponent<{
deselectAllDraftEntities,
}) => {
const { draftEntities, refetch: refetchDraftEntities } = useDraftEntities();
const { notifications } = useNotificationsWithLinks();
const { archiveNotifications, markNotificationsAsRead } =
useNotificationEntities();
const { archiveNotificationsForEntity, markNotificationsAsReadForEntity } =
useNotificationCount();

const popupState = usePopupState({
variant: "popover",
Expand Down Expand Up @@ -108,41 +106,37 @@ export const DraftEntitiesBulkActionsDropdown: FunctionComponent<{
>(archiveEntitiesMutation);

const ignoreAllSelectedDraftEntities = useCallback(async () => {
if (!notifications) {
if (!selectedDraftEntities.length) {
return;
}

const relatedNotifications = notifications.filter((notification) =>
selectedDraftEntityIds.includes(
notification.occurredInEntity.metadata.recordId.entityId,
),
);

await archiveEntities({
variables: {
entityIds: [
...selectedDraftEntities,
...(incomingOrOutgoingDraftLinksToIgnore ?? []),
].map(({ metadata }) => metadata.recordId.entityId),
...selectedDraftEntityIds,
...(incomingOrOutgoingDraftLinksToIgnore ?? []).map(
({ metadata }) => metadata.recordId.entityId,
),
],
},
});

await archiveNotifications({
notificationEntities: relatedNotifications.map(({ entity }) => entity),
});

await Promise.all(
selectedDraftEntityIds.map((entityId) =>
archiveNotificationsForEntity({ targetEntityId: entityId }),
),
);
await refetchDraftEntities();

deselectAllDraftEntities();
}, [
notifications,
archiveNotifications,
archiveEntities,
selectedDraftEntityIds,
selectedDraftEntities,
refetchDraftEntities,
incomingOrOutgoingDraftLinksToIgnore,
archiveNotificationsForEntity,
deselectAllDraftEntities,
incomingOrOutgoingDraftLinksToIgnore,
refetchDraftEntities,
selectedDraftEntities,
selectedDraftEntityIds,
]);

const [
Expand Down Expand Up @@ -222,15 +216,6 @@ export const DraftEntitiesBulkActionsDropdown: FunctionComponent<{
>(updateEntitiesMutation);

const acceptAllSelectedDraftEntities = useCallback(async () => {
const relatedGraphChangeNotifications =
notifications?.filter(
({ kind, occurredInEntity }) =>
kind === "graph-change" &&
selectedDraftEntityIds.includes(
occurredInEntity.metadata.recordId.entityId,
),
) ?? [];

await updateEntities({
variables: {
entityUpdates: [
Expand All @@ -244,24 +229,24 @@ export const DraftEntitiesBulkActionsDropdown: FunctionComponent<{
},
});

await markNotificationsAsRead({
notificationEntities: relatedGraphChangeNotifications.map(
({ entity }) => entity,
await Promise.all(
selectedDraftEntities.map((entity) =>
markNotificationsAsReadForEntity({
targetEntityId: entity.entityId,
}),
),
});
);

await refetchDraftEntities();

deselectAllDraftEntities();
}, [
notifications,
markNotificationsAsRead,
selectedDraftEntityIds,
selectedDraftEntities,
deselectAllDraftEntities,
leftOrRightDraftEntitiesToAccept,
updateEntities,
markNotificationsAsReadForEntity,
refetchDraftEntities,
deselectAllDraftEntities,
selectedDraftEntities,
updateEntities,
]);

const [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import { createContext, useContext, useMemo, useState } from "react";
import type {
GetEntitySubgraphQuery,
GetEntitySubgraphQueryVariables,
} from "../graphql/api-types.gen";
import { getEntitySubgraphQuery } from "../graphql/queries/knowledge/entity.queries";
import { useAuthInfo } from "../pages/shared/auth-info-context";
import { pollInterval } from "./poll-interval";
} from "../../graphql/api-types.gen";
import { getEntitySubgraphQuery } from "../../graphql/queries/knowledge/entity.queries";
import { useDraftEntitiesCount } from "../../shared/draft-entities-count-context";
import { pollInterval } from "../../shared/poll-interval";
import { useAuthInfo } from "../shared/auth-info-context";

export type DraftEntitiesContextValue = {
draftEntities?: Entity[];
Expand All @@ -38,6 +39,10 @@ export const useDraftEntities = () => {
return draftEntitiesContext;
};

/**
* Context to provide full information of draft entities, for use in the actions page.
* A separate app-wide context provides simply a count of draft entities.
*/
export const DraftEntitiesContextProvider: FunctionComponent<
PropsWithChildren
> = ({ children }) => {
Expand All @@ -48,9 +53,11 @@ export const DraftEntitiesContextProvider: FunctionComponent<

const { authenticatedUser } = useAuthInfo();

const { refetch: refetchDraftEntitiesCount } = useDraftEntitiesCount();

const {
data: draftEntitiesData,
refetch,
refetch: refetchFullData,
loading,
} = useQuery<GetEntitySubgraphQuery, GetEntitySubgraphQueryVariables>(
getEntitySubgraphQuery,
Expand Down Expand Up @@ -104,10 +111,17 @@ export const DraftEntitiesContextProvider: FunctionComponent<
draftEntitiesSubgraph,
loading,
refetch: async () => {
await refetch();
await refetchFullData();
await refetchDraftEntitiesCount();
},
}),
[draftEntities, draftEntitiesSubgraph, loading, refetch],
[
draftEntities,
draftEntitiesSubgraph,
loading,
refetchFullData,
refetchDraftEntitiesCount,
],
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
useState,
} from "react";

import { useDraftEntities } from "../../shared/draft-entities-context";
import { Button } from "../../shared/ui";
import type { MinimalActor } from "../../shared/use-actors";
import { useActors } from "../../shared/use-actors";
Expand All @@ -30,6 +29,7 @@ import {
getDraftEntityTypes,
isFilerStateDefaultFilterState,
} from "./draft-entities/draft-entities-filters";
import { useDraftEntities } from "./draft-entities-context";
import { DraftEntity } from "./draft-entity";

const incrementNumberOfEntitiesToDisplay = 20;
Expand Down
2 changes: 1 addition & 1 deletion apps/hash-frontend/src/pages/actions.page/draft-entity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { Box, Checkbox, Typography } from "@mui/material";
import type { FunctionComponent } from "react";
import { useMemo, useState } from "react";

import { useDraftEntities } from "../../shared/draft-entities-context";
import { ArrowUpRightRegularIcon } from "../../shared/icons/arrow-up-right-regular-icon";
import { Link } from "../../shared/ui";
import { EntityEditorSlideStack } from "../shared/entity-editor-slide-stack";
import { useEntityHref } from "../shared/use-entity-href";
import { useDraftEntities } from "./draft-entities-context";
import { DraftEntityActionButtons } from "./draft-entity/draft-entity-action-buttons";
import { DraftEntityProvenance } from "./draft-entity/draft-entity-provenance";
import { DraftEntityType } from "./draft-entity/draft-entity-type";
Expand Down
Loading

0 comments on commit cc36894

Please sign in to comment.