From 3350094dd9427cac899fe507059cc3830faa5b01 Mon Sep 17 00:00:00 2001 From: Michael Giek Date: Sun, 12 Jan 2025 21:18:58 +0100 Subject: [PATCH] #118 - add Variables to SettingsModal --- .../service/environment-service.ts | 13 ++ src/main/event/main-event-service.ts | 6 + .../shared/settings/SettingsModal.tsx | 50 +++++-- .../settings/VariableTab/VariableTab.tsx | 129 ++++++++++++++++++ src/renderer/components/sidebar/FooterBar.tsx | 3 +- src/renderer/components/ui/dialog.tsx | 3 +- src/renderer/components/ui/tabs.tsx | 2 +- src/renderer/index.tsx | 2 +- .../services/event/renderer-event-service.ts | 1 + src/renderer/state/settingsStore.ts | 74 ++++++++++ src/shim/event-service.ts | 6 + 11 files changed, 275 insertions(+), 14 deletions(-) create mode 100644 src/renderer/components/shared/settings/VariableTab/VariableTab.tsx create mode 100644 src/renderer/state/settingsStore.ts diff --git a/src/main/environment/service/environment-service.ts b/src/main/environment/service/environment-service.ts index f58a51da..6e62c004 100644 --- a/src/main/environment/service/environment-service.ts +++ b/src/main/environment/service/environment-service.ts @@ -51,6 +51,15 @@ export class EnvironmentService implements Initializable { } } + /** + * Sets and saves all variables in the current collection. + * @param variables + */ + public setAndSaveAllVariables(variables: VariableObject[]) { + this.currentCollection.variables = {}; + variables.forEach((variable) => (this.currentCollection.variables[variable.key] = variable)); + } + /** * Enables or disables a variable in the current collection. * @@ -96,4 +105,8 @@ export class EnvironmentService implements Initializable { private getVariableValue(key: string) { return this.getVariable(key)?.value; } + + public setVariable(variable: VariableObject) { + return this.currentCollection.variables[variable.key] = variable; + } } diff --git a/src/main/event/main-event-service.ts b/src/main/event/main-event-service.ts index 5e21b0af..aa80ff3f 100644 --- a/src/main/event/main-event-service.ts +++ b/src/main/event/main-event-service.ts @@ -6,6 +6,7 @@ import { PersistenceService } from '../persistence/service/persistence-service'; import { TrufosObject } from 'shim/objects'; import { EnvironmentService } from 'main/environment/service/environment-service'; import './stream-events'; +import { VariableObject } from '../../shim/variables'; const persistenceService = PersistenceService.instance; const environmentService = EnvironmentService.instance; @@ -100,4 +101,9 @@ export class MainEventService implements IEventService { async getVariable(key: string) { return environmentService.getVariable(key); } + + async setAndSaveAllVariables(variables: VariableObject[]) { + environmentService.setAndSaveAllVariables(variables); + await persistenceService.saveCollection(environmentService.currentCollection); + } } diff --git a/src/renderer/components/shared/settings/SettingsModal.tsx b/src/renderer/components/shared/settings/SettingsModal.tsx index db17924a..f3089f63 100644 --- a/src/renderer/components/shared/settings/SettingsModal.tsx +++ b/src/renderer/components/shared/settings/SettingsModal.tsx @@ -1,27 +1,57 @@ import { - Dialog, + Dialog, DialogClose, DialogContent, - DialogDescription, + DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog'; import { FiSettings } from 'react-icons/fi'; +import { VariableTab } from '@/components/shared/settings/VariableTab/VariableTab'; +import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; +import { useVariableStore } from '@/state/settingsStore'; +import { Button } from '@/components/ui/button'; +import * as React from 'react'; export const SettingsModal = () => { + const { save, cancel, openModal } = useVariableStore.getState(); + const isOpen = useVariableStore((state) => state.isOpen); + return ( - - + + - - - Lorem ipsusm? - - Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur + + + Settings + + + + + Variables + + + + + + + +
+ + +
+
+
); -}; +}; \ No newline at end of file diff --git a/src/renderer/components/shared/settings/VariableTab/VariableTab.tsx b/src/renderer/components/shared/settings/VariableTab/VariableTab.tsx new file mode 100644 index 00000000..bcc9944b --- /dev/null +++ b/src/renderer/components/shared/settings/VariableTab/VariableTab.tsx @@ -0,0 +1,129 @@ +import { Divider } from '@/components/shared/Divider'; +import { Button } from '@/components/ui/button'; +import { AddIcon, CheckedIcon, DeleteIcon } from '@/components/icons'; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table'; +import { cn } from '@/lib/utils'; +import { useVariableStore } from '@/state/settingsStore'; + +export function VariableTab() { + + const { addNewVariable, deleteVariable, update } = useVariableStore(); + const allVariables = useVariableStore((state) => state.variables); + + return ( +
+
+
+ +
+ + +
+ +
+ + + + Key + Value + Description + {/* Action Column */} + + + + + {allVariables.map((variable, index) => ( + + + update(index, e.target.value, 'key')} + /> + + + + update(index, e.target.value, 'value')} + /> + + + + update(index, e.target.value, 'description')} + className="w-full bg-transparent outline-none" + placeholder="Enter variable description" + /> + + + +
+
+ update(index, e.target.checked, 'isActive')} + className={cn( + 'form-checkbox h-4 w-4 appearance-none border rounded-[2px] ', + variable.isActive + ? 'border-[rgba(107,194,224,1)] bg-[rgba(25,54,65,1)]' + : 'border-[rgba(238,238,238,1)] bg-transparent' + )} + /> + + {variable.isActive && ( +
+ +
+ )} +
+ + +
+
+
+ ))} +
+
+
+
+ ); +} diff --git a/src/renderer/components/sidebar/FooterBar.tsx b/src/renderer/components/sidebar/FooterBar.tsx index e178ab35..8d765afd 100644 --- a/src/renderer/components/sidebar/FooterBar.tsx +++ b/src/renderer/components/sidebar/FooterBar.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'; import { RendererEventService } from '@/services/event/renderer-event-service'; import { GithubIcon } from '@/components/icons'; +import { SettingsModal } from '@/components/shared/settings/SettingsModal'; export function FooterBar() { const [appVersion, setAppVersion] = useState(undefined); @@ -25,7 +26,7 @@ export function FooterBar() { > {/* Adjust the size as needed */} - {/**/} + ); } diff --git a/src/renderer/components/ui/dialog.tsx b/src/renderer/components/ui/dialog.tsx index 6f1ab0e7..ac7e44f6 100644 --- a/src/renderer/components/ui/dialog.tsx +++ b/src/renderer/components/ui/dialog.tsx @@ -32,7 +32,7 @@ const DialogContent = React.forwardRef< React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - + Close + )); DialogContent.displayName = DialogPrimitive.Content.displayName; diff --git a/src/renderer/components/ui/tabs.tsx b/src/renderer/components/ui/tabs.tsx index fd67be27..1a4202ff 100644 --- a/src/renderer/components/ui/tabs.tsx +++ b/src/renderer/components/ui/tabs.tsx @@ -9,7 +9,7 @@ const Tabs = React.forwardRef< >(({ className, ...props }, ref) => ( )); diff --git a/src/renderer/index.tsx b/src/renderer/index.tsx index c5587253..5ae40acb 100644 --- a/src/renderer/index.tsx +++ b/src/renderer/index.tsx @@ -29,4 +29,4 @@ RendererEventService.instance.loadCollection().then((collection) => { const requests = collection.children.filter((c) => c.type === 'request') as TrufosRequest[]; initialize({ requests, collectionId: collection.id }); root.render(); -}); +}); \ No newline at end of file diff --git a/src/renderer/services/event/renderer-event-service.ts b/src/renderer/services/event/renderer-event-service.ts index d2bece78..57d5a814 100644 --- a/src/renderer/services/event/renderer-event-service.ts +++ b/src/renderer/services/event/renderer-event-service.ts @@ -11,6 +11,7 @@ const METHOD_NAMES = new Set([ 'deleteObject', 'getActiveEnvironmentVariables', 'getVariable', + 'setAndSaveAllVariables', ]); const INSTANCE = {} as IEventService; diff --git a/src/renderer/state/settingsStore.ts b/src/renderer/state/settingsStore.ts new file mode 100644 index 00000000..8ae7afb1 --- /dev/null +++ b/src/renderer/state/settingsStore.ts @@ -0,0 +1,74 @@ +import { create } from 'zustand'; +import { immer } from 'zustand/middleware/immer'; +import { VariableObject } from 'shim/variables'; +import { RendererEventService } from '@/services/event/renderer-event-service'; + +interface VariableState { + variables: VariableObject[]; + collectionId: string; + isOpen: boolean; +} + +interface VariableStateAction { + openModal: () => void; + addNewVariable: () => void; + deleteVariable: (index: number) => void; + update: (index: number, changeValue: string | boolean, key: keyof VariableObject) => void; + save: () => void; + cancel: () => void; +} + +export const useVariableStore = create()( + immer((set, get) => ({ + variables: [], + collectionId: '', + isOpen: false, + openModal: () => { + RendererEventService.instance.loadCollection().then((collection) => { + const variables = Object.values(collection.variables); + set({ + variables: variables, + collectionId: collection.id, + isOpen: true, + }); + }); + }, + addNewVariable: () => { + set((state) => { + console.log('addNewVariable', state.variables); + state.variables.push({ + key: '', + value: '', + description: '', + isActive: false, + }); + }); + }, + deleteVariable: (index: number) => { + console.log('deleteVariable', index); + set((state) => { + state.variables.splice(index, 1); + }); + }, + update: async (index: number, changeValue: string | boolean, key: keyof VariableObject) => + set((state) => { + console.log('update', index, changeValue, key); + state.variables[index] = { + ...state.variables[index], + [key]: changeValue, + }; + }), + save: async () => { + RendererEventService.instance.setAndSaveAllVariables(get().variables); + set((state) => { + state.variables = []; + state.isOpen = false; + }); + }, + cancel: async () => + set((state) => { + state.variables = []; + state.isOpen = false; + }), + })) +); \ No newline at end of file diff --git a/src/shim/event-service.ts b/src/shim/event-service.ts index 4fcd9b41..f6cfb964 100644 --- a/src/shim/event-service.ts +++ b/src/shim/event-service.ts @@ -63,4 +63,10 @@ export interface IEventService { * @param key The key of the variable. */ getVariable(key: string): Promise; + + /** + * Set a variable. + * @param variables + */ + setAndSaveAllVariables(variables: VariableObject[]): void; }