Skip to content

Commit a948d7f

Browse files
committed
wip: update device image by using base image from collection
Signed-off-by: Damiano Mason <damiano.mason@secomind.com>
1 parent c45109b commit a948d7f

6 files changed

Lines changed: 650 additions & 53 deletions

File tree

frontend/src/components/BaseImageSelect.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ const BASE_IMAGE_SELECT_OPTIONS_FRAGMENT = graphql`
7474
id
7575
name
7676
version
77+
url
7778
}
7879
}
7980
}

frontend/src/components/DeviceTabs/SoftwareUpdateTab.tsx

Lines changed: 123 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,14 @@
1818
* SPDX-License-Identifier: Apache-2.0
1919
*/
2020

21-
import React, { useEffect, useState, useRef } from "react";
21+
import React, {
22+
useEffect,
23+
useState,
24+
useRef,
25+
useCallback,
26+
Suspense,
27+
useMemo,
28+
} from "react";
2229
import type { Subscription } from "relay-runtime";
2330
import { FormattedMessage, useIntl } from "react-intl";
2431
import {
@@ -27,17 +34,24 @@ import {
2734
fetchQuery,
2835
useRelayEnvironment,
2936
usePaginationFragment,
37+
usePreloadedQuery,
38+
PreloadedQuery,
39+
UseMutationConfig,
3040
} from "react-relay/hooks";
3141

3242
import type { SoftwareUpdateTab_PaginationQuery } from "@/api/__generated__/SoftwareUpdateTab_PaginationQuery.graphql";
3343
import type { SoftwareUpdateTab_otaOperations$key } from "@/api/__generated__/SoftwareUpdateTab_otaOperations.graphql";
34-
import type { SoftwareUpdateTab_createManualOtaOperation_Mutation } from "@/api/__generated__/SoftwareUpdateTab_createManualOtaOperation_Mutation.graphql";
44+
// import type { SoftwareUpdateTab_createManualOtaOperation_Mutation } from "@/api/__generated__/SoftwareUpdateTab_createManualOtaOperation_Mutation.graphql";
3545

3646
import Alert from "@/components/Alert";
3747
import OperationTable from "@/components/OperationTable";
3848
import Spinner from "@/components/Spinner";
3949
import { Tab } from "@/components/Tabs";
4050
import BaseImageForm from "@/forms/BaseImageForm";
51+
import { Device_getBaseImageCollections_Query } from "@/api/__generated__/Device_getBaseImageCollections_Query.graphql";
52+
import { GET_BASE_IMAGE_COLL_QUERY } from "@/pages/Device";
53+
import { SoftwareUpdateTab_createManualOtaOperationNoExistingBaseImage_Mutation, SoftwareUpdateTab_createManualOtaOperationNoExistingBaseImage_Mutation$data } from "@/api/__generated__/SoftwareUpdateTab_createManualOtaOperationNoExistingBaseImage_Mutation.graphql";
54+
import { SoftwareUpdateTab_createManualOtaOperationExistingBaseImage_Mutation, SoftwareUpdateTab_createManualOtaOperationExistingBaseImage_Mutation$data } from "@/api/__generated__/SoftwareUpdateTab_createManualOtaOperationExistingBaseImage_Mutation.graphql";
4155

4256
const DEVICE_OTA_OPERATIONS_FRAGMENT = graphql`
4357
fragment SoftwareUpdateTab_otaOperations on Device
@@ -73,11 +87,11 @@ const GET_DEVICE_OTA_OPERATIONS_QUERY = graphql`
7387
}
7488
`;
7589

76-
const DEVICE_CREATE_MANUAL_OTA_OPERATION_MUTATION = graphql`
77-
mutation SoftwareUpdateTab_createManualOtaOperation_Mutation(
78-
$input: CreateManualOtaOperationInput!
90+
const DEVICE_CREATE_MANUAL_OTA_OPERATION_NO_EXISTING_IMAGE_MUTATION = graphql`
91+
mutation SoftwareUpdateTab_createManualOtaOperationNoExistingBaseImage_Mutation(
92+
$input: CreateManualOtaOperationNoExistingBaseImageInput!
7993
) {
80-
createManualOtaOperation(input: $input) {
94+
createManualOtaOperationNoExistingBaseImage(input: $input) {
8195
result {
8296
id
8397
baseImageUrl
@@ -90,12 +104,47 @@ const DEVICE_CREATE_MANUAL_OTA_OPERATION_MUTATION = graphql`
90104
}
91105
`;
92106

107+
const DEVICE_CREATE_MANUAL_OTA_OPERATION_EXISTING_IMAGE_MUTATION = graphql`
108+
mutation SoftwareUpdateTab_createManualOtaOperationExistingBaseImage_Mutation(
109+
$input: CreateManualOtaOperationExistingBaseImageInput!
110+
) {
111+
createManualOtaOperationExistingBaseImage(input: $input) {
112+
result {
113+
id
114+
baseImageUrl
115+
createdAt
116+
status
117+
statusCode
118+
updatedAt
119+
}
120+
}
121+
}
122+
`;
123+
124+
export type GetBaseImageCollsQueryType = PreloadedQuery<
125+
Device_getBaseImageCollections_Query,
126+
Record<string, unknown>
127+
>;
128+
129+
type OTAOperationFunctionIncompleteVariables = {
130+
input: {
131+
deviceId: string;
132+
baseImageFile?: File;
133+
baseImageUrl?: string;
134+
}
135+
};
136+
137+
type OTAOperationFunctionVariables = UseMutationConfig<SoftwareUpdateTab_createManualOtaOperationNoExistingBaseImage_Mutation>["variables"] & UseMutationConfig<SoftwareUpdateTab_createManualOtaOperationExistingBaseImage_Mutation>["variables"]
138+
type NoExistingImageMutationName = "createManualOtaOperationNoExistingBaseImage" | "createManualOtaOperationExistingBaseImage"
139+
93140
type DeviceSoftwareUpdateTabProps = {
94141
deviceRef: SoftwareUpdateTab_otaOperations$key;
142+
getBaseImageCollsQuery: GetBaseImageCollsQueryType;
95143
};
96144

97145
const DeviceSoftwareUpdateTab = ({
98146
deviceRef,
147+
getBaseImageCollsQuery,
99148
}: DeviceSoftwareUpdateTabProps) => {
100149
const [isRefreshing, setIsRefreshing] = useState(false);
101150
const [errorFeedback, setErrorFeedback] = useState<React.ReactNode>(null);
@@ -109,10 +158,34 @@ const DeviceSoftwareUpdateTab = ({
109158

110159
const deviceId = data.id;
111160

112-
const [createOtaOperation, isCreatingOtaOperation] =
113-
useMutation<SoftwareUpdateTab_createManualOtaOperation_Mutation>(
114-
DEVICE_CREATE_MANUAL_OTA_OPERATION_MUTATION,
161+
const [createOtaOperationNoExistingImage, isCreatingOtaOperationNoExistingImage] =
162+
useMutation<SoftwareUpdateTab_createManualOtaOperationNoExistingBaseImage_Mutation>(
163+
DEVICE_CREATE_MANUAL_OTA_OPERATION_NO_EXISTING_IMAGE_MUTATION,
115164
);
165+
const [createOtaOperationExistingImage, isCreatingOtaOperationExistingImage] =
166+
useMutation<SoftwareUpdateTab_createManualOtaOperationExistingBaseImage_Mutation>(
167+
DEVICE_CREATE_MANUAL_OTA_OPERATION_EXISTING_IMAGE_MUTATION,
168+
);
169+
const pickOTAOperationFunction = useCallback((...input: Array<File|string> ) => {
170+
const variables: OTAOperationFunctionIncompleteVariables = {
171+
input: {
172+
deviceId,
173+
},
174+
}
175+
if (input.length === 1) {
176+
const [baseImage] = input;
177+
if (baseImage instanceof File) {
178+
variables.input.baseImageFile = baseImage
179+
return {func: createOtaOperationNoExistingImage, vars: variables as UseMutationConfig<SoftwareUpdateTab_createManualOtaOperationNoExistingBaseImage_Mutation>["variables"]}
180+
}
181+
else if (typeof baseImage === "string") {
182+
variables.input.baseImageUrl = baseImage
183+
return {func: createOtaOperationExistingImage, vars: variables as UseMutationConfig<SoftwareUpdateTab_createManualOtaOperationExistingBaseImage_Mutation>["variables"]}
184+
}
185+
}
186+
}, [createOtaOperationNoExistingImage, createOtaOperationExistingImage])
187+
188+
const isCreatingOtaOperation = useMemo(() => isCreatingOtaOperationNoExistingImage || isCreatingOtaOperationExistingImage, [isCreatingOtaOperationNoExistingImage, isCreatingOtaOperationExistingImage])
116189

117190
const otaOperations = (
118191
data.otaOperations?.edges?.map(({ node }) => node) || []
@@ -186,14 +259,11 @@ const DeviceSoftwareUpdateTab = ({
186259
return null;
187260
}
188261

189-
const launchManualOTAUpdate = (file: File) => {
262+
const launchManualOTAUpdate = (...input: Array<File|string>) => {
263+
const {func: createOtaOperation, vars: variables} = pickOTAOperationFunction(...input)
264+
console.log("vars after picking:", variables);
190265
createOtaOperation({
191-
variables: {
192-
input: {
193-
deviceId,
194-
baseImageFile: file,
195-
},
196-
},
266+
variables: variables as OTAOperationFunctionVariables,
197267
onCompleted(data, errors) {
198268
if (errors) {
199269
const errorFeedback = errors
@@ -213,7 +283,15 @@ const DeviceSoftwareUpdateTab = ({
213283
);
214284
},
215285
updater(store, data) {
216-
const otaOperationId = data?.createManualOtaOperation?.result?.id;
286+
if (data) {
287+
let mutData: SoftwareUpdateTab_createManualOtaOperationNoExistingBaseImage_Mutation$data["createManualOtaOperationNoExistingBaseImage"] | SoftwareUpdateTab_createManualOtaOperationExistingBaseImage_Mutation$data["createManualOtaOperationExistingBaseImage"] | undefined;
288+
if("createManualOtaOperationNoExistingBaseImage" in data) {
289+
mutData = data.createManualOtaOperationNoExistingBaseImage
290+
}
291+
else if (data && "createManualOtaOperationExistingBaseImage" in data) {
292+
mutData = data.createManualOtaOperationExistingBaseImage
293+
}
294+
const otaOperationId = mutData?.result?.id;
217295
if (otaOperationId) {
218296
const otaOperation = store.get(otaOperationId);
219297
const storedDevice = store.get(deviceId);
@@ -225,10 +303,16 @@ const DeviceSoftwareUpdateTab = ({
225303
);
226304
}
227305
}
306+
}
228307
},
229308
});
230309
};
231310

311+
const baseImageCollections = usePreloadedQuery(
312+
GET_BASE_IMAGE_COLL_QUERY,
313+
getBaseImageCollsQuery,
314+
);
315+
232316
return (
233317
<Tab
234318
eventKey="device-software-update-tab"
@@ -252,11 +336,14 @@ const DeviceSoftwareUpdateTab = ({
252336
>
253337
{errorFeedback}
254338
</Alert>
255-
<BaseImageForm
256-
className="mt-3"
257-
onSubmit={launchManualOTAUpdate}
258-
isLoading={isCreatingOtaOperation}
259-
/>
339+
<Suspense fallback={<Spinner />}>
340+
<BaseImageForm
341+
className="mt-3"
342+
onManualOTAImageSubmit={launchManualOTAUpdate}
343+
isLoading={isCreatingOtaOperation}
344+
baseImageCollectionsData={baseImageCollections}
345+
/>
346+
</Suspense>
260347
{currentOperation && (
261348
<div className="mt-3">
262349
<FormattedMessage
@@ -290,4 +377,18 @@ const DeviceSoftwareUpdateTab = ({
290377
);
291378
};
292379

380+
export const DisabledDeviceSoftwareTab = ({}) => {
381+
const intl = useIntl();
382+
return (
383+
<Tab
384+
className="disabled"
385+
eventKey="device-software-update-tab"
386+
title={intl.formatMessage({
387+
id: "components.DeviceTabs.SoftwareUpdateTab",
388+
defaultMessage: "Software Updates",
389+
})}
390+
/>
391+
);
392+
};
393+
293394
export default DeviceSoftwareUpdateTab;

0 commit comments

Comments
 (0)