Skip to content

Commit 4cf8cfe

Browse files
authored
Optimized count query on object list page (#5884)
1 parent aaddd2c commit 4cf8cfe

File tree

8 files changed

+115
-191
lines changed

8 files changed

+115
-191
lines changed

frontend/app/src/entities/nodes/api/getObjectItems.ts

Lines changed: 0 additions & 64 deletions
This file was deleted.

frontend/app/src/entities/nodes/hooks/useObjectItems.ts

Lines changed: 0 additions & 87 deletions
This file was deleted.

frontend/app/src/entities/nodes/object-header.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { useObjectDetails } from "@/entities/nodes/hooks/useObjectDetails";
2-
import { useObjectItems } from "@/entities/nodes/hooks/useObjectItems";
3-
import { getPermission } from "@/entities/permission/utils";
2+
import { useObjectsCount } from "@/entities/nodes/object/domain/get-objects-count.query";
43
import { ModelSchema } from "@/entities/schema/types";
54
import graphqlClient from "@/shared/api/graphql/graphqlClientApollo";
65
import { queryClient } from "@/shared/api/rest/client";
@@ -25,24 +24,26 @@ const ObjectHeader = ({ schema, objectId }: ObjectHeaderProps) => {
2524

2625
const ObjectItemsHeader = ({ schema }: ObjectHeaderProps) => {
2726
const [filters] = useFilters();
28-
const { data, loading, error } = useObjectItems(schema, filters);
29-
const kindFilter = filters?.find((filter) => filter.name === "kind__value");
27+
const {
28+
data: count,
29+
isPending,
30+
isRefetching,
31+
isError,
32+
} = useObjectsCount({ schemaKind: schema.kind as string, filters });
3033

31-
const schemaKind = kindFilter?.value || (schema.kind as string);
32-
const { count, permissions } = data?.[schemaKind] ?? { count: undefined, permissions: undefined };
33-
const currentPermission = getPermission(permissions?.edges);
34-
35-
if (!currentPermission.view.isAllowed) {
36-
return null;
37-
}
34+
const refetchObjects = () => {
35+
queryClient.invalidateQueries({
36+
predicate: (query) => query.queryKey.includes("objects"),
37+
});
38+
};
3839

3940
return (
4041
<Content.CardTitle
4142
title={schema.label || schema.name}
42-
badgeContent={loading && !error ? "..." : count}
43+
badgeContent={isPending && !isError ? "..." : count}
4344
description={schema.description}
44-
isReloadLoading={loading}
45-
reload={() => graphqlClient.refetchQueries({ include: [schema.kind!] })}
45+
isReloadLoading={isRefetching}
46+
reload={refetchObjects}
4647
data-testid="object-header"
4748
end={
4849
<ObjectHelpButton
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import graphqlClient from "@/shared/api/graphql/graphqlClientApollo";
2+
import { ContextParams } from "@/shared/api/types";
3+
import { gql } from "@apollo/client";
4+
import { jsonToGraphQLQuery } from "json-to-graphql-query";
5+
6+
const getObjectsCountQuery = (kind: string) => {
7+
const query = {
8+
query: {
9+
__name: `GetObjectsCount${kind}`,
10+
[kind]: {
11+
count: true,
12+
},
13+
},
14+
};
15+
16+
return gql(jsonToGraphQLQuery(query));
17+
};
18+
19+
export type GetObjectsCountFromApiParams = ContextParams & { schemaKind: string };
20+
21+
export const getObjectsCountFromApi = async ({
22+
schemaKind,
23+
branchName,
24+
atDate,
25+
}: GetObjectsCountFromApiParams) => {
26+
return graphqlClient.query({
27+
query: getObjectsCountQuery(schemaKind),
28+
context: {
29+
branch: branchName,
30+
date: atDate,
31+
},
32+
});
33+
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { useCurrentBranch } from "@/entities/branches/ui/branches-provider";
2+
import { datetimeAtom } from "@/shared/stores/time.atom";
3+
import { queryOptions, useQuery } from "@tanstack/react-query";
4+
import { useAtomValue } from "jotai";
5+
import { GetObjectsCountParams, getObjectsCount } from "./get-objects-count";
6+
7+
export function getObjectsCountQueryOptions({
8+
schemaKind,
9+
filters,
10+
branchName,
11+
atDate,
12+
}: GetObjectsCountParams) {
13+
return queryOptions({
14+
queryKey: [branchName, atDate, "objects", schemaKind, "count", JSON.stringify(filters)],
15+
queryFn: async () => {
16+
return getObjectsCount({
17+
schemaKind,
18+
branchName,
19+
atDate,
20+
filters,
21+
});
22+
},
23+
});
24+
}
25+
26+
export function useObjectsCount(params: Omit<GetObjectsCountParams, "branchName" | "atDate">) {
27+
const { currentBranch } = useCurrentBranch();
28+
const timeMachineDate = useAtomValue(datetimeAtom);
29+
30+
return useQuery(
31+
getObjectsCountQueryOptions({
32+
...params,
33+
branchName: currentBranch.name,
34+
atDate: timeMachineDate,
35+
})
36+
);
37+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { getObjectsCountFromApi } from "@/entities/nodes/object/api/get-objects-count-from-api";
2+
import { ContextParams } from "@/shared/api/types";
3+
import { Filter } from "@/shared/hooks/useFilters";
4+
5+
export type GetObjectsCountParams = ContextParams & {
6+
schemaKind: string;
7+
filters?: Array<Filter>;
8+
};
9+
10+
export type GetObjectsCount = (args: GetObjectsCountParams) => Promise<number>;
11+
12+
export const getObjectsCount: GetObjectsCount = async ({
13+
schemaKind,
14+
branchName,
15+
atDate,
16+
filters = [],
17+
}) => {
18+
const kindFilter = filters?.find((filter) => filter.name === "kind__value");
19+
const schemaKindToQuery: string = kindFilter?.value ?? schemaKind;
20+
21+
const { data } = await getObjectsCountFromApi({
22+
schemaKind: schemaKindToQuery,
23+
branchName,
24+
atDate,
25+
});
26+
27+
return data[schemaKindToQuery].count;
28+
};

frontend/app/src/entities/user-profile/api/getTokens.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

frontend/app/tests/e2e/resource-manager/resource-pool.spec.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,8 @@ test.describe("/resource-manager - Resource Manager", () => {
66
test.use({ storageState: ACCOUNT_STATE_PATH.ADMIN });
77

88
test("create a new pool", async ({ page }) => {
9-
await Promise.all([
10-
page.waitForResponse((response) => {
11-
const reqData = response.request().postDataJSON();
12-
const status = response.status();
13-
14-
return reqData?.operationName === "CoreResourcePool" && status === 200;
15-
}),
16-
17-
page.goto("/resource-manager"),
18-
]);
9+
await page.goto("/resource-manager");
10+
await expect(page.getByRole("link", { name: "External prefixes pool" })).toBeVisible();
1911
await page.getByTestId("create-object-button").click();
2012

2113
await page.getByLabel("Select an object type").click();

0 commit comments

Comments
 (0)