Skip to content

Commit d145535

Browse files
committed
wip[frontend]: add subscriptions for campaigns
- Added subscriptions to DeploymentCampaign page - Added subscriptions to UpdateCampaign page TODO: - Add subscriptions to Channels and Channel page - Add subscriptions to DeploymentCampaigns and UpdateCampaigns page - figure out how to update Target Tabs component on DeploymentCampaign and UpdateCampaign pages Signed-off-by: ArnelaL <arnela.lisic@secomind.com>
1 parent 3686ad9 commit d145535

5 files changed

Lines changed: 180 additions & 132 deletions

File tree

frontend/src/api/schema.graphql

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,12 @@ type LocalizedAttribute {
900900
languageTag: String!
901901
}
902902

903+
type base_image_collection_result {
904+
created: BaseImageCollection
905+
updated: BaseImageCollection
906+
destroyed: ID
907+
}
908+
903909
"The result of the :delete_base_image_collection mutation"
904910
type DeleteBaseImageCollectionResult {
905911
"The record that was successfully deleted"
@@ -1092,6 +1098,12 @@ type BaseImageCollection implements Node {
10921098
): BaseImageConnection!
10931099
}
10941100

1101+
type base_image_result {
1102+
created: BaseImage
1103+
updated: BaseImage
1104+
destroyed: ID
1105+
}
1106+
10951107
"The result of the :delete_base_image mutation"
10961108
type DeleteBaseImageResult {
10971109
"The record that was successfully deleted"
@@ -5248,6 +5260,12 @@ type TenantInfo {
52485260
defaultLocale: String!
52495261
}
52505262

5263+
type channels_result {
5264+
created: Channel
5265+
updated: Channel
5266+
destroyed: ID
5267+
}
5268+
52515269
"The result of the :delete_channel mutation"
52525270
type DeleteChannelResult {
52535271
"The record that was successfully deleted"
@@ -5459,6 +5477,11 @@ type Channel implements Node {
54595477
): CampaignConnection!
54605478
}
54615479

5480+
type campaign_target_changed_result {
5481+
created: CampaignTarget
5482+
updated: CampaignTarget
5483+
}
5484+
54625485
enum CampaignTargetSortField {
54635486
ID
54645487
STATUS
@@ -5623,6 +5646,25 @@ type CampaignTarget {
56235646
otaOperation: OtaOperation
56245647
}
56255648

5649+
type campaign_result {
5650+
updated: Campaign
5651+
}
5652+
5653+
type update_campaigns_result {
5654+
created: Campaign
5655+
updated: Campaign
5656+
}
5657+
5658+
type deployment_campaigns_result {
5659+
created: Campaign
5660+
updated: Campaign
5661+
}
5662+
5663+
type campaigns_result {
5664+
created: Campaign
5665+
updated: Campaign
5666+
}
5667+
56265668
"The result of the :create_campaign mutation"
56275669
type CreateCampaignResult {
56285670
"The successful result of the mutation"
@@ -6411,10 +6453,48 @@ type RootMutationType {
64116453
}
64126454

64136455
type RootSubscriptionType {
6456+
campaigns(
6457+
"A filter to limit the results"
6458+
filter: CampaignFilterInput
6459+
): campaigns_result
6460+
deploymentCampaigns(
6461+
"A filter to limit the results"
6462+
filter: CampaignFilterInput
6463+
6464+
types: [String!]
6465+
): deployment_campaigns_result
6466+
updateCampaigns(
6467+
"A filter to limit the results"
6468+
filter: CampaignFilterInput
6469+
6470+
types: [String!]
6471+
): update_campaigns_result
6472+
campaign(
6473+
"A filter to limit the results"
6474+
filter: CampaignFilterInput
6475+
6476+
id: ID!
6477+
): campaign_result
6478+
campaignTargetChanged(
6479+
"A filter to limit the results"
6480+
filter: CampaignTargetFilterInput
6481+
): campaign_target_changed_result
6482+
channels(
6483+
"A filter to limit the results"
6484+
filter: ChannelFilterInput
6485+
): channels_result
64146486
deviceChanged(
64156487
"A filter to limit the results"
64166488
filter: DeviceFilterInput
64176489
): device_changed_result
6490+
baseImage(
6491+
"A filter to limit the results"
6492+
filter: BaseImageFilterInput
6493+
): base_image_result
6494+
baseImageCollection(
6495+
"A filter to limit the results"
6496+
filter: BaseImageCollectionFilterInput
6497+
): base_image_collection_result
64186498
}
64196499

64206500
"""

frontend/src/pages/DeploymentCampaign.tsx

Lines changed: 21 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,19 @@
1818
* SPDX-License-Identifier: Apache-2.0
1919
*/
2020

21-
import { Suspense, useCallback, useEffect, useRef, useState } from "react";
21+
import { Suspense, useCallback, useEffect } from "react";
2222
import { useParams } from "react-router-dom";
2323
import { ErrorBoundary } from "react-error-boundary";
2424
import { FormattedMessage } from "react-intl";
2525
import {
26-
fetchQuery,
2726
graphql,
28-
useFragment,
2927
usePreloadedQuery,
30-
useRelayEnvironment,
3128
useQueryLoader,
29+
useSubscription,
3230
} from "react-relay/hooks";
3331
import type { PreloadedQuery } from "react-relay/hooks";
34-
import type { Subscription } from "relay-runtime";
3532

3633
import type { DeploymentCampaign_getCampaign_Query } from "@/api/__generated__/DeploymentCampaign_getCampaign_Query.graphql";
37-
import type { DeploymentCampaign_RefreshFragment$key } from "@/api/__generated__/DeploymentCampaign_RefreshFragment.graphql";
3834

3935
import Center from "@/components/Center";
4036
import Col from "@/components/Col";
@@ -57,7 +53,6 @@ const GET_CAMPAIGN_QUERY = graphql`
5753
name
5854
...DeploymentCampaignForm_CampaignFragment
5955
...CampaignStatsChart_CampaignStatsChartFragment
60-
...DeploymentCampaign_RefreshFragment
6156
...DeploymentTargetsTabs_SuccessfulFragment @arguments(first: $first)
6257
...DeploymentTargetsTabs_FailedFragment @arguments(first: $first)
6358
...DeploymentTargetsTabs_InProgressFragment @arguments(first: $first)
@@ -66,65 +61,21 @@ const GET_CAMPAIGN_QUERY = graphql`
6661
}
6762
`;
6863

69-
const CAMPAIGN_REFRESH_FRAGMENT = graphql`
70-
fragment DeploymentCampaign_RefreshFragment on Campaign {
71-
id
72-
status
73-
}
74-
`;
75-
76-
type DeploymentCampaignRefreshProps = {
77-
campaignRef: DeploymentCampaign_RefreshFragment$key;
78-
};
79-
80-
const DeploymentCampaignRefresh = ({
81-
campaignRef,
82-
}: DeploymentCampaignRefreshProps) => {
83-
const relayEnvironment = useRelayEnvironment();
84-
const { id, status } = useFragment(CAMPAIGN_REFRESH_FRAGMENT, campaignRef);
85-
const [isRefreshing, setIsRefreshing] = useState(false);
86-
87-
// TODO: use GraphQL subscription (when available) to get deployments about Deployment Campaign
88-
const subscriptionRef = useRef<Subscription | null>(null);
89-
useEffect(() => {
90-
return () => {
91-
if (subscriptionRef.current) {
92-
subscriptionRef.current.unsubscribe();
64+
const CAMPAIGN_UPDATE_SUBSCRIPTION = graphql`
65+
subscription DeploymentCampaign_campaignUpdated_Subscription($id: ID!) {
66+
campaign(id: $id) {
67+
updated {
68+
id
69+
status
70+
outcome
71+
idleTargetCount
72+
inProgressTargetCount
73+
failedTargetCount
74+
successfulTargetCount
9375
}
94-
};
95-
}, []);
96-
97-
useEffect(() => {
98-
if (status === "FINISHED" || isRefreshing) {
99-
return;
10076
}
101-
const refreshTimerId = setTimeout(() => {
102-
setIsRefreshing(true);
103-
subscriptionRef.current = fetchQuery(
104-
relayEnvironment,
105-
GET_CAMPAIGN_QUERY,
106-
{
107-
deploymentCampaignId: id,
108-
first: RECORDS_TO_LOAD_FIRST,
109-
},
110-
{ fetchPolicy: "network-only" },
111-
).subscribe({
112-
complete: () => {
113-
setIsRefreshing(false);
114-
},
115-
error: () => {
116-
setIsRefreshing(false);
117-
},
118-
});
119-
}, 10000);
120-
121-
return () => {
122-
clearTimeout(refreshTimerId);
123-
};
124-
}, [id, status, relayEnvironment, isRefreshing, setIsRefreshing]);
125-
126-
return isRefreshing ? <Spinner className="ms-2 mx-auto" /> : null;
127-
};
77+
}
78+
`;
12879

12980
type DeploymentCampaignContentProps = {
13081
getCampaignQuery: PreloadedQuery<DeploymentCampaign_getCampaign_Query>;
@@ -157,9 +108,7 @@ const DeploymentCampaignContent = ({
157108

158109
return (
159110
<Page>
160-
<Page.Header title={campaign.name}>
161-
<DeploymentCampaignRefresh campaignRef={campaign} />
162-
</Page.Header>
111+
<Page.Header title={campaign.name} />
163112
<Page.Main>
164113
<Row>
165114
<Col lg={9}>
@@ -179,6 +128,11 @@ const DeploymentCampaignContent = ({
179128
const DeploymentCampaignPage = () => {
180129
const { deploymentCampaignId = "" } = useParams();
181130

131+
useSubscription({
132+
subscription: CAMPAIGN_UPDATE_SUBSCRIPTION,
133+
variables: { id: deploymentCampaignId },
134+
});
135+
182136
const [getCampaignQuery, getCampaign] =
183137
useQueryLoader<DeploymentCampaign_getCampaign_Query>(GET_CAMPAIGN_QUERY);
184138

frontend/src/pages/DeploymentCampaigns.tsx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@
1818
* SPDX-License-Identifier: Apache-2.0
1919
*/
2020

21-
import { Suspense, useCallback, useEffect } from "react";
21+
import { Suspense, useCallback, useEffect, useMemo } from "react";
2222
import { ErrorBoundary } from "react-error-boundary";
2323
import { FormattedMessage } from "react-intl";
2424
import type { PreloadedQuery } from "react-relay/hooks";
25-
import { graphql, usePreloadedQuery, useQueryLoader } from "react-relay/hooks";
25+
import {
26+
graphql,
27+
usePreloadedQuery,
28+
useQueryLoader,
29+
useSubscription,
30+
} from "react-relay/hooks";
2631

2732
import type { DeploymentCampaigns_getCampaigns_Query } from "@/api/__generated__/DeploymentCampaigns_getCampaigns_Query.graphql";
2833

@@ -44,6 +49,18 @@ const GET_CAMPAIGNS_QUERY = graphql`
4449
}
4550
`;
4651

52+
const CAMPAIGN_UPDATED_SUBSCRIPTION = graphql`
53+
subscription DeploymentCampaigns_campaign_updated_Subscription {
54+
deploymentCampaigns {
55+
updated {
56+
id
57+
status
58+
outcome
59+
}
60+
}
61+
}
62+
`;
63+
4764
interface DeploymentCampaignsContentProps {
4865
getCampaignsQuery: PreloadedQuery<DeploymentCampaigns_getCampaigns_Query>;
4966
}
@@ -90,6 +107,16 @@ const DeploymentCampaignsPage = () => {
90107
[getCampaigns],
91108
);
92109

110+
useSubscription(
111+
useMemo(
112+
() => ({
113+
subscription: CAMPAIGN_UPDATED_SUBSCRIPTION,
114+
variables: {},
115+
}),
116+
[],
117+
),
118+
);
119+
93120
useEffect(fetchCampaigns, [fetchCampaigns]);
94121

95122
return (

0 commit comments

Comments
 (0)