Skip to content

Commit 4f80050

Browse files
committed
handle update
1 parent 27e72a1 commit 4f80050

File tree

5 files changed

+144
-28
lines changed

5 files changed

+144
-28
lines changed

client/src/features/dataConnectorsV2/components/DataConnectorModal/DataConnectorModalBody.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ import type {
3131
AddCloudStorageState,
3232
CloudStorageDetails,
3333
CloudStorageSchema,
34-
CredentialSaveStatus,
3534
} from "../../../project/components/cloudStorage/projectCloudStorage.types";
36-
import { AddCloudStorageSuccessAlert } from "../../../project/components/cloudStorage/cloudStorageModalComponents";
3735
import { getSchemaOptions } from "../../../project/utils/projectCloudStorage.utils";
3836
import {
3937
AddStorageAdvanced,
@@ -46,6 +44,9 @@ import { slugFromTitle } from "../../../../utils/helpers/HelperFunctions";
4644
import type { CloudStorageSecretGet } from "../../../projectsV2/api/storagesV2.api";
4745

4846
import { type DataConnectorFlat } from "../dataConnector.utils";
47+
import DataConnectorModalResult, {
48+
type CredentialSaveStatus,
49+
} from "./DataConnectorModalResult";
4950
import DataConnectorSaveCredentialsInfo from "./DataConnectorSaveCredentialsInfo";
5051

5152
interface AddOrEditDataConnectorProps {
@@ -59,7 +60,7 @@ interface AddOrEditDataConnectorProps {
5960
}
6061

6162
interface DataConnectorModalBodyProps {
62-
addResultStorageName: string | undefined;
63+
dataConnectorName: string | undefined;
6364
flatDataConnector: DataConnectorFlat;
6465
credentialSaveStatus: CredentialSaveStatus;
6566
redraw: boolean;
@@ -77,7 +78,7 @@ interface DataConnectorModalBodyProps {
7778
type SchemaQueryResult = ReturnType<typeof useGetCloudStorageSchemaQuery>;
7879

7980
export default function DataConnectorModalBody({
80-
addResultStorageName,
81+
dataConnectorName,
8182
flatDataConnector,
8283
credentialSaveStatus,
8384
redraw,
@@ -97,12 +98,10 @@ export default function DataConnectorModalBody({
9798
if (redraw) return <Loader />;
9899
if (success) {
99100
return (
100-
<AddCloudStorageSuccessAlert
101-
{...{
102-
addResultStorageName,
103-
storageId: flatDataConnector.dataConnectorId ?? null,
104-
credentialSaveStatus,
105-
}}
101+
<DataConnectorModalResult
102+
alreadyExisted={!!flatDataConnector.dataConnectorId}
103+
credentialSaveStatus={credentialSaveStatus}
104+
dataConnectorName={dataConnectorName}
106105
/>
107106
);
108107
}
@@ -222,6 +221,8 @@ export function DataConnectorMount({
222221
mode: "onChange",
223222
defaultValues: {
224223
name: flatDataConnector.name || "",
224+
namespace: flatDataConnector.namespace || "",
225+
slug: flatDataConnector.slug || "",
225226
mountPoint:
226227
flatDataConnector.mountPoint ||
227228
`${flatDataConnector.schema?.toLowerCase()}`,
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*!
2+
* Copyright 2024 - Swiss Data Science Center (SDSC)
3+
* A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
4+
* Eidgenössische Technische Hochschule Zürich (ETHZ).
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import { SuccessAlert } from "../../../../components/Alert";
20+
export type CredentialSaveStatus = "failure" | "none" | "success" | "trying";
21+
22+
interface DataConnectorModalResultProps {
23+
alreadyExisted: boolean;
24+
credentialSaveStatus: CredentialSaveStatus;
25+
dataConnectorName: string | undefined;
26+
}
27+
28+
export default function DataConnectorModalResult({
29+
dataConnectorName,
30+
credentialSaveStatus,
31+
alreadyExisted,
32+
}: DataConnectorModalResultProps) {
33+
if (credentialSaveStatus == "trying")
34+
return (
35+
<SuccessAlert dismissible={false} timeout={0}>
36+
<p className="mb-0">
37+
The data connector {dataConnectorName} has been successfully{" "}
38+
{alreadyExisted ? "updated" : "added"}; saving the credentials...
39+
</p>
40+
</SuccessAlert>
41+
);
42+
43+
if (credentialSaveStatus == "success")
44+
return (
45+
<SuccessAlert dismissible={false} timeout={0}>
46+
<p className="mb-0">
47+
The data connector {dataConnectorName} has been successfully{" "}
48+
{alreadyExisted ? "updated" : "added"}, along with its credentials.
49+
</p>
50+
</SuccessAlert>
51+
);
52+
if (credentialSaveStatus == "failure")
53+
return (
54+
<SuccessAlert dismissible={false} timeout={0}>
55+
<p className="mb-0">
56+
The data connector {dataConnectorName} has been successfully{" "}
57+
{alreadyExisted ? "updated" : "added"},{" "}
58+
<b>but the credentials were not saved</b>. You can re-enter them and
59+
save by editing the storage.
60+
</p>
61+
</SuccessAlert>
62+
);
63+
64+
return (
65+
<SuccessAlert dismissible={false} timeout={0}>
66+
<p className="mb-0">
67+
The data connector {dataConnectorName} has been successfully{" "}
68+
{alreadyExisted ? "updated" : "added"}.
69+
</p>
70+
</SuccessAlert>
71+
);
72+
}

client/src/features/dataConnectorsV2/components/DataConnectorModal/index.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import {
3737
import {
3838
AddCloudStorageState,
3939
CloudStorageDetailsOptions,
40-
CredentialSaveStatus,
4140
TestCloudStorageConnectionParams,
4241
} from "../../../project/components/cloudStorage/projectCloudStorage.types";
4342

@@ -62,6 +61,7 @@ import {
6261
DataConnectorConnectionTestResult,
6362
} from "./dataConnectorModalButtons";
6463
import DataConnectorModalBody from "./DataConnectorModalBody";
64+
import type { CredentialSaveStatus } from "./DataConnectorModalResult";
6565
import {
6666
dataConnectorPostFromFlattened,
6767
dataConnectorToFlattened,
@@ -368,7 +368,8 @@ export default function DataConnectorModal({
368368
const isModifyResultLoading = updateResult.isLoading;
369369
const addResultError = createResult.error;
370370
const modifyResultError = updateResult.error;
371-
const addResultStorageName = createResult?.data?.name;
371+
const dataConnectorName =
372+
createResult?.data?.name || updateResult?.data?.name;
372373

373374
const disableAddButton =
374375
isAddResultLoading ||
@@ -417,7 +418,7 @@ export default function DataConnectorModal({
417418

418419
<ModalBody data-cy="cloud-storage-edit-body">
419420
<DataConnectorModalBody
420-
addResultStorageName={addResultStorageName}
421+
dataConnectorName={dataConnectorName}
421422
flatDataConnector={flatDataConnector}
422423
credentialSaveStatus={credentialSaveStatus}
423424
redraw={redraw}

tests/cypress/e2e/groupV2.spec.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ describe("Work with group data connectors", () => {
273273
.listGroupV2Members()
274274
.listProjectV2ByNamespace()
275275
.listDataConnectors({ namespace: "test-2-group-v2" })
276-
.postDataConnector();
276+
.testCloudStorage({ success: false })
277+
.postDataConnector({ namespace: "test-2-group-v2" });
277278
cy.contains("test 2 group-v2").should("be.visible").click();
278279
cy.wait("@readGroupV2");
279280
cy.contains("public-storage").should("be.visible");
@@ -297,7 +298,36 @@ describe("Work with group data connectors", () => {
297298
cy.wait("@postDataConnector");
298299
cy.getDataCy("cloud-storage-edit-body").should(
299300
"contain.text",
300-
"The storage example-storage has been successfully added."
301+
"The data connector example-storage has been successfully added."
302+
);
303+
cy.getDataCy("data-connector-edit-close-button").click();
304+
cy.wait("@getDataConnectors");
305+
});
306+
307+
it("edit a group data connector", () => {
308+
fixtures
309+
.getStorageSchema({ fixture: "cloudStorage/storage-schema-s3.json" })
310+
.readGroupV2()
311+
.readGroupV2Namespace()
312+
.listGroupV2Members()
313+
.listProjectV2ByNamespace()
314+
.listDataConnectors({ namespace: "test-2-group-v2" })
315+
.testCloudStorage({ success: true })
316+
.patchDataConnector({ namespace: "test-2-group-v2" });
317+
cy.contains("test 2 group-v2").should("be.visible").click();
318+
cy.wait("@readGroupV2");
319+
cy.contains("public-storage").should("be.visible").click();
320+
cy.getDataCy("data-connector-edit").should("be.visible").click();
321+
// Fill out the details
322+
cy.getDataCy("test-data-connector-button").click();
323+
cy.getDataCy("add-data-connector-continue-button")
324+
.contains("Continue")
325+
.click();
326+
cy.getDataCy("data-connector-edit-update-button").click();
327+
cy.wait("@patchDataConnector");
328+
cy.getDataCy("cloud-storage-edit-body").should(
329+
"contain.text",
330+
"The data connector example-storage has been successfully updated."
301331
);
302332
cy.getDataCy("data-connector-edit-close-button").click();
303333
cy.wait("@getDataConnectors");

tests/cypress/support/renkulab-fixtures/dataConnectors.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,19 +144,31 @@ export function DataConnector<T extends FixturesConstructor>(Parent: T) {
144144
return this;
145145
}
146146

147-
// patchDataConnector(args?: DataConnectorArgs) {
148-
// const { name = "patchDataConnector" } = args ?? {};
149-
// const response = {
150-
// statusCode: 201,
151-
// fixture: "dataConnector/new-data-connector.json",
152-
// };
153-
// cy.intercept(
154-
// "PATCH",
155-
// "/ui-server/api/data/data_connectors/*",
156-
// response
157-
// ).as(name);
158-
// return this;
159-
// }
147+
patchDataConnector(args?: DataConnectorArgs) {
148+
const {
149+
fixture = "dataConnector/new-data-connector.json",
150+
name = "patchDataConnector",
151+
namespace,
152+
} = args ?? {};
153+
cy.fixture(fixture).then((dataConnector) => {
154+
// eslint-disable-next-line max-nested-callbacks
155+
cy.intercept(
156+
"PATCH",
157+
"/ui-server/api/data/data_connectors/*",
158+
(req) => {
159+
const newDataConnector = req.body;
160+
expect(newDataConnector.namespace).to.not.be.undefined;
161+
expect(newDataConnector.slug).to.not.be.undefined;
162+
expect(newDataConnector.visibility).to.not.be.undefined;
163+
if (namespace) {
164+
expect(newDataConnector.namespace).equal(namespace);
165+
}
166+
req.reply({ body: dataConnector, statusCode: 201, delay: 1000 });
167+
}
168+
).as(name);
169+
});
170+
return this;
171+
}
160172

161173
// deleteDataConnector(args?: DataConnectorArgs) {
162174
// const { name = "deleteDataConnector" } = args ?? {};

0 commit comments

Comments
 (0)