Skip to content

Commit

Permalink
Enable server-side pagination for update_channels
Browse files Browse the repository at this point in the history
Updated queries for `update_channel` to support server-side pagination.
This change ensures data fetching is paginated on the backend while
maintaining the current client-side logic. A future update will
optimize the respective tables to fully leverage pagination, avoiding
an immediate rewrite of the client-side implementation.

Part of #779

Signed-off-by: Omar <[email protected]>
  • Loading branch information
OmarBrbutovic committed Jan 15, 2025
1 parent abbddc2 commit c9574f4
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 36 deletions.
35 changes: 34 additions & 1 deletion frontend/src/api/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2528,6 +2528,27 @@ enum UpdateChannelSortField {
NAME
}

":update_channel connection"
type UpdateChannelConnection {
"Total count on all pages"
count: Int

"Page information"
pageInfo: PageInfo!

":update_channel edges"
edges: [UpdateChannelEdge!]
}

":update_channel edge"
type UpdateChannelEdge {
"Cursor"
cursor: String!

":update_channel node"
node: UpdateChannel!
}

input UpdateChannelFilterName {
isNil: Boolean
eq: String
Expand Down Expand Up @@ -2897,7 +2918,19 @@ type RootQueryType {

"A filter to limit the results"
filter: UpdateChannelFilterInput
): [UpdateChannel!]!

"The number of records to return from the beginning. Maximum 250"
first: Int

"Show records before the specified keyset."
before: String

"Show records after the specified keyset."
after: String

"The number of records to return to the end. Maximum 250"
last: Int
): UpdateChannelConnection

"Retrieves the current tenant."
tenantInfo: TenantInfo!
Expand Down
44 changes: 28 additions & 16 deletions frontend/src/components/UpdateChannelsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
*/

import { FormattedMessage } from "react-intl";
import { graphql, useFragment } from "react-relay/hooks";
import { graphql, usePaginationFragment } from "react-relay/hooks";

import type { UpdateChannelsTable_PaginationQuery } from "api/__generated__/UpdateChannelsTable_PaginationQuery.graphql";
import type {
UpdateChannelsTable_UpdateChannelFragment$data,
UpdateChannelsTable_UpdateChannelFragment$key,
Expand All @@ -33,22 +34,33 @@ import { Link, Route } from "Navigation";
// We use graphql fields below in columns configuration
/* eslint-disable relay/unused-fields */
const DEVICE_GROUPS_TABLE_FRAGMENT = graphql`
fragment UpdateChannelsTable_UpdateChannelFragment on UpdateChannel
@relay(plural: true) {
id
name
handle
targetGroups {
fragment UpdateChannelsTable_UpdateChannelFragment on RootQueryType
@refetchable(queryName: "UpdateChannelsTable_PaginationQuery") {
updateChannels(first: $first, after: $after)
@connection(key: "UpdateChannelsTable_updateChannels") {
edges {
node {
id
name
handle
targetGroups {
edges {
node {
name
}
}
}
}
}
}
}
`;

type TableRecord = UpdateChannelsTable_UpdateChannelFragment$data[0];
type TableRecord = NonNullable<
NonNullable<
UpdateChannelsTable_UpdateChannelFragment$data["updateChannels"]
>["edges"]
>[number]["node"];

const columnHelper = createColumnHelper<TableRecord>();
const columns = [
Expand Down Expand Up @@ -105,14 +117,14 @@ type Props = {
};

const UpdateChannelsTable = ({ className, updateChannelsRef }: Props) => {
const updateChannels = useFragment(
DEVICE_GROUPS_TABLE_FRAGMENT,
updateChannelsRef,
);

return (
<Table className={className} columns={columns} data={updateChannels} />
);
const { data } = usePaginationFragment<
UpdateChannelsTable_PaginationQuery,
UpdateChannelsTable_UpdateChannelFragment$key
>(DEVICE_GROUPS_TABLE_FRAGMENT, updateChannelsRef);

const tableData = data.updateChannels?.edges?.map((edge) => edge.node) ?? [];

return <Table className={className} columns={columns} data={tableData} />;
};

export default UpdateChannelsTable;
10 changes: 7 additions & 3 deletions frontend/src/forms/CreateUpdateCampaign.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ const UPDATE_CAMPAIGN_OPTIONS_FRAGMENT = graphql`
}
}
updateChannels {
id
name
edges {
node {
id
name
}
}
}
}
`;
Expand Down Expand Up @@ -314,7 +318,7 @@ const CreateBaseImageCollectionForm = ({
defaultMessage: "Select an Update Channel",
})}
</option>
{updateChannels.map((updateChannel) => (
{updateChannels?.edges?.map(({ node: updateChannel }) => (
<option key={updateChannel.id} value={updateChannel.id}>
{updateChannel.name}
</option>
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/pages/UpdateCampaignCreate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import type {
UpdateCampaignCreate_getOptions_Query$data,
} from "api/__generated__/UpdateCampaignCreate_getOptions_Query.graphql";
import type { UpdateCampaignCreate_createUpdateCampaign_Mutation } from "api/__generated__/UpdateCampaignCreate_createUpdateCampaign_Mutation.graphql";

import Alert from "components/Alert";
import Button from "components/Button";
import Center from "components/Center";
Expand All @@ -53,6 +54,7 @@ const GET_CREATE_UPDATE_CAMPAIGN_OPTIONS_QUERY = graphql`
}
updateChannels {
__typename
count
}
...CreateUpdateCampaign_OptionsFragment
}
Expand Down Expand Up @@ -218,7 +220,7 @@ const UpdateCampaignWrapper = ({
if (baseImageCollections?.count === 0) {
return <NoBaseImageCollections />;
}
if (updateChannels.length === 0) {
if (updateChannels?.count === 0) {
return <NoUpdateChannels />;
}

Expand Down
16 changes: 8 additions & 8 deletions frontend/src/pages/UpdateChannel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Suspense, useCallback, useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { ErrorBoundary } from "react-error-boundary";
import {
ConnectionHandler,
graphql,
useMutation,
usePreloadedQuery,
Expand Down Expand Up @@ -177,14 +178,13 @@ const UpdateChannelContent = ({

const root = store.getRoot();

const updateChannels = root.getLinkedRecords("updateChannels");
if (updateChannels) {
root.setLinkedRecords(
updateChannels.filter(
(updateChannel) => updateChannel.getDataID() !== updateChannelId,
),
"updateChannels",
);
const connection = ConnectionHandler.getConnection(
root,
"UpdateChannelsTable_updateChannels",
);

if (connection) {
ConnectionHandler.deleteNode(connection, updateChannelId);
}

const targetGroupIds = new Set(
Expand Down
17 changes: 10 additions & 7 deletions frontend/src/pages/UpdateChannels.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This file is part of Edgehog.
Copyright 2023-2024 SECO Mind Srl
Copyright 2023-2025 SECO Mind Srl
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,7 @@ import { graphql, usePreloadedQuery, useQueryLoader } from "react-relay/hooks";
import type { PreloadedQuery } from "react-relay/hooks";

import type { UpdateChannels_getUpdateChannels_Query } from "api/__generated__/UpdateChannels_getUpdateChannels_Query.graphql";

import Button from "components/Button";
import Center from "components/Center";
import UpdateChannelsTable from "components/UpdateChannelsTable";
Expand All @@ -33,10 +34,8 @@ import Spinner from "components/Spinner";
import { Link, Route } from "Navigation";

const GET_UPDATE_CHANNELS_QUERY = graphql`
query UpdateChannels_getUpdateChannels_Query {
updateChannels {
...UpdateChannelsTable_UpdateChannelFragment
}
query UpdateChannels_getUpdateChannels_Query($first: Int, $after: String) {
...UpdateChannelsTable_UpdateChannelFragment
}
`;

Expand All @@ -47,7 +46,7 @@ type UpdateChannelsContentProps = {
const UpdateChannelsContent = ({
getUpdateChannelsQuery,
}: UpdateChannelsContentProps) => {
const { updateChannels } = usePreloadedQuery(
const updateChannels = usePreloadedQuery(
GET_UPDATE_CHANNELS_QUERY,
getUpdateChannelsQuery,
);
Expand Down Expand Up @@ -83,7 +82,11 @@ const UpdateChannelsPage = () => {
);

const fetchUpdateChannels = useCallback(
() => getUpdateChannels({}, { fetchPolicy: "store-and-network" }),
() =>
getUpdateChannels(
{ first: 10_000 },
{ fetchPolicy: "store-and-network" },
),
[getUpdateChannels],
);

Expand Down

0 comments on commit c9574f4

Please sign in to comment.