Skip to content

Commit da51bb4

Browse files
committed
feat: data-connectors support on group and user namespace pages
1 parent 765e524 commit da51bb4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+5583
-118
lines changed

client/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"storybook-wait-server": "wait-on http://127.0.0.1:6006",
2323
"storybook-test": "test-storybook",
2424
"storybook-compile-and-test": "concurrently -k -s first -n 'BUILD,TEST' -c 'magenta,blue' 'npm run storybook-build && npm run storybook-start-server' 'npm run storybook-wait-server && npm run storybook-test'",
25-
"generate-api": "npm run generate-api:dataServicesUser && npm run generate-api:namespaceV2 && npm run generate-api:projectV2 && npm run generate-api:platform && npm run generate-api:searchV2 && npm run generate-api:storages",
25+
"generate-api": "npm run generate-api:data-connectors && npm run generate-api:dataServicesUser && npm run generate-api:namespaceV2 && npm run generate-api:projectV2 && npm run generate-api:platform && npm run generate-api:searchV2 && npm run generate-api:storages",
26+
"generate-api:data-connectors": "rtk-query-codegen-openapi src/features/projectsV2/api/data-connectors.api-config.ts",
2627
"generate-api:dataServicesUser": "rtk-query-codegen-openapi src/features/user/dataServicesUser.api/dataServicesUser.api-config.ts",
2728
"generate-api:namespaceV2": "rtk-query-codegen-openapi src/features/projectsV2/api/namespace.api-config.ts",
2829
"generate-api:projectV2": "rtk-query-codegen-openapi src/features/projectsV2/api/projectV2.api-config.ts",

client/src/features/ProjectPageV2/ProjectPageContent/DataSources/DataSourceCredentialsModal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
} from "../../../projectsV2/api/projectV2.enhanced-api";
2929
import type { CloudStorageGetRead } from "../../../projectsV2/api/storagesV2.api";
3030
import type { SessionStartCloudStorageConfiguration } from "../../../sessionsV2/startSessionOptionsV2.types";
31-
import CloudStorageSecretsModal from "../../../sessionsV2/DataConnectorSecretsModal";
31+
import DataStorageSecretsModal from "../../../sessionsV2/DataStorageSecretsModal";
3232

3333
import useDataSourceConfiguration from "./useDataSourceConfiguration.hook";
3434
import { Loader } from "../../../../components/Loader";
@@ -188,7 +188,7 @@ export default function DataSourceCredentialsModal({
188188
}
189189

190190
return (
191-
<CloudStorageSecretsModal
191+
<DataStorageSecretsModal
192192
cloudStorageConfigs={cloudStorageConfigs}
193193
context="storage"
194194
isOpen={isOpen}

client/src/features/ProjectPageV2/ProjectPageContent/DataSources/DataSourceDisplay.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
} from "reactstrap";
3232

3333
import { Loader } from "../../../../components/Loader";
34-
import DataConnectorModal from "../../../dataConnectorsV2/components/DataConnectorModal";
34+
import DataSourceModal from "./DataSourceModal";
3535
import {
3636
type CloudStorageGetRead,
3737
useDeleteStoragesV2ByStorageIdMutation,
@@ -174,7 +174,7 @@ export function DataSourceActions({
174174
isOpen={isDeleteOpen}
175175
toggleModal={toggleDelete}
176176
/>
177-
<DataConnectorModal
177+
<DataSourceModal
178178
currentStorage={storage}
179179
isOpen={isEditOpen}
180180
toggle={toggleEdit}

client/src/features/dataConnectorsV2/components/DataConnectorModal.tsx renamed to client/src/features/ProjectPageV2/ProjectPageContent/DataSources/DataSourceModal.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,53 +23,53 @@ import { useCallback, useEffect, useMemo, useState } from "react";
2323
import { ArrowCounterclockwise } from "react-bootstrap-icons";
2424
import { Button, Modal, ModalBody, ModalFooter, ModalHeader } from "reactstrap";
2525

26-
import { RtkOrNotebooksError } from "../../../components/errors/RtkErrorAlert";
27-
import { usePostStoragesV2ByStorageIdSecretsMutation } from "../../projectsV2/api/projectV2.enhanced-api";
26+
import { RtkOrNotebooksError } from "../../../../components/errors/RtkErrorAlert";
27+
import { usePostStoragesV2ByStorageIdSecretsMutation } from "../../../projectsV2/api/projectV2.enhanced-api";
2828
import {
2929
CloudStorageGetV2Read,
3030
CloudStoragePatch,
3131
PostStoragesV2ApiArg,
3232
RCloneConfig,
3333
usePatchStoragesV2ByStorageIdMutation,
3434
usePostStoragesV2Mutation,
35-
} from "../../projectsV2/api/storagesV2.api";
35+
} from "../../../projectsV2/api/storagesV2.api";
3636

37-
import AddStorageBreadcrumbNavbar from "../../project/components/cloudStorage/AddStorageBreadcrumbNavbar";
37+
import AddStorageBreadcrumbNavbar from "../../../project/components/cloudStorage/AddStorageBreadcrumbNavbar";
3838
import {
3939
useGetCloudStorageSchemaQuery,
4040
useTestCloudStorageConnectionMutation,
41-
} from "../../project/components/cloudStorage/projectCloudStorage.api";
41+
} from "../../../project/components/cloudStorage/projectCloudStorage.api";
4242
import {
4343
CLOUD_STORAGE_SENSITIVE_FIELD_TOKEN,
4444
CLOUD_STORAGE_TOTAL_STEPS,
4545
EMPTY_CLOUD_STORAGE_DETAILS,
4646
EMPTY_CLOUD_STORAGE_STATE,
47-
} from "../../project/components/cloudStorage/projectCloudStorage.constants";
47+
} from "../../../project/components/cloudStorage/projectCloudStorage.constants";
4848
import {
4949
AddCloudStorageForProjectParams,
5050
AddCloudStorageState,
5151
CloudStorageDetails,
5252
CloudStorageDetailsOptions,
5353
CredentialSaveStatus,
5454
TestCloudStorageConnectionParams,
55-
} from "../../project/components/cloudStorage/projectCloudStorage.types";
55+
} from "../../../project/components/cloudStorage/projectCloudStorage.types";
5656

5757
import {
5858
AddCloudStorageContinueButton,
5959
AddCloudStorageBackButton,
6060
AddCloudStorageConnectionTestResult,
6161
AddCloudStorageHeaderContent,
62-
} from "../../project/components/cloudStorage/cloudStorageModalComponents";
62+
} from "../../../project/components/cloudStorage/cloudStorageModalComponents";
6363
import {
6464
findSensitive,
6565
getCurrentStorageDetails,
6666
getSchemaProviders,
6767
hasProviderShortlist,
68-
} from "../../project/utils/projectCloudStorage.utils";
68+
} from "../../../project/utils/projectCloudStorage.utils";
6969

70-
import styles from "../../project/components/cloudStorage/CloudStorage.module.scss";
70+
import styles from "../../../project/components/cloudStorage/CloudStorage.module.scss";
7171

72-
import DataConnectorModalBody from "./DataConnectorModalBody";
72+
import DataSourceModalBody from "./DataSourceModalBody";
7373

7474
interface DataConnectorModalProps {
7575
currentStorage?: CloudStorageGetV2Read | null;
@@ -484,7 +484,7 @@ export default function DataConnectorModal({
484484
</ModalHeader>
485485

486486
<ModalBody data-cy="cloud-storage-edit-body">
487-
<DataConnectorModalBody
487+
<DataSourceModalBody
488488
addResultStorageName={addResultStorageName}
489489
credentialSaveStatus={credentialSaveStatus}
490490
isV2={true}

client/src/features/dataConnectorsV2/components/DataConnectorModalBody.tsx renamed to client/src/features/ProjectPageV2/ProjectPageContent/DataSources/DataSourceModalBody.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,27 @@
1818

1919
import cx from "classnames";
2020

21-
import { Loader } from "../../../components/Loader";
22-
import { RtkOrNotebooksError } from "../../../components/errors/RtkErrorAlert";
21+
import { Loader } from "../../../../components/Loader";
22+
import { RtkOrNotebooksError } from "../../../../components/errors/RtkErrorAlert";
2323

24-
import { CLOUD_STORAGE_TOTAL_STEPS } from "../../project/components/cloudStorage/projectCloudStorage.constants";
24+
import { CLOUD_STORAGE_TOTAL_STEPS } from "../../../project/components/cloudStorage/projectCloudStorage.constants";
2525
import type {
2626
AddCloudStorageState,
2727
CloudStorageDetails,
2828
CloudStorageSchema,
29-
} from "../../project/components/cloudStorage/projectCloudStorage.types";
29+
} from "../../../project/components/cloudStorage/projectCloudStorage.types";
3030
import {
3131
AddCloudStorageSuccessAlert,
3232
type AddCloudStorageBodyContentProps,
33-
} from "../../project/components/cloudStorage/cloudStorageModalComponents";
33+
} from "../../../project/components/cloudStorage/cloudStorageModalComponents";
3434
import {
3535
AddStorageAdvanced,
3636
AddStorageAdvancedToggle,
3737
AddStorageMount,
3838
AddStorageOptions,
3939
AddStorageType,
40-
} from "../../project/components/cloudStorage/AddOrEditCloudStorage";
41-
import type { CloudStorageSecretGet } from "../../projectsV2/api/storagesV2.api";
40+
} from "../../../project/components/cloudStorage/AddOrEditCloudStorage";
41+
import type { CloudStorageSecretGet } from "../../../projectsV2/api/storagesV2.api";
4242

4343
interface AddOrEditCloudStorageProps {
4444
schema: CloudStorageSchema[];

client/src/features/ProjectPageV2/ProjectPageContent/DataSources/DataSourcesBox.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ import cx from "classnames";
1919
import { useCallback, useState } from "react";
2020
import { Database, PlusLg } from "react-bootstrap-icons";
2121
import { Loader } from "../../../../components/Loader";
22-
import DataConnectorModal from "../../../dataConnectorsV2/components/DataConnectorModal";
2322
import { Project } from "../../../projectsV2/api/projectV2.api";
2423
import { useGetStoragesV2Query } from "../../../projectsV2/api/storagesV2.api";
2524
import AccessGuard from "../../utils/AccessGuard";
2625
import useProjectAccess from "../../utils/useProjectAccess.hook";
2726
import { DataSourceDisplay } from "./DataSourceDisplay";
27+
import DataSourceModal from "./DataSourceModal";
2828
import {
2929
Badge,
3030
Button,
@@ -117,7 +117,7 @@ export function DataSourcesDisplay({ project }: { project: Project }) {
117117
</ListGroup>
118118
)}
119119
</CardBody>
120-
<DataConnectorModal
120+
<DataSourceModal
121121
currentStorage={null}
122122
isOpen={isOpen}
123123
toggle={toggle}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
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+
import cx from "classnames";
19+
import { useCallback, useEffect, useState } from "react";
20+
import { Lock, Pencil, Trash, XLg } from "react-bootstrap-icons";
21+
import {
22+
Button,
23+
Col,
24+
DropdownItem,
25+
Modal,
26+
ModalBody,
27+
ModalFooter,
28+
ModalHeader,
29+
Row,
30+
} from "reactstrap";
31+
32+
import { Loader } from "../../../components/Loader";
33+
import DataConnectorModal from "./DataConnectorModal";
34+
import type { DataConnectorRead } from "../../projectsV2/api/data-connectors.api";
35+
import { useDeleteDataConnectorsByDataConnectorIdMutation } from "../../projectsV2/api/projectV2.enhanced-api";
36+
import DataConnectorCredentialsModal from "./DataConnectorCredentialsModal";
37+
import { ButtonWithMenuV2 } from "../../../components/buttons/Button";
38+
39+
interface DataConnectorDeleteModalProps {
40+
dataConnector: DataConnectorRead;
41+
isOpen: boolean;
42+
toggleModal: () => void;
43+
}
44+
function DataConnectorDeleteModal({
45+
dataConnector,
46+
toggleModal,
47+
isOpen,
48+
}: DataConnectorDeleteModalProps) {
49+
const [deleteDataConnector, { isLoading, isSuccess }] =
50+
useDeleteDataConnectorsByDataConnectorIdMutation();
51+
52+
useEffect(() => {
53+
if (isSuccess) {
54+
toggleModal();
55+
}
56+
}, [isSuccess, toggleModal]);
57+
const onDeleteDataCollector = () => {
58+
deleteDataConnector({
59+
dataConnectorId: dataConnector.id,
60+
});
61+
};
62+
63+
return (
64+
<Modal size="lg" isOpen={isOpen} toggle={toggleModal} centered>
65+
<ModalHeader className="text-danger" toggle={toggleModal}>
66+
Delete data connector
67+
</ModalHeader>
68+
<ModalBody>
69+
<Row>
70+
<Col>
71+
<p>
72+
Are you sure you want to delete this data connector? It will
73+
affect all projects that use it.
74+
</p>
75+
<p className="mb-0">
76+
Data connector: <code>{dataConnector.name}</code>
77+
</p>
78+
</Col>
79+
</Row>
80+
</ModalBody>
81+
<ModalFooter>
82+
<div className="d-flex justify-content-end">
83+
<Button color="outline-danger" onClick={toggleModal}>
84+
<XLg className={cx("bi", "me-1")} />
85+
Cancel
86+
</Button>
87+
<Button
88+
color="danger"
89+
className={cx("float-right", "ms-2")}
90+
data-cy="delete-data-connector-modal-button"
91+
type="submit"
92+
onClick={onDeleteDataCollector}
93+
>
94+
{isLoading ? (
95+
<>
96+
<Loader className="me-1" inline size={16} />
97+
Deleting data connector
98+
</>
99+
) : (
100+
<>
101+
<Trash className={cx("bi", "me-1")} />
102+
Remove data connector
103+
</>
104+
)}
105+
</Button>
106+
</div>
107+
</ModalFooter>
108+
</Modal>
109+
);
110+
}
111+
export default function DataConnectorActions({
112+
dataConnector,
113+
}: {
114+
dataConnector: DataConnectorRead;
115+
}) {
116+
const [isCredentialsOpen, setCredentialsOpen] = useState(false);
117+
const [isDeleteOpen, setIsDeleteOpen] = useState(false);
118+
const [isEditOpen, setIsEditOpen] = useState(false);
119+
const toggleCredentials = useCallback(() => {
120+
setCredentialsOpen((open) => !open);
121+
}, []);
122+
const toggleDelete = useCallback(() => {
123+
setIsDeleteOpen((open) => !open);
124+
}, []);
125+
const toggleEdit = useCallback(() => {
126+
setIsEditOpen((open) => !open);
127+
}, []);
128+
129+
const defaultAction = (
130+
<Button
131+
className="text-nowrap"
132+
color="outline-primary"
133+
data-cy="data-connector-edit"
134+
onClick={toggleEdit}
135+
size="sm"
136+
>
137+
<Pencil className={cx("bi", "me-1")} />
138+
Edit
139+
</Button>
140+
);
141+
142+
return (
143+
<>
144+
<ButtonWithMenuV2
145+
color="outline-primary"
146+
default={defaultAction}
147+
preventPropagation
148+
size="sm"
149+
>
150+
<DropdownItem
151+
data-cy="data-connector-credentials"
152+
onClick={toggleCredentials}
153+
>
154+
<Lock className={cx("bi", "me-1")} />
155+
Credentials
156+
</DropdownItem>
157+
<DropdownItem data-cy="data-connector-delete" onClick={toggleDelete}>
158+
<Trash className={cx("bi", "me-1")} />
159+
Remove
160+
</DropdownItem>
161+
</ButtonWithMenuV2>
162+
<DataConnectorCredentialsModal
163+
dataConnector={dataConnector}
164+
setOpen={setCredentialsOpen}
165+
isOpen={isCredentialsOpen}
166+
/>
167+
<DataConnectorDeleteModal
168+
dataConnector={dataConnector}
169+
isOpen={isDeleteOpen}
170+
toggleModal={toggleDelete}
171+
/>
172+
<DataConnectorModal
173+
dataConnector={dataConnector}
174+
isOpen={isEditOpen}
175+
toggle={toggleEdit}
176+
/>
177+
</>
178+
);
179+
}

0 commit comments

Comments
 (0)