From 10baaf44b13b15c3f088684a9ada75f1aec5a8e3 Mon Sep 17 00:00:00 2001
From: Tasko Olevski
Date: Fri, 31 Jan 2025 10:55:51 +0100
Subject: [PATCH 1/4] feat: create data connector in project
---
.../DataConnectorModalBody.tsx | 32 +++++++++++++++++--
.../components/DataConnectorModal/index.tsx | 5 ++-
.../components/DataConnectorsBox.tsx | 2 +-
.../cloudStorage/AddOrEditCloudStorage.tsx | 5 +++
.../cloudStorage/CloudStorageModal.tsx | 1 +
.../cloudStorageModalComponents.tsx | 3 ++
.../projectsV2/api/namespace.enhanced-api.ts | 12 +++++++
.../projectsV2/api/projectV2.enhanced-api.ts | 6 ++--
.../fields/ProjectNamespaceFormField.tsx | 30 +++++++++++++++--
.../projectsV2/list/ProjectV2ListDisplay.tsx | 2 +-
10 files changed, 87 insertions(+), 11 deletions(-)
create mode 100644 client/src/features/projectsV2/api/namespace.enhanced-api.ts
diff --git a/client/src/features/dataConnectorsV2/components/DataConnectorModal/DataConnectorModalBody.tsx b/client/src/features/dataConnectorsV2/components/DataConnectorModal/DataConnectorModalBody.tsx
index 040dc1468a..3d8b04f5c0 100644
--- a/client/src/features/dataConnectorsV2/components/DataConnectorModal/DataConnectorModalBody.tsx
+++ b/client/src/features/dataConnectorsV2/components/DataConnectorModal/DataConnectorModalBody.tsx
@@ -47,15 +47,18 @@ import dataConnectorFormSlice from "../../state/dataConnectors.slice";
import DataConnectorModalResult from "./DataConnectorModalResult";
import DataConnectorSaveCredentialsInfo from "./DataConnectorSaveCredentialsInfo";
+import type { Project } from "../../../projectsV2/api/projectV2.api";
interface AddOrEditDataConnectorProps {
storageSecrets: DataConnectorSecret[];
+ project?: Project;
}
type DataConnectorModalBodyProps = AddOrEditDataConnectorProps;
export default function DataConnectorModalBody({
storageSecrets,
+ project,
}: DataConnectorModalBodyProps) {
const { flatDataConnector, schemata, success } = useAppSelector(
(state) => state.dataConnectorFormSlice
@@ -76,13 +79,17 @@ export default function DataConnectorModalBody({
Or, connect to cloud storage to read and write custom data.
)}
-
+
>
);
}
function AddOrEditDataConnector({
storageSecrets,
+ project,
}: AddOrEditDataConnectorProps) {
const { cloudStorageState, flatDataConnector, schemata, validationResult } =
useAppSelector((state) => state.dataConnectorFormSlice);
@@ -150,7 +157,10 @@ function AddOrEditDataConnector({
setState={setState}
/>
-
+
>
);
return Error - not implemented yet
;
@@ -173,7 +183,7 @@ type DataConnectorMountFormFields =
| "mountPoint"
| "readOnly"
| "saveCredentials";
-export function DataConnectorMount() {
+export function DataConnectorMount({ project }: AddOrEditDataConnectorProps) {
const dispatch = useAppDispatch();
const { cloudStorageState, flatDataConnector, schemata } = useAppSelector(
(state) => state.dataConnectorFormSlice
@@ -305,6 +315,18 @@ export function DataConnectorMount() {
const fields: Partial = { ...field };
delete fields?.ref;
return (
+ // {
+ // field.onChange(e);
+ // onFieldValueChange("namespace", e?.value || "");
+ // }}
+ ///>
);
}}
diff --git a/client/src/features/dataConnectorsV2/components/DataConnectorModal/index.tsx b/client/src/features/dataConnectorsV2/components/DataConnectorModal/index.tsx
index 8b79effa3a..8d163d8f34 100644
--- a/client/src/features/dataConnectorsV2/components/DataConnectorModal/index.tsx
+++ b/client/src/features/dataConnectorsV2/components/DataConnectorModal/index.tsx
@@ -102,7 +102,10 @@ export function DataConnectorModalBodyAndFooter({
) : schemaQueryResult.error ? (
) : (
-
+
)}
diff --git a/client/src/features/dataConnectorsV2/components/DataConnectorsBox.tsx b/client/src/features/dataConnectorsV2/components/DataConnectorsBox.tsx
index e67a53f56d..7fabeff587 100644
--- a/client/src/features/dataConnectorsV2/components/DataConnectorsBox.tsx
+++ b/client/src/features/dataConnectorsV2/components/DataConnectorsBox.tsx
@@ -34,7 +34,7 @@ import Pagination from "../../../components/Pagination";
import { RtkOrNotebooksError } from "../../../components/errors/RtkErrorAlert";
import useGroupPermissions from "../../groupsV2/utils/useGroupPermissions.hook";
import PermissionsGuard from "../../permissionsV2/PermissionsGuard";
-import type { NamespaceKind } from "../../projectsV2/api/namespace.api";
+import type { NamespaceKind } from "../../projectsV2/api/namespace.enhanced-api";
import { useGetUserQuery } from "../../usersV2/api/users.api";
import {
useGetDataConnectorsQuery,
diff --git a/client/src/features/project/components/cloudStorage/AddOrEditCloudStorage.tsx b/client/src/features/project/components/cloudStorage/AddOrEditCloudStorage.tsx
index b2a43f873e..fba792befb 100644
--- a/client/src/features/project/components/cloudStorage/AddOrEditCloudStorage.tsx
+++ b/client/src/features/project/components/cloudStorage/AddOrEditCloudStorage.tsx
@@ -80,6 +80,7 @@ interface AddOrEditCloudStorageProps {
state: AddCloudStorageState;
storage: CloudStorageDetails;
storageSecrets: CloudStorageSecretGet[];
+ projectId?: string;
}
export default function AddOrEditCloudStorage({
@@ -88,6 +89,7 @@ export default function AddOrEditCloudStorage({
setState,
state,
storage,
+ projectId,
}: AddOrEditCloudStorageProps) {
const ContentByStep =
state.step >= 0 && state.step <= CLOUD_STORAGE_TOTAL_STEPS
@@ -107,6 +109,7 @@ export default function AddOrEditCloudStorage({
setStorage={setStorage}
storageSecrets={[]}
validationSucceeded={false}
+ projectId={projectId}
/>
>
);
@@ -171,6 +174,7 @@ export interface AddStorageStepProps {
storageSecrets: CloudStorageSecretGet[];
isV2?: boolean;
validationSucceeded: boolean;
+ projectId?: string;
}
const mapStepToElement: {
@@ -1035,6 +1039,7 @@ export function AddStorageMount({
storage,
state,
validationSucceeded,
+ projectId,
}: AddStorageStepProps) {
const {
control,
diff --git a/client/src/features/project/components/cloudStorage/CloudStorageModal.tsx b/client/src/features/project/components/cloudStorage/CloudStorageModal.tsx
index 7c82f886b6..2aa60873fd 100644
--- a/client/src/features/project/components/cloudStorage/CloudStorageModal.tsx
+++ b/client/src/features/project/components/cloudStorage/CloudStorageModal.tsx
@@ -403,6 +403,7 @@ export default function CloudStorageModal({
storageId={storageId}
success={success}
validationSucceeded={validationSucceeded}
+ projectId={projectId}
/>
diff --git a/client/src/features/project/components/cloudStorage/cloudStorageModalComponents.tsx b/client/src/features/project/components/cloudStorage/cloudStorageModalComponents.tsx
index 40231aeeae..3e0b177ddf 100644
--- a/client/src/features/project/components/cloudStorage/cloudStorageModalComponents.tsx
+++ b/client/src/features/project/components/cloudStorage/cloudStorageModalComponents.tsx
@@ -107,6 +107,7 @@ export interface AddCloudStorageBodyContentProps
storageDetails: CloudStorageDetails;
success: boolean;
validationSucceeded: boolean;
+ projectId?: string;
}
export function AddCloudStorageBodyContent({
addResultStorageName,
@@ -121,6 +122,7 @@ export function AddCloudStorageBodyContent({
storageDetails,
storageId,
success,
+ projectId,
}: AddCloudStorageBodyContentProps) {
if (redraw) return ;
if (success) {
@@ -140,6 +142,7 @@ export function AddCloudStorageBodyContent({
state={state}
storage={storageDetails}
storageSecrets={[]}
+ projectId={projectId}
/>
);
}
diff --git a/client/src/features/projectsV2/api/namespace.enhanced-api.ts b/client/src/features/projectsV2/api/namespace.enhanced-api.ts
new file mode 100644
index 0000000000..5a248ab5f2
--- /dev/null
+++ b/client/src/features/projectsV2/api/namespace.enhanced-api.ts
@@ -0,0 +1,12 @@
+import {
+ NamespaceKind as NamespaceKindOrig,
+ NamespaceResponse as NamespaceResponseOrig,
+} from "./namespace.api.ts";
+
+export type NamespaceKind = NamespaceKindOrig | "project";
+export interface NamespaceResponse
+ extends Omit {
+ namespace_kind: NamespaceKind;
+}
+export type NamespaceResponseList = NamespaceResponse[];
+export type GetNamespacesApiResponse = NamespaceResponseList;
diff --git a/client/src/features/projectsV2/api/projectV2.enhanced-api.ts b/client/src/features/projectsV2/api/projectV2.enhanced-api.ts
index 56440923f2..4b385f0b85 100644
--- a/client/src/features/projectsV2/api/projectV2.enhanced-api.ts
+++ b/client/src/features/projectsV2/api/projectV2.enhanced-api.ts
@@ -17,10 +17,12 @@ import type {
GetGroupsApiArg,
GetGroupsApiResponse as GetGroupsApiResponseOrig,
GetNamespacesApiArg,
- GetNamespacesApiResponse as GetNamespacesApiResponseOrig,
GroupResponseList,
- NamespaceResponseList,
} from "./namespace.api";
+import type {
+ GetNamespacesApiResponse as GetNamespacesApiResponseOrig,
+ NamespaceResponseList,
+} from "./namespace.enhanced-api";
export interface GetGroupsApiResponse extends AbstractKgPaginatedResponse {
groups: GetGroupsApiResponseOrig;
diff --git a/client/src/features/projectsV2/fields/ProjectNamespaceFormField.tsx b/client/src/features/projectsV2/fields/ProjectNamespaceFormField.tsx
index 4afff294a1..fc42c0e8b4 100644
--- a/client/src/features/projectsV2/fields/ProjectNamespaceFormField.tsx
+++ b/client/src/features/projectsV2/fields/ProjectNamespaceFormField.tsx
@@ -38,6 +38,8 @@ import { ErrorAlert } from "../../../components/Alert";
import { Loader } from "../../../components/Loader";
import type { PaginatedState } from "../../session/components/options/fetchMore.types";
import type { GetNamespacesApiResponse } from "../api/projectV2.enhanced-api";
+import type { Project } from "../api/projectV2.api";
+import type { NamespaceResponse } from "../api/namespace.enhanced-api";
import {
useGetNamespacesByNamespaceSlugQuery,
useGetNamespacesQuery,
@@ -136,6 +138,7 @@ interface NamespaceSelectorProps {
namespaces: ResponseNamespaces;
onChange?: (newValue: SingleValue) => void;
onFetchMore?: () => void;
+ project?: Project;
}
function NamespaceSelector({
@@ -146,10 +149,27 @@ function NamespaceSelector({
namespaces,
onChange,
onFetchMore,
+ project,
}: NamespaceSelectorProps) {
+ const namespaceOptions = useMemo(() => {
+ if (!project) {
+ return namespaces;
+ }
+ return [
+ {
+ id: project.id,
+ name: project.name,
+ slug: `${project.namespace}/${project.slug}`,
+ created_by: project.created_by,
+ creation_date: project.creation_date,
+ namespace_kind: "project",
+ } as NamespaceResponse,
+ ...namespaces,
+ ];
+ }, [namespaces, project]);
const currentValue = useMemo(
- () => namespaces.find(({ slug }) => slug === currentNamespace),
- [namespaces, currentNamespace]
+ () => namespaceOptions.find(({ slug }) => slug === currentNamespace),
+ [namespaceOptions, currentNamespace]
);
const components = useMemo(
@@ -163,7 +183,7 @@ function NamespaceSelector({
return (