From 032a2299df32cab8cdc7ca59534df5454f261a0e Mon Sep 17 00:00:00 2001 From: Austin Akers Date: Fri, 31 Oct 2025 14:16:15 -0400 Subject: [PATCH 1/3] chore: rebased branch against stage --- package.json | 2 + pnpm-lock.yaml | 39 ++++ src/components/ui/accordion.tsx | 63 ++++++ src/components/ui/switch.tsx | 28 +++ .../components/CreateTableGUI/index.tsx | 204 ++++++++++++++++++ .../components/TextEditorView/index.tsx | 19 +- 6 files changed, 348 insertions(+), 7 deletions(-) create mode 100644 src/components/ui/accordion.tsx create mode 100644 src/components/ui/switch.tsx create mode 100644 src/features/instance/applications/components/CreateTableGUI/index.tsx diff --git a/package.json b/package.json index 8d98fac0d..24a39c1a9 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@datadog/browser-rum-react": "^6.18.0", "@hookform/resolvers": "^5.0.0", "@monaco-editor/react": "^4.7.0", + "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-alert-dialog": "^1.1.6", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-dropdown-menu": "^2.1.6", @@ -37,6 +38,7 @@ "@radix-ui/react-select": "^2.1.6", "@radix-ui/react-separator": "^1.1.2", "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.3", "@radix-ui/react-toggle": "^1.1.10", "@radix-ui/react-tooltip": "^1.1.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dc503c41c..ab0ef3d0a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1162,6 +1162,19 @@ packages: '@radix-ui/primitive@1.1.3': resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + '@radix-ui/react-accordion@1.2.12': + resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-alert-dialog@1.1.15': resolution: {integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==} peerDependencies: @@ -1188,6 +1201,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-collapsible@1.1.12': + resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-collection@1.1.7': resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} peerDependencies: @@ -1463,6 +1489,19 @@ packages: '@types/react': optional: true + '@radix-ui/react-switch@1.2.6': + resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-tabs@1.1.13': resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} peerDependencies: diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx new file mode 100644 index 000000000..54c2ee7e6 --- /dev/null +++ b/src/components/ui/accordion.tsx @@ -0,0 +1,63 @@ +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDownIcon } from "lucide-react" +import { cn } from "@/lib/cn" + +function Accordion({ + ...props +}: React.ComponentProps) { + return +} + +function AccordionItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AccordionTrigger({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + + ) +} + +function AccordionContent({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + +
{children}
+
+ ) +} + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch.tsx new file mode 100644 index 000000000..4c58ff3a9 --- /dev/null +++ b/src/components/ui/switch.tsx @@ -0,0 +1,28 @@ +import * as React from "react" +import * as SwitchPrimitive from "@radix-ui/react-switch" +import { cn } from "@/lib/cn" + +function Switch({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +export { Switch } diff --git a/src/features/instance/applications/components/CreateTableGUI/index.tsx b/src/features/instance/applications/components/CreateTableGUI/index.tsx new file mode 100644 index 000000000..d6b8833a2 --- /dev/null +++ b/src/features/instance/applications/components/CreateTableGUI/index.tsx @@ -0,0 +1,204 @@ +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'; +import { Button } from '@/components/ui/button'; +import { Form } from '@/components/ui/form/Form'; +import { FormControl } from '@/components/ui/form/FormControl'; +import { FormField } from '@/components/ui/form/FormField'; +import { FormItem } from '@/components/ui/form/FormItem'; +import { FormLabel } from '@/components/ui/form/FormLabel'; +import { FormMessage } from '@/components/ui/form/FormMessage'; +import { Input } from '@/components/ui/input'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; +import { Plus, TrashIcon } from 'lucide-react'; +// import { zodResolver } from '@hookform/resolvers/zod'; +import { useFieldArray, useForm } from 'react-hook-form'; + +export function CreateTableGUI() { + const methods = useForm({ + // resolver: zodResolver(), + defaultValues: { + tableName: '', + isRestEndpoint: 'false', + noAdditionalProperties: 'false', + tableFields: [{ fieldName: '', fieldType: 'id', isPrimaryKey: 'true', isNullable: 'false', isIndexed: 'false' }], + }, + }); + const { control } = methods; + + const { fields, append, remove } = useFieldArray({ + name: 'tableFields', + control, + }); + return ( +
+

Create Table

+ + + Why create a table? + + Creating a table is the basis of a data-driven application and can immediately be used as RESTful endpoint. + This can also be configured as a caching table and extended and customized for specific endpoint behavior. + + + +
+ + ( + + Table Name + + + + + + )} + /> + ( + + + + + Make available as a REST endpoint + + + )} + /> + ( + + + + + Do not allow additional properties + + + )} + /> +
+
+

Table Fields

+ +
+ {fields.map((field, index) => ( +
+
+ ( + + Field Name + + + + + + )} + /> + ( + + Type + + + + + + )} + /> +
+
+
+ ( + + + + + Indexed + + + )} + /> + ( + + + + + Primary Key + + + )} + /> + ( + + + + + Nullable + + + )} + /> +
+ +
+
+ ))} + + +
+ ); +} diff --git a/src/features/instance/applications/components/TextEditorView/index.tsx b/src/features/instance/applications/components/TextEditorView/index.tsx index 8374fce2e..dee9a7bed 100644 --- a/src/features/instance/applications/components/TextEditorView/index.tsx +++ b/src/features/instance/applications/components/TextEditorView/index.tsx @@ -28,11 +28,16 @@ const extensionToLanguageMap: Record = { export function TextEditorView() { const instanceParams = useInstanceClientIdParams(); const { openedEntryContents, openedEntry, restrictPackageModification, isSavingFile, saveFile } = useEditorView(); - const { content: updatedFileContent, setContent } = useEditorFileContent(!!openedEntry && !openedEntry.package && openedEntry.path); + const { content: updatedFileContent, setContent } = useEditorFileContent( + !!openedEntry && !openedEntry.package && openedEntry.path + ); - const setUpdatedFileContent = useCallback((newValue: string | undefined) => { - setContent(newValue !== openedEntryContents ? newValue : undefined); - }, [openedEntryContents, setContent]); + const setUpdatedFileContent = useCallback( + (newValue: string | undefined) => { + setContent(newValue !== openedEntryContents ? newValue : undefined); + }, + [openedEntryContents, setContent] + ); const canManageBrowseInstance = useInstanceBrowseManagePermission(); const [mounted, setMounted] = useState | null>(null); @@ -103,11 +108,11 @@ export function TextEditorView() { payload: updatedFileContent, project: openedEntry.project, }, - openedEntry.path, + openedEntry.path ); } }, - [openedEntry, instanceParams, updatedFileContent], + [openedEntry, instanceParams, updatedFileContent] ); useListener( @@ -119,7 +124,7 @@ export function TextEditorView() { editor.setValue(openedEntryContents); } }, - [openedEntryContents, mounted], + [openedEntryContents, mounted] ); if (!openedEntry) { From 7560bb1bf3cead0434469d5c2318c630f2e130fd Mon Sep 17 00:00:00 2001 From: Austin Akers Date: Thu, 16 Oct 2025 18:20:17 -0400 Subject: [PATCH 2/3] feat: base ui for create table gui --- pnpm-lock.yaml | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab0ef3d0a..9f66f9c3d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: '@monaco-editor/react': specifier: ^4.7.0 version: 4.7.0(monaco-editor@0.52.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-accordion': + specifier: ^1.2.12 + version: 1.2.12(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-alert-dialog': specifier: ^1.1.6 version: 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -50,6 +53,9 @@ importers: '@radix-ui/react-slot': specifier: ^1.1.2 version: 1.2.3(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-switch': + specifier: ^1.2.6 + version: 1.2.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-tabs': specifier: ^1.1.3 version: 1.1.13(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -7901,6 +7907,23 @@ snapshots: '@radix-ui/primitive@1.1.3': {} + '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.2 + '@types/react-dom': 19.2.2(@types/react@19.2.2) + '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -7924,6 +7947,22 @@ snapshots: '@types/react': 19.2.2 '@types/react-dom': 19.2.2(@types/react@19.2.2) + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.2 + '@types/react-dom': 19.2.2(@types/react@19.2.2) + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) @@ -8229,6 +8268,21 @@ snapshots: optionalDependencies: '@types/react': 19.2.2 + '@radix-ui/react-switch@1.2.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.2)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.2 + '@types/react-dom': 19.2.2(@types/react@19.2.2) + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@radix-ui/primitive': 1.1.3 From 02a77aa49409c8c52aa266b7d86ee94c46873162 Mon Sep 17 00:00:00 2001 From: Austin Akers Date: Wed, 12 Nov 2025 10:54:59 -0500 Subject: [PATCH 3/3] chore: Updated add new schema modal --- .../index.tsx | 2 +- .../components/ContentActions.tsx | 12 +++++- .../components/TextEditorView/index.tsx | 21 ++++++++++ src/features/instance/applications/index.tsx | 4 +- .../applications/modals/AddSchemaModal.tsx | 38 +++++++++++++++++++ src/lib/storage/watchedValueKeys.ts | 1 + 6 files changed, 75 insertions(+), 3 deletions(-) rename src/features/instance/applications/components/{CreateTableGUI => AddSchemaForm}/index.tsx (99%) create mode 100644 src/features/instance/applications/modals/AddSchemaModal.tsx diff --git a/src/features/instance/applications/components/CreateTableGUI/index.tsx b/src/features/instance/applications/components/AddSchemaForm/index.tsx similarity index 99% rename from src/features/instance/applications/components/CreateTableGUI/index.tsx rename to src/features/instance/applications/components/AddSchemaForm/index.tsx index d6b8833a2..852ef3c6f 100644 --- a/src/features/instance/applications/components/CreateTableGUI/index.tsx +++ b/src/features/instance/applications/components/AddSchemaForm/index.tsx @@ -12,7 +12,7 @@ import { Plus, TrashIcon } from 'lucide-react'; // import { zodResolver } from '@hookform/resolvers/zod'; import { useFieldArray, useForm } from 'react-hook-form'; -export function CreateTableGUI() { +export function AddSchemaForm() { const methods = useForm({ // resolver: zodResolver(), defaultValues: { diff --git a/src/features/instance/applications/components/ContentActions.tsx b/src/features/instance/applications/components/ContentActions.tsx index ebc7ffb04..31db89c64 100644 --- a/src/features/instance/applications/components/ContentActions.tsx +++ b/src/features/instance/applications/components/ContentActions.tsx @@ -7,7 +7,7 @@ import { useEditorView } from '@/features/instance/applications/hooks/useEditorV import { useInstanceBrowseManagePermission } from '@/hooks/usePermissions'; import { useEmitToListeners } from '@/lib/events/listener'; import { useSetWatchedValue } from '@/lib/events/watcher'; -import { FileIcon, FolderIcon, PackageIcon, PencilIcon, SaveIcon, TrashIcon, Undo2Icon } from 'lucide-react'; +import { FileIcon, FolderIcon, PackageIcon, PencilIcon, PlusIcon, SaveIcon, TrashIcon, Undo2Icon } from 'lucide-react'; export function ContentActions() { const instanceParams = useInstanceClientIdParams(); @@ -23,6 +23,7 @@ export function ContentActions() { const onRedeployClick = useSetWatchedValue('ShowRedeployApplicationModal', true); const onSaveClick = useEmitToListeners('SaveFile', true); const onRevertChangesClicked = useEmitToListeners('RevertChanges', true); + const onAddSchemaClick = useEmitToListeners('ShowAddSchemaModal', true); const fileIsClean = updatedFileContent === undefined || updatedFileContent === openedEntryContents; @@ -69,6 +70,15 @@ export function ContentActions() { Add Directory } + + {openedEntry.path.endsWith('.graphql') && canManageBrowseInstance && } {!!openedEntry.package && canManageBrowseInstance && !restrictPackageModification && + + + + + ); +} diff --git a/src/lib/storage/watchedValueKeys.ts b/src/lib/storage/watchedValueKeys.ts index 7de4bc741..64b04a424 100644 --- a/src/lib/storage/watchedValueKeys.ts +++ b/src/lib/storage/watchedValueKeys.ts @@ -2,6 +2,7 @@ export interface WatchedValuesTypeMap { RevertChanges: true; SaveFile: true; ShowAddDirectoryOrFileModalType: 'file' | 'directory' | false; + ShowAddSchemaModal: boolean; ShowDeleteDirectoryOrFileModal: boolean; ShowRedeployApplicationModal: boolean; ShowRenameFileModal: boolean;