Skip to content

Commit e3a4e17

Browse files
committed
#259 - Add variable management components for collections and environments
1 parent 295dff9 commit e3a4e17

File tree

16 files changed

+377
-196
lines changed

16 files changed

+377
-196
lines changed

src/main/main.ts

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const createWindow = async () => {
2828
preload: path.join(__dirname, 'preload.js'),
2929
},
3030
});
31+
mainWindow.setFullScreen(true);
3132

3233
// Open links in default browser
3334
mainWindow.webContents.setWindowOpenHandler(({ url }) => {

src/renderer/components/shared/settings/SettingsModal.tsx

+51-19
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,48 @@ import {
77
DialogTrigger,
88
} from '@/components/ui/dialog';
99
import { FiSettings } from 'react-icons/fi';
10-
import {
11-
variableArrayToMap,
12-
VariableEditor,
13-
variableMapToArray,
14-
} from '@/components/shared/settings/VariableTab/VariableEditor';
1510
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
1611
import { Button } from '@/components/ui/button';
1712
import * as React from 'react';
1813
import { useState } from 'react';
19-
import { selectVariables, useVariableActions, useVariableStore } from '@/state/variableStore';
14+
import {
15+
selectCollectionVariables,
16+
selectEnvironmentVariables,
17+
useVariableActions,
18+
useVariableStore,
19+
} from '@/state/variableStore';
20+
import { CollectionVariableTab } from '@/components/shared/settings/variableTabs/CollectionVariableTab';
21+
import {
22+
variableArrayToMap,
23+
variableMapToArray,
24+
} from '@/components/shared/settings/variableTabs/helper/EditVariableHelper';
25+
import { EnvironmentVariableTab } from '@/components/shared/settings/variableTabs/EnvironmentVariableTab';
2026

2127
export const SettingsModal = () => {
22-
const { setVariables } = useVariableActions();
23-
const variables = useVariableStore((state) => selectVariables(state));
24-
const [editorVariables, setEditorVariables] = useState(variableMapToArray(variables));
28+
const actions = useVariableActions();
29+
const collectionStoreVariables = useVariableStore((state) => selectCollectionVariables(state));
30+
const environmentStoreVariables = useVariableStore((state) => selectEnvironmentVariables(state));
31+
32+
const [collectionVariables, setCollectionVariables] = useState(
33+
variableMapToArray(collectionStoreVariables)
34+
);
35+
const [environmentVariables, setEnvironmentVariables] = useState(environmentStoreVariables);
2536
const [isValid, setValid] = useState(false);
26-
const [isOpen, setOpen] = useState(false);
37+
const [isOpen, setOpen] = useState(true);
2738

2839
const save = async () => {
29-
console.info('Saving variables:', editorVariables);
30-
await setVariables(variableArrayToMap(editorVariables));
40+
await actions.setCollectionVariables(variableArrayToMap(collectionVariables));
41+
await setEnvironmentVariables(environmentVariables);
3142
setOpen(false);
3243
};
3344

45+
const apply = async () => {
46+
await actions.setCollectionVariables(variableArrayToMap(v));
47+
await setEnvironmentVariables(environmentVariables);
48+
};
49+
3450
const cancel = () => {
35-
setEditorVariables(variableMapToArray(variables));
51+
setCollectionVariables(variableMapToArray(collectionStoreVariables));
3652
setOpen(false);
3753
};
3854

@@ -45,15 +61,23 @@ export const SettingsModal = () => {
4561
<DialogHeader className="mt-auto">
4662
<DialogTitle>Settings</DialogTitle>
4763
</DialogHeader>
48-
<Tabs defaultValue="variables" className="h-[calc(50vh)]">
64+
<Tabs defaultValue="collectionVariables" className="h-[calc(50vh)]">
4965
<TabsList>
50-
<TabsTrigger value="variables">Variables</TabsTrigger>
66+
<TabsTrigger value="collectionVariables">CollectionVariables</TabsTrigger>
67+
<TabsTrigger value="environmentVariables">EnvironmentVariables</TabsTrigger>
5168
</TabsList>
52-
<TabsContent value="variables" className="max-h-[50vh] overflow-y-auto">
53-
<VariableEditor
54-
variables={editorVariables}
69+
<TabsContent value="collectionVariables" className="max-h-[50vh] overflow-y-auto">
70+
<CollectionVariableTab
71+
variables={collectionVariables}
72+
onValidChange={setValid}
73+
onVariablesChange={setCollectionVariables}
74+
/>
75+
</TabsContent>
76+
<TabsContent value="environmentVariables" className="max-h-[50vh] overflow-y-auto">
77+
<EnvironmentVariableTab
78+
environments={environmentVariables}
5579
onValidChange={setValid}
56-
onVariablesChange={setEditorVariables}
80+
onVariablesChange={setCollectionVariables} // TODO is wrong
5781
/>
5882
</TabsContent>
5983
</Tabs>
@@ -66,6 +90,14 @@ export const SettingsModal = () => {
6690
>
6791
<span className="leading-4 font-bold">Save</span>
6892
</Button>
93+
<Button
94+
className="mt-0 ml-0 mr-0 mb-0"
95+
onClick={apply}
96+
disabled={!isValid}
97+
variant={isValid ? 'secondary' : 'secondaryDisable'}
98+
>
99+
<span className="leading-4 font-bold">Apply</span>
100+
</Button>
69101
<Button className="mt-0 mr-2 mb-0" onClick={cancel} variant="destructive">
70102
<span className="leading-4 font-bold">Cancel</span>
71103
</Button>

src/renderer/components/shared/settings/VariableTab/VariableEditor.tsx

-163
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { VariableEditor } from '@/components/shared/settings/variableTabs/table/VariableEditor';
2+
import { VariableObjectWithKey } from 'shim/objects/variables';
3+
4+
export interface CollectionVariableTabProps {
5+
variables: VariableObjectWithKey[];
6+
onValidChange?: (valid: boolean) => void;
7+
onVariablesChange?: (variables: VariableObjectWithKey[]) => void;
8+
}
9+
10+
export const CollectionVariableTab = ({
11+
variables,
12+
onValidChange,
13+
onVariablesChange,
14+
}: CollectionVariableTabProps) => {
15+
return (
16+
<VariableEditor
17+
className="p-4 relative"
18+
variables={variables}
19+
onValidChange={onValidChange}
20+
onVariablesChange={onVariablesChange}
21+
></VariableEditor>
22+
);
23+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { VariableObjectWithKey } from 'shim/objects/variables';
2+
import { useEffect, useState } from 'react';
3+
import {
4+
Sidebar,
5+
SidebarHeader,
6+
SidebarMenuButton,
7+
SidebarProvider,
8+
} from '@/components/ui/sidebar';
9+
import { EnvironmentMap } from 'shim/objects/environment';
10+
import { variableMapToArray } from '@/components/shared/settings/variableTabs/helper/EditVariableHelper';
11+
import { VariableEditor } from '@/components/shared/settings/variableTabs/table/VariableEditor';
12+
13+
export interface EnvironmentVariableEditorProps {
14+
environments: EnvironmentMap;
15+
onValidChange?: (valid: boolean) => void;
16+
onVariablesChange?: (variables: VariableObjectWithKey[]) => void;
17+
}
18+
19+
/** A component that allows adding, editing and removing variables */
20+
export const EnvironmentVariableTab = ({
21+
environments,
22+
onVariablesChange,
23+
onValidChange,
24+
}: EnvironmentVariableEditorProps) => {
25+
const environmentList = Object.keys(environments);
26+
const firstEnvironmentKey = environmentList[0] as keyof EnvironmentMap;
27+
const firstEnvironment = environments[firstEnvironmentKey] ?? {};
28+
const [editorEnvironmentVariables, setEditorEnvironmentVariables] = useState(
29+
variableMapToArray(firstEnvironment)
30+
);
31+
const [selectedEnvironment, setSelectedEnvironment] = useState(environmentList[0]);
32+
33+
useEffect(() => {
34+
const selectedEnvironmentKey = selectedEnvironment as keyof EnvironmentMap;
35+
const selectedEnvironmentVariables = environments[selectedEnvironmentKey] ?? {};
36+
setEditorEnvironmentVariables(variableMapToArray(selectedEnvironmentVariables));
37+
}, [selectedEnvironment, environments]);
38+
39+
return (
40+
<div className="p-4 flex">
41+
<SidebarProvider>
42+
<Sidebar collapsible={'none'}>
43+
<SidebarHeader>Environments</SidebarHeader>
44+
{environmentList.map((environment) => (
45+
<SidebarMenuButton
46+
isActive={environment === selectedEnvironment}
47+
onClick={() => setSelectedEnvironment(environment)}
48+
className="mr-4"
49+
key={environment}
50+
>
51+
{environment}
52+
</SidebarMenuButton>
53+
))}
54+
<SidebarMenuButton> + Add Environment</SidebarMenuButton>
55+
</Sidebar>
56+
<VariableEditor
57+
className={'p-4 m-1 flex-1'}
58+
variables={editorEnvironmentVariables}
59+
onVariablesChange={onVariablesChange}
60+
onValidChange={onValidChange}
61+
/>
62+
</SidebarProvider>
63+
</div>
64+
);
65+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {
2+
VARIABLE_NAME_REGEX,
3+
VariableMap,
4+
VariableObject,
5+
VariableObjectWithKey,
6+
} from 'shim/objects/variables';
7+
8+
export function variableMapToArray(map: VariableMap) {
9+
return Object.entries(map).map<VariableObjectWithKey>(([key, variable]) => ({
10+
key,
11+
...variable,
12+
}));
13+
}
14+
15+
export function variableArrayToMap(array: VariableObjectWithKey[]) {
16+
return Object.fromEntries<VariableObject>(array.map(({ key, ...variable }) => [key, variable]));
17+
}
18+
19+
export function getInvalidVariableKeys(variables: VariableObjectWithKey[]) {
20+
const allKeys = new Set<string>();
21+
const invalidKeys = new Set<string>();
22+
for (const { key } of variables) {
23+
if (key === '' || key.length > 255 || allKeys.has(key) || !VARIABLE_NAME_REGEX.test(key)) {
24+
invalidKeys.add(key);
25+
}
26+
allKeys.add(key);
27+
}
28+
29+
return invalidKeys;
30+
}

0 commit comments

Comments
 (0)