From 0bfde5223657d611d752352c4d3023bd31f8adca Mon Sep 17 00:00:00 2001 From: Marc McIntosh Date: Wed, 6 Nov 2024 13:17:42 +0100 Subject: [PATCH 01/54] wip(integrations): add service for the api. --- src/__fixtures__/index.ts | 1 + src/__fixtures__/integrations.ts | 127 +++++++++++++++++++++++++ src/app/store.ts | 3 + src/services/refact/index.ts | 1 + src/services/refact/integrations.ts | 140 ++++++++++++++++++++++++++++ 5 files changed, 272 insertions(+) create mode 100644 src/__fixtures__/integrations.ts create mode 100644 src/services/refact/integrations.ts diff --git a/src/__fixtures__/index.ts b/src/__fixtures__/index.ts index 143af08aa..9c8cb51e4 100644 --- a/src/__fixtures__/index.ts +++ b/src/__fixtures__/index.ts @@ -3,3 +3,4 @@ export * from "./chat"; export { TABLE } from "./table"; export * from "./context_files"; export * from "./prompts"; +export * from "./integrations"; diff --git a/src/__fixtures__/integrations.ts b/src/__fixtures__/integrations.ts new file mode 100644 index 000000000..5212a7a08 --- /dev/null +++ b/src/__fixtures__/integrations.ts @@ -0,0 +1,127 @@ +import type { Integration } from "../services/refact"; + +export const INTEGRATIONS_RESPONSE: Integration[] = [ + { + name: "github", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + title: "IntegrationGitHub", + type: "object", + required: ["GH_TOKEN"], + properties: { + GH_TOKEN: { + description: "GitHub token for authentication.", + type: "string", + }, + gh_binary_path: { + description: "Path to the GitHub CLI binary.", + type: ["string", "null"], + }, + }, + }, + value: { + detail: + "Problem constructing tool from /Users/valaises/.cache/refact/integrations.d/github.yaml: missing field `GH_TOKEN`", + }, + }, + { + name: "gitlab", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + title: "IntegrationGitLab", + type: "object", + required: ["GITLAB_TOKEN"], + properties: { + GITLAB_TOKEN: { + description: "GitLab token for authentication.", + type: "string", + }, + glab_binary_path: { + description: "Path to the GitLab CLI binary.", + type: ["string", "null"], + }, + }, + }, + value: { + detail: + "Problem constructing tool from /Users/valaises/.cache/refact/integrations.d/gitlab.yaml: missing field `GITLAB_TOKEN`", + }, + }, + { + name: "pdb", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + title: "IntegrationPdb", + type: "object", + properties: { + python_path: { + description: "Path to the Python binary.", + type: ["string", "null"], + }, + }, + }, + value: { + python_path: null, + }, + }, + { + name: "postgres", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + title: "IntegrationPostgres", + type: "object", + required: ["connection_string"], + properties: { + connection_string: { + description: "Connection string for the PostgreSQL database.", + type: "string", + }, + psql_binary_path: { + description: "Path to the psql binary.", + type: ["string", "null"], + }, + }, + }, + value: { + detail: + "Problem constructing tool from /Users/valaises/.cache/refact/integrations.d/postgres.yaml: missing field `connection_string`", + }, + }, + { + name: "chrome", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + title: "IntegrationChrome", + type: "object", + properties: { + chrome_path: { + description: + "Path to the Chrome binary or WebSocket URL for remote debugging.", + type: ["string", "null"], + }, + idle_browser_timeout: { + description: "Idle timeout for the Chrome browser in seconds.", + type: ["integer", "null"], + format: "uint32", + minimum: 0.0, + }, + window_size: { + description: + "Window size for the Chrome browser in the format [width, height].", + type: ["array", "null"], + items: { + type: "integer", + format: "uint32", + minimum: 0.0, + }, + }, + }, + }, + value: { + chrome_path: + "/Users/valaises/temp/chrome/mac_arm-130.0.6723.69/chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing", + window_size: [1024, 768], + idle_browser_timeout: 600, + }, + }, +]; diff --git a/src/app/store.ts b/src/app/store.ts index cc7fa97f0..602190dc5 100644 --- a/src/app/store.ts +++ b/src/app/store.ts @@ -19,6 +19,7 @@ import { diffApi, pathApi, pingApi, + integrationsApi, } from "../services/refact"; import { smallCloudApi } from "../services/smallcloud"; import { reducer as fimReducer } from "../features/FIM/reducer"; @@ -75,6 +76,7 @@ const rootReducer = combineSlices( errorSlice, informationSlice, pagesSlice, + integrationsApi, ); const rootPersistConfig = { @@ -136,6 +138,7 @@ export function setUpStore(preloadedState?: Partial) { diffApi.middleware, smallCloudApi.middleware, pathApi.middleware, + integrationsApi.middleware, ) .prepend(historyMiddleware.middleware) // .prepend(errorMiddleware.middleware) diff --git a/src/services/refact/index.ts b/src/services/refact/index.ts index b8aaa4168..2106aa1dc 100644 --- a/src/services/refact/index.ts +++ b/src/services/refact/index.ts @@ -9,3 +9,4 @@ export * from "./types"; export * from "./diffs"; export * from "./path"; export * from "./ping"; +export * from "./integrations"; diff --git a/src/services/refact/integrations.ts b/src/services/refact/integrations.ts new file mode 100644 index 000000000..772618b8a --- /dev/null +++ b/src/services/refact/integrations.ts @@ -0,0 +1,140 @@ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { RootState } from "../../app/store"; + +const INTEGRATIONS_URL = "/v1/integrations"; +const INTEGRATIONS_SAVE_URL = "/v1/integrations-save"; +const INTEGRATIONS_ICONS_URL = "/v1/integrations-icons"; + +export const integrationsApi = createApi({ + reducerPath: "integrationsApi", + tagTypes: ["INTEGRATIONS"], + baseQuery: fetchBaseQuery({ + prepareHeaders: (headers, api) => { + const getState = api.getState as () => RootState; + const state = getState(); + const token = state.config.apiKey; + headers.set("credentials", "same-origin"); + if (token) { + headers.set("Authorization", `Bearer ${token}`); + } + return headers; + }, + }), + endpoints: (builder) => ({ + getAllIntegrations: builder.query({ + providesTags: ["INTEGRATIONS"], + async queryFn(_arg, api, extraOptions, baseQuery) { + const state = api.getState() as RootState; + const port = state.config.lspPort as unknown as number; + const url = `http://127.0.0.1:${port}${INTEGRATIONS_URL}`; + const response = await baseQuery({ + url, + ...extraOptions, + }); + + if (response.error) { + return { error: response.error }; + } + + if (!isIntegrations(response.data)) { + return { + error: { + status: "CUSTOM_ERROR", + error: "Failed to parse integrations response", + data: response.data, + }, + }; + } + return { data: response.data }; + }, + }), + saveIntegration: builder.mutation({ + invalidatesTags: ["INTEGRATIONS"], + async queryFn(arg, api, extraOptions, baseQuery) { + const state = api.getState() as RootState; + const port = state.config.lspPort as unknown as number; + const url = `http://127.0.0.1:${port}${INTEGRATIONS_SAVE_URL}`; + const response = await baseQuery({ + url, + method: "POST", + body: arg, + ...extraOptions, + }); + + if (response.error) { + return { error: response.error }; + } + + return { data: response.data }; + }, + }), + getIntegrationIcons: builder.query({ + async queryFn(arg, api, extraOptions, baseQuery) { + const state = api.getState() as RootState; + const port = state.config.lspPort as unknown as number; + const url = `http://127.0.0.1:${port}${INTEGRATIONS_ICONS_URL}`; + + const response = await baseQuery({ url, ...extraOptions }); + + if (response.error) { + return { error: response.error }; + } + + if (!isIntegrationIcons(response.data)) { + return { + error: { + status: "CUSTOM_ERROR", + error: "Failed to parse integration icons response", + data: response.data, + }, + }; + } + + return { data: response.data }; + }, + }), + }), +}); + +export function isIntegrationIcons(json: unknown): json is IntegrationIcon[] { + if (!Array.isArray(json)) return false; + return json.every(isIntegrationIcon); +} +export type IntegrationIcon = { + name: string; + value: string; +}; + +export function isIntegrationIcon(json: unknown): json is IntegrationIcon { + if (!json) return false; + if (typeof json !== "object") return false; + if (!("name" in json)) return false; + if (typeof json.name !== "string") return false; + if (!("value" in json)) return false; + if (typeof json.value !== "string") return false; + return true; +} + +export type Integration = { + name: string; + schema: null | Record; // TODO: JSON schema + value: { + // Value = any json value :/ + [key: string]: unknown; + detail?: string; + }; +}; + +function isIntegrations(json: unknown): json is Integration[] { + if (!Array.isArray(json)) return false; + return json.every(isIntegration); +} +export function isIntegration(json: unknown): json is Integration { + if (!json) return false; + if (typeof json !== "object") return false; + if (!("name" in json)) return false; + if (typeof json.name !== "string") return false; + if (!("schema" in json)) return false; + if (!("value" in json)) return false; + return true; +} From 81c8b6d94430bd13d125660002c75fe29f86c6af Mon Sep 17 00:00:00 2001 From: Marc McIntosh Date: Wed, 6 Nov 2024 13:21:25 +0100 Subject: [PATCH 02/54] fix(integrations): add _ to unused function argument. --- src/services/refact/integrations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/refact/integrations.ts b/src/services/refact/integrations.ts index 772618b8a..231dff55a 100644 --- a/src/services/refact/integrations.ts +++ b/src/services/refact/integrations.ts @@ -69,7 +69,7 @@ export const integrationsApi = createApi({ }, }), getIntegrationIcons: builder.query({ - async queryFn(arg, api, extraOptions, baseQuery) { + async queryFn(_arg, api, extraOptions, baseQuery) { const state = api.getState() as RootState; const port = state.config.lspPort as unknown as number; const url = `http://127.0.0.1:${port}${INTEGRATIONS_ICONS_URL}`; From 281568d6d6a1d665d3e793f7a6237cdea5ee8366 Mon Sep 17 00:00:00 2001 From: Marc McIntosh Date: Wed, 6 Nov 2024 13:30:11 +0100 Subject: [PATCH 03/54] wip(integrations): add enabled feild. --- src/services/refact/integrations.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/refact/integrations.ts b/src/services/refact/integrations.ts index 231dff55a..914bbb9ab 100644 --- a/src/services/refact/integrations.ts +++ b/src/services/refact/integrations.ts @@ -117,6 +117,7 @@ export function isIntegrationIcon(json: unknown): json is IntegrationIcon { export type Integration = { name: string; + enabled: boolean; schema: null | Record; // TODO: JSON schema value: { // Value = any json value :/ @@ -134,6 +135,7 @@ export function isIntegration(json: unknown): json is Integration { if (typeof json !== "object") return false; if (!("name" in json)) return false; if (typeof json.name !== "string") return false; + if (!("enabled" in json)) return false; if (!("schema" in json)) return false; if (!("value" in json)) return false; return true; From 777d4a03aa329814aac4080b4f15d77de0fc7038 Mon Sep 17 00:00:00 2001 From: Marc McIntosh Date: Wed, 6 Nov 2024 13:51:48 +0100 Subject: [PATCH 04/54] chore(types): update integration fixture --- src/__fixtures__/integrations.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/__fixtures__/integrations.ts b/src/__fixtures__/integrations.ts index 5212a7a08..f26f8b1d5 100644 --- a/src/__fixtures__/integrations.ts +++ b/src/__fixtures__/integrations.ts @@ -3,6 +3,7 @@ import type { Integration } from "../services/refact"; export const INTEGRATIONS_RESPONSE: Integration[] = [ { name: "github", + enabled: true, schema: { $schema: "http://json-schema.org/draft-07/schema#", title: "IntegrationGitHub", @@ -26,6 +27,7 @@ export const INTEGRATIONS_RESPONSE: Integration[] = [ }, { name: "gitlab", + enabled: false, schema: { $schema: "http://json-schema.org/draft-07/schema#", title: "IntegrationGitLab", @@ -49,6 +51,7 @@ export const INTEGRATIONS_RESPONSE: Integration[] = [ }, { name: "pdb", + enabled: true, schema: { $schema: "http://json-schema.org/draft-07/schema#", title: "IntegrationPdb", @@ -66,6 +69,7 @@ export const INTEGRATIONS_RESPONSE: Integration[] = [ }, { name: "postgres", + enabled: false, schema: { $schema: "http://json-schema.org/draft-07/schema#", title: "IntegrationPostgres", @@ -89,6 +93,7 @@ export const INTEGRATIONS_RESPONSE: Integration[] = [ }, { name: "chrome", + enabled: true, schema: { $schema: "http://json-schema.org/draft-07/schema#", title: "IntegrationChrome", From af79cde6065a48a6fb0d53d2d0526be5f79dc82e Mon Sep 17 00:00:00 2001 From: alashchev17 Date: Wed, 6 Nov 2024 19:10:34 +0100 Subject: [PATCH 05/54] wip: integrations page layout + data retrieval --- src/app/middleware.ts | 13 +++ .../IntegrationsView.module.css | 10 ++ .../IntegrationsView/IntegrationsView.tsx | 92 +++++++++++++++++++ src/components/Toolbar/Dropdown.tsx | 4 + src/components/Toolbar/Toolbar.tsx | 2 + src/features/App.tsx | 9 ++ src/features/Integrations/Integrations.tsx | 84 +++++++++++++++++ src/features/Integrations/index.ts | 1 + src/features/Pages/pagesSlice.ts | 7 +- src/hooks/useGetIntegrationsDataQuery.ts | 15 +++ src/services/refact/integrations.ts | 1 + 11 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 src/components/IntegrationsView/IntegrationsView.module.css create mode 100644 src/components/IntegrationsView/IntegrationsView.tsx create mode 100644 src/features/Integrations/Integrations.tsx create mode 100644 src/features/Integrations/index.ts create mode 100644 src/hooks/useGetIntegrationsDataQuery.ts diff --git a/src/app/middleware.ts b/src/app/middleware.ts index c12a45614..4c2c1ff5f 100644 --- a/src/app/middleware.ts +++ b/src/app/middleware.ts @@ -11,6 +11,7 @@ import { restoreChat, } from "../features/Chat/Thread"; import { statisticsApi } from "../services/refact/statistics"; +import { integrationsApi } from "../services/refact/integrations"; import { capsApi, isCapsErrorResponse } from "../services/refact/caps"; import { promptsApi } from "../services/refact/prompts"; import { toolsApi } from "../services/refact/tools"; @@ -84,6 +85,18 @@ startListening({ listenerApi.dispatch(setError(errorMessage)); } + if ( + integrationsApi.endpoints.getAllIntegrations.matchRejected(action) && + !action.meta.condition + ) { + // getting first 2 lines of error message to show to user + console.log(`[DEBUG]: maybeData: `, action.payload?.data); + const errorMessage = isDetailMessage(action.payload?.data) + ? action.payload.data.detail + : `fetching integrations.`; + listenerApi.dispatch(setError(errorMessage)); + } + if ( chatAskQuestionThunk.rejected.match(action) && !action.meta.aborted && diff --git a/src/components/IntegrationsView/IntegrationsView.module.css b/src/components/IntegrationsView/IntegrationsView.module.css new file mode 100644 index 000000000..cd562bd68 --- /dev/null +++ b/src/components/IntegrationsView/IntegrationsView.module.css @@ -0,0 +1,10 @@ +.icon { + max-width: 75px; + object-fit: cover; +} + +.integrationCard { + padding: 1rem; + height: 175px; + min-width: calc(50% - 0.5rem); +} diff --git a/src/components/IntegrationsView/IntegrationsView.tsx b/src/components/IntegrationsView/IntegrationsView.tsx new file mode 100644 index 000000000..c7a04cb99 --- /dev/null +++ b/src/components/IntegrationsView/IntegrationsView.tsx @@ -0,0 +1,92 @@ +import React from "react"; +import { Box, Card, Flex, Heading, Text } from "@radix-ui/themes"; +import type { Integration, IntegrationIcon } from "../../services/refact"; +import { Spinner } from "../Spinner"; +import { ErrorCallout } from "../Callout"; +import { useAppDispatch, useAppSelector } from "../../hooks"; +import { clearError, getErrorMessage } from "../../features/Errors/errorsSlice"; +import styles from "./IntegrationsView.module.css"; + +export const IntegrationsView: React.FC<{ + integrationsData?: Integration[]; + integrationsIcons?: IntegrationIcon[]; + isLoading: boolean; + goBack?: () => void; +}> = ({ integrationsData, integrationsIcons, isLoading, goBack }) => { + const dispatch = useAppDispatch(); + const error = useAppSelector(getErrorMessage); + + if (isLoading || !integrationsData || !integrationsIcons) { + return ; + } + + const goBackAndClearError = () => { + goBack && goBack(); + dispatch(clearError()); + }; + + if (error) { + return {error}; + } + + return ( + + + + Integrations Setup + + + {/* TODO: Implement form here */} + {integrationsData.map((integration) => ( + + + icon.name === integration.name, + )?.value ?? "" + } + alt={integration.name} + className={styles.icon} + /> + {integration.name} + + + ))} + + + + ); +}; + +{ + /* + {integration.name} + {integration.value.detail && ( + + {integration.value.detail} + + )} + */ +} diff --git a/src/components/Toolbar/Dropdown.tsx b/src/components/Toolbar/Dropdown.tsx index 7f111640f..5c53d4877 100644 --- a/src/components/Toolbar/Dropdown.tsx +++ b/src/components/Toolbar/Dropdown.tsx @@ -20,6 +20,7 @@ export type DropdownNavigationOptions = | "hot keys" | "restart tour" | "cloud login" + | "integrations" | ""; type DropdownProps = { @@ -171,6 +172,9 @@ export const Dropdown: React.FC = ({ Edit Bring Your Own Key )} + handleNavigation("integrations")}> + Setup Integrations + handleNavigation("hot keys")}> Hot Keys... diff --git a/src/components/Toolbar/Toolbar.tsx b/src/components/Toolbar/Toolbar.tsx index 96c1be60e..f5f045a07 100644 --- a/src/components/Toolbar/Toolbar.tsx +++ b/src/components/Toolbar/Toolbar.tsx @@ -74,6 +74,8 @@ export const Toolbar = ({ activeTab }: ToolbarProps) => { dispatch(restart()); dispatch(popBackTo("initial setup")); dispatch(push({ name: "welcome" })); + } else if (to === "integrations") { + dispatch(push({ name: "integrations page" })); } else if (to === "chat") { dispatch(popBackTo("history")); dispatch(push({ name: "chat" })); diff --git a/src/features/App.tsx b/src/features/App.tsx index f0915abc2..dcbaaba8b 100644 --- a/src/features/App.tsx +++ b/src/features/App.tsx @@ -33,6 +33,7 @@ import { Toolbar } from "../components/Toolbar"; import { Tab } from "../components/Toolbar/Toolbar"; import { PageWrapper } from "../components/PageWrapper"; import { ThreadHistory } from "./ThreadHistory"; +import { Integrations } from "./Integrations"; export interface AppProps { style?: React.CSSProperties; @@ -201,6 +202,14 @@ export const InnerApp: React.FC = ({ style }: AppProps) => { onCloseStatistic={goBack} /> )} + {page.name === "integrations page" && ( + + )} {page.name === "thread history page" && ( void; + backFromIntegrations: () => void; + host: Config["host"]; + tabbed: Config["tabbed"]; +}; + +export const Integrations: React.FC = ({ + onCloseIntegrations, + backFromIntegrations, + host, + tabbed, +}) => { + const LeftRightPadding = + host === "web" + ? { initial: "2", xl: "9" } + : { + initial: "2", + xs: "2", + sm: "4", + md: "8", + lg: "8", + xl: "9", + }; + + const { integrations, icons } = useGetIntegrationsQuery(); + + useEffect(() => { + console.log(`[DEBUG]: integrations: `, integrations); + }, [integrations]); + + useEffect(() => { + console.log(`[DEBUG]: icons: `, icons); + }, [icons]); + + return ( + + {host === "vscode" && !tabbed ? ( + + + + ) : ( + + )} + + + + + + + ); +}; diff --git a/src/features/Integrations/index.ts b/src/features/Integrations/index.ts new file mode 100644 index 000000000..67f0f0e96 --- /dev/null +++ b/src/features/Integrations/index.ts @@ -0,0 +1 @@ +export { type IntegrationsProps, Integrations } from "./Integrations"; diff --git a/src/features/Pages/pagesSlice.ts b/src/features/Pages/pagesSlice.ts index 2cb0e015f..0d38c150d 100644 --- a/src/features/Pages/pagesSlice.ts +++ b/src/features/Pages/pagesSlice.ts @@ -53,6 +53,10 @@ export interface ChatThreadHistoryPage { chatId: string; } +export interface IntegrationsSetupPage { + name: "integrations page"; +} + export type Page = | InitialSetupPage | CloudLogin @@ -66,7 +70,8 @@ export type Page = | FIMDebugPage | StatisticsPage | DocumentationSettingsPage - | ChatThreadHistoryPage; + | ChatThreadHistoryPage + | IntegrationsSetupPage; export type PageSliceState = Page[]; diff --git a/src/hooks/useGetIntegrationsDataQuery.ts b/src/hooks/useGetIntegrationsDataQuery.ts new file mode 100644 index 000000000..d5345881e --- /dev/null +++ b/src/hooks/useGetIntegrationsDataQuery.ts @@ -0,0 +1,15 @@ +import { integrationsApi } from "../services/refact/integrations"; +import { useGetPing } from "./useGetPing"; + +export const useGetIntegrationsQuery = () => { + const ping = useGetPing(); + const skip = !ping.data; + const integrations = integrationsApi.useGetAllIntegrationsQuery(undefined, { + skip, + }); + const icons = integrationsApi.useGetIntegrationIconsQuery(undefined, { + skip, + }); + + return { integrations, icons }; +}; diff --git a/src/services/refact/integrations.ts b/src/services/refact/integrations.ts index 914bbb9ab..0f8a4865a 100644 --- a/src/services/refact/integrations.ts +++ b/src/services/refact/integrations.ts @@ -33,6 +33,7 @@ export const integrationsApi = createApi({ }); if (response.error) { + console.log(`[DEBUG]: error: `, response.error); return { error: response.error }; } From 780268b1b5d04c298c5fea16a1e2ed3e0556ec24 Mon Sep 17 00:00:00 2001 From: alashchev17 Date: Thu, 7 Nov 2024 21:09:01 +0100 Subject: [PATCH 06/54] wip: conditional rendering of form and cards & JSON schema parsing into form --- package-lock.json | 308 ++++++++++++++++-- package.json | 4 + .../CustomFieldsAndWidgets.tsx | 78 +++++ .../IntegrationsView.module.css | 24 ++ .../IntegrationsView/IntegrationsView.tsx | 240 +++++++++++--- src/services/refact/integrations.ts | 134 +++++++- src/utils/jsonSchemaVerifier.ts | 31 ++ 7 files changed, 734 insertions(+), 85 deletions(-) create mode 100644 src/components/IntegrationsView/CustomFieldsAndWidgets.tsx create mode 100644 src/utils/jsonSchemaVerifier.ts diff --git a/package-lock.json b/package-lock.json index 6aa6318e2..d48020f8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,11 @@ "license": "BSD-3-Clause", "dependencies": { "@reduxjs/toolkit": "^2.2.7", + "@rjsf/core": "^5.22.3", + "@rjsf/utils": "^5.22.3", + "@rjsf/validator-ajv8": "^5.22.3", "@types/react": "^18.2.43", + "ajv": "^8.17.1", "react-redux": "^9.1.2" }, "devDependencies": { @@ -2664,6 +2668,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2697,6 +2718,13 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -3357,6 +3385,30 @@ "resolve": "~1.19.0" } }, + "node_modules/@microsoft/tsdoc-config/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@microsoft/tsdoc-config/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", @@ -5591,6 +5643,69 @@ } } }, + "node_modules/@rjsf/core": { + "version": "5.22.3", + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.22.3.tgz", + "integrity": "sha512-YVunuas8RyetoPsy/bfkintjMo896APJMmFeYR7fiVQSvANY7Hvc7ySdQ7UmRhtzUyYwDCnplLv01exHpzXCAg==", + "license": "Apache-2.0", + "dependencies": { + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "markdown-to-jsx": "^7.4.1", + "nanoid": "^3.3.7", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@rjsf/utils": "^5.22.x", + "react": "^16.14.0 || >=17" + } + }, + "node_modules/@rjsf/utils": { + "version": "5.22.3", + "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.22.3.tgz", + "integrity": "sha512-/aWtYX2ruK3x/bGsePc25UEbSsJvLUAMQO1i306RQ3QQzWn4hbyenBfT4iMxh6Kaly6kmKavBlB7knpooCx4OQ==", + "license": "Apache-2.0", + "dependencies": { + "json-schema-merge-allof": "^0.8.1", + "jsonpointer": "^5.0.1", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.14.0 || >=17" + } + }, + "node_modules/@rjsf/utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/@rjsf/validator-ajv8": { + "version": "5.22.3", + "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-5.22.3.tgz", + "integrity": "sha512-fHu+oPOckpSHMwKdPCP/h8TtcOJ4I45RxFR//cN1c+um6OtpE/0t9JkVWAtbQlNJffIrzacnJjH5NpGwssxjrA==", + "license": "Apache-2.0", + "dependencies": { + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@rjsf/utils": "^5.22.x" + } + }, "node_modules/@rollup/pluginutils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", @@ -10130,21 +10245,38 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ansi-escapes": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", @@ -11397,6 +11529,27 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/compute-gcd": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", + "integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==", + "dependencies": { + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, + "node_modules/compute-lcm": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz", + "integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==", + "dependencies": { + "compute-gcd": "^1.2.1", + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, "node_modules/computeds": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", @@ -12784,6 +12937,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -12817,6 +12987,13 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -13078,8 +13255,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.2", @@ -13121,6 +13297,12 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "license": "BSD-3-Clause" + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -15701,11 +15883,34 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "node_modules/json-schema-compare": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", + "integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.4" + } + }, + "node_modules/json-schema-merge-allof": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", + "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", + "license": "MIT", + "dependencies": { + "compute-lcm": "^1.1.2", + "json-schema-compare": "^0.2.2", + "lodash": "^4.17.20" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -15737,6 +15942,15 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -16214,8 +16428,13 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" }, "node_modules/lodash.camelcase": { "version": "4.3.0", @@ -16524,10 +16743,10 @@ } }, "node_modules/markdown-to-jsx": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.3.2.tgz", - "integrity": "sha512-B+28F5ucp83aQm+OxNrPkS8z0tMKaeHiy0lHJs3LqCyDQFtWuenaIrkaVTgAm1pf1AU85LXltva86hlaT17i8Q==", - "dev": true, + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.5.0.tgz", + "integrity": "sha512-RrBNcMHiFPcz/iqIj0n3wclzHXjwS7mzjBNWecKKVhNTIxQepIix6Il/wZCn2Cg5Y1ow2Qi84+eJrryFRWBEWw==", + "license": "MIT", "engines": { "node": ">= 10" }, @@ -17937,7 +18156,6 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", @@ -18275,7 +18493,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -19129,7 +19346,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -19139,8 +19355,7 @@ "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/property-information": { "version": "6.4.0", @@ -20330,6 +20545,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requireindex": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", @@ -22355,6 +22579,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -22513,6 +22738,39 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/validate.io-array": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz", + "integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==", + "license": "MIT" + }, + "node_modules/validate.io-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz", + "integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==" + }, + "node_modules/validate.io-integer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz", + "integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==", + "dependencies": { + "validate.io-number": "^1.0.3" + } + }, + "node_modules/validate.io-integer-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz", + "integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==", + "dependencies": { + "validate.io-array": "^1.0.3", + "validate.io-integer": "^1.0.4" + } + }, + "node_modules/validate.io-number": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz", + "integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg==" + }, "node_modules/validator": { "version": "13.11.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", diff --git a/package.json b/package.json index f79061630..10c377557 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,11 @@ }, "dependencies": { "@reduxjs/toolkit": "^2.2.7", + "@rjsf/core": "^5.22.3", + "@rjsf/utils": "^5.22.3", + "@rjsf/validator-ajv8": "^5.22.3", "@types/react": "^18.2.43", + "ajv": "^8.17.1", "react-redux": "^9.1.2" }, "devDependencies": { diff --git a/src/components/IntegrationsView/CustomFieldsAndWidgets.tsx b/src/components/IntegrationsView/CustomFieldsAndWidgets.tsx new file mode 100644 index 000000000..5fb70a2fb --- /dev/null +++ b/src/components/IntegrationsView/CustomFieldsAndWidgets.tsx @@ -0,0 +1,78 @@ +// TODO: fix unsafe returns +/* eslint-disable @typescript-eslint/no-unsafe-return */ +import React from "react"; +import { Box, Checkbox, TextField, TextArea } from "@radix-ui/themes"; +import { FieldProps, WidgetProps } from "@rjsf/utils"; +import { IntegrationSchema } from "../../services/refact"; + +// Custom String Field +const CustomStringField: React.FC> = ({ + id, + label, + required, + onChange, + value, +}) => ( + + + onChange(e.target.value)} + value={typeof value === "string" ? value : ""} + /> + +); + +const CustomTitleField: React.FC< + FieldProps +> = () => { + return null; +}; + +// Custom Textarea Widget +const CustomTextareaWidget: React.FC< + WidgetProps +> = ({ id, label, required, onChange, value }) => ( + + +