Skip to content

Commit 691e587

Browse files
committed
env tab ui and push updates to it via env tab state store
1 parent 73850b5 commit 691e587

File tree

8 files changed

+146
-85
lines changed

8 files changed

+146
-85
lines changed

src/components/atoms/Tabs.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const Tabs = () => {
1919
'before:absolute before:h-[0.25rem] before:w-full before:bg-slate-300 before:content-[""] before:bottom-0 before:left-0';
2020
const tabCommonStyles =
2121
'tab flex items-center gap-x-2 border-r border-neutral-300 bg-transparent pr-0 tracking-[0.15em] transition duration-500 ease-in text-sm';
22-
const messageForConfirmActionModal = 'You have unsaved changes in the flowtest, are you sure you want to close it?';
22+
const messageForConfirmActionModal = `You have unsaved changes in the ${focusTab?.type}, are you sure you want to close it?`;
2323

2424
const handleCloseTab = (event, tab) => {
2525
event.stopPropagation();
@@ -34,6 +34,12 @@ const Tabs = () => {
3434
setConfirmActionModalOpen(true);
3535
return;
3636
}
37+
} else if (tab.type === OBJ_TYPES.environment) {
38+
if (tab.variablesDraft && !isEqual(tab.variables, tab.variablesDraft)) {
39+
console.debug(`Confirm close for tabId: ${tab.id} : collectionId: ${tab.collectionId}`);
40+
setConfirmActionModalOpen(true);
41+
return;
42+
}
3743
}
3844
closeTab(tab.id, tab.collectionId);
3945
};

src/components/molecules/environment/index.js

Lines changed: 49 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
11
import React from 'react';
2+
import useEnvStore from 'stores/EnvStore';
3+
import { EditText } from 'react-edit-text';
4+
import 'react-edit-text/dist/index.css';
5+
import { toast } from 'react-toastify';
6+
import { TrashIcon } from '@heroicons/react/24/outline';
7+
8+
const Env = () => {
9+
const variables = useEnvStore((state) => state.variables);
10+
const handleAddRow = useEnvStore((state) => state.handleAddRow);
11+
const handleKeyChange = useEnvStore((state) => state.handleKeyChange);
12+
const handleValueChange = useEnvStore((state) => state.handleValueChange);
13+
14+
const handleSave = ({ name, value, previousValue }) => {
15+
console.log('handle save');
16+
if (name === 'editVariableKey') {
17+
const existingVar = Object.keys(variables).find((key) => key === value);
18+
if (existingVar) {
19+
toast.error('A variable with the same name already exists');
20+
} else {
21+
handleKeyChange(value, previousValue);
22+
}
23+
} else {
24+
handleValueChange(name, value);
25+
}
26+
};
227

3-
const Env = ({ variables }) => {
428
return (
529
<div className='p-4'>
6-
<div>Test Tab panel for environment</div>
30+
{/* <div>Test Tab panel for environment</div> */}
731
<div className='overflow-x-auto'>
832
<table className='table table-zebra'>
933
{/* head */}
@@ -12,63 +36,34 @@ const Env = ({ variables }) => {
1236
<th></th>
1337
<th>Key</th>
1438
<th>Value</th>
15-
<th>New Value</th>
39+
{/* <th>New Value</th> */}
1640
</tr>
1741
</thead>
1842
<tbody>
19-
<tr>
20-
<th>1</th>
21-
<td>Test variable 1</td>
22-
<td>ABC</td>
23-
<td>
24-
<input
25-
type='text'
26-
className='block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 outline-blue-300 focus:border-blue-100 focus:ring-blue-100'
27-
placeholder='label'
28-
required
29-
onChange={(event) => {
30-
const labelValue = event.target.value;
31-
console.log(`New value for ABC: ${labelValue}`);
32-
}}
33-
/>
34-
</td>
35-
</tr>
36-
<tr>
37-
<th>2</th>
38-
<td>Test variable 2</td>
39-
<td>DEF</td>
40-
<td>
41-
<input
42-
type='text'
43-
className='block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 outline-blue-300 focus:border-blue-100 focus:ring-blue-100'
44-
placeholder='label'
45-
required
46-
onChange={(event) => {
47-
const labelValue = event.target.value;
48-
console.log(`New value for DEF: ${labelValue}`);
49-
}}
50-
/>
51-
</td>
52-
</tr>
53-
<tr>
54-
<th>3</th>
55-
<td>Test variable 3</td>
56-
<td>ZXE</td>
57-
<td>
58-
<input
59-
type='text'
60-
className='block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 outline-blue-300 focus:border-blue-100 focus:ring-blue-100'
61-
placeholder='label'
62-
required
63-
onChange={(event) => {
64-
const labelValue = event.target.value;
65-
console.log(`New value for ZXE: ${labelValue}`);
66-
}}
67-
/>
68-
</td>
69-
</tr>
43+
{Object.entries(variables).map(([key, value], index) => (
44+
<tr key={index}>
45+
<th>{index}</th>
46+
<td>
47+
<EditText name='editVariableKey' className='text-xl' value={key} onSave={handleSave} />
48+
</td>
49+
<td>
50+
<EditText name={key} className='text-xl' value={value} onSave={handleSave} />
51+
</td>
52+
<td>
53+
<div
54+
className='relative inline-block p-2 text-left transition duration-200 ease-out rounded rounded-l-none hover:bg-slate-200'
55+
onClick={() => {
56+
console.log(`Delete ${key}`);
57+
}}
58+
>
59+
<TrashIcon className='w-4 h-4' aria-hidden='true' />
60+
</div>
61+
</td>
62+
</tr>
63+
))}
7064
</tbody>
7165
</table>
66+
<button onClick={handleAddRow}>+ Add Variable</button>
7267
</div>
7368
</div>
7469
);

src/components/molecules/flow/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ const Flow = ({ collectionId }) => {
225225
onDragOver={onDragOver}
226226
//onNodeDragStop={() => setCanvasDirty()}
227227
isValidConnection={isValidConnection}
228-
//fitView
228+
fitView
229229
>
230230
<Controls>
231231
<ControlButton

src/components/molecules/flow/nodes/RequestNode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { PropTypes } from 'prop-types';
33
import RequestBody from './RequestBody';
44
import FlowNode from 'components/atoms/flow/FlowNode';
55
import { getInputType } from 'utils/common';
6-
import { PlusIcon, TrashIcon } from '@heroicons/react/24/solid';
6+
import { PlusIcon, TrashIcon } from '@heroicons/react/24/outline';
77
import { getDefaultValue } from 'utils/common';
88
import AddVariableModal from 'components/molecules/modals/flow/AddVariableModal';
99
import useCanvasStore from 'stores/CanvasStore';

src/components/molecules/headers/TabPanelHeader.js

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import SaveFlowModal from '../modals/SaveFlowModal';
1111

1212
import { useTabStore } from 'stores/TabStore';
1313
import Button from 'components/atoms/common/Button';
14-
import { BUTTON_TYPES } from 'constants/Common';
14+
import { BUTTON_TYPES, OBJ_TYPES } from 'constants/Common';
1515
import GenerateFlowTestModal from '../modals/GenerateFlowTestModal';
1616
import useCanvasStore from 'stores/CanvasStore';
1717

@@ -32,7 +32,7 @@ const TabPanelHeader = () => {
3232
<div className='flex items-center justify-between pl-4 gap-x-4'>
3333
<SaveFlowModal tab={focusTab} />
3434
{/* ToDo: Create our own side sheet component */}
35-
{graphRunLogs.length != 0 ? (
35+
{focusTab.type === OBJ_TYPES.flowtest && graphRunLogs.length != 0 ? (
3636
<div className='drawer drawer-end'>
3737
<input id='graph-logs-side-sheet' type='checkbox' className='drawer-toggle' />
3838
<div className='cursor-pointer drawer-content'>
@@ -72,23 +72,25 @@ const TabPanelHeader = () => {
7272
</Tippy>
7373
</button>
7474
</div>
75-
<div className='pl-4 border-l gen_ai_button border-neutral-300'>
76-
<Button
77-
btnType={BUTTON_TYPES.tertiary}
78-
isDisabled={false}
79-
onClickHandle={() => setGenerateFlowTestModalOpen(true)}
80-
fullWidth={true}
81-
className='flex items-center justify-between gap-x-4'
82-
>
83-
<SparklesIcon className='w-5 h-5' />
84-
Generate
85-
</Button>
86-
<GenerateFlowTestModal
87-
closeFn={() => setGenerateFlowTestModalOpen(false)}
88-
open={generateFlowTestModalOpen}
89-
collectionId={focusTab.collectionId}
90-
/>
91-
</div>
75+
{focusTab.type === OBJ_TYPES.flowtest && (
76+
<div className='pl-4 border-l gen_ai_button border-neutral-300'>
77+
<Button
78+
btnType={BUTTON_TYPES.tertiary}
79+
isDisabled={false}
80+
onClickHandle={() => setGenerateFlowTestModalOpen(true)}
81+
fullWidth={true}
82+
className='flex items-center justify-between gap-x-4'
83+
>
84+
<SparklesIcon className='w-5 h-5' />
85+
Generate
86+
</Button>
87+
<GenerateFlowTestModal
88+
closeFn={() => setGenerateFlowTestModalOpen(false)}
89+
open={generateFlowTestModalOpen}
90+
collectionId={focusTab.collectionId}
91+
/>
92+
</div>
93+
)}
9294
</div>
9395
</>
9496
) : (

src/components/molecules/workspace/WorkspaceContent.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ import useCanvasStore from 'stores/CanvasStore';
55
import TabPanelHeader from '../headers/TabPanelHeader';
66
import { OBJ_TYPES } from 'constants/Common';
77
import Env from '../environment';
8+
import useEnvStore from 'stores/EnvStore';
89

910
const WorkspaceContent = () => {
1011
const setNodes = useCanvasStore((state) => state.setNodes);
1112
const setEdges = useCanvasStore((state) => state.setEdges);
1213
const setLogs = useCanvasStore((state) => state.setLogs);
1314

15+
const setVariables = useEnvStore((state) => state.setVariables);
16+
1417
const focusTabId = useTabStore((state) => state.focusTabId);
1518
const tabs = useTabStore((state) => state.tabs);
1619
const focusTab = tabs.find((t) => t.id === focusTabId);
@@ -24,20 +27,15 @@ const WorkspaceContent = () => {
2427
setNodes(result.nodes);
2528
setEdges(result.edges);
2629
setLogs([]);
30+
} else if (focusTab.type === OBJ_TYPES.environment) {
31+
setVariables(focusTab.variablesDraft ? focusTab.variablesDraft : focusTab.variables);
2732
}
2833
}
2934

3035
return (
3136
<div className='flex flex-col h-full'>
32-
{focusTab &&
33-
(focusTab.type === OBJ_TYPES.flowtest ? (
34-
<>
35-
<TabPanelHeader />
36-
<Flow collectionId={focusTab.collectionId} />
37-
</>
38-
) : (
39-
<Env />
40-
))}
37+
<TabPanelHeader />
38+
{focusTab && (focusTab.type === OBJ_TYPES.flowtest ? <Flow collectionId={focusTab.collectionId} /> : <Env />)}
4139
</div>
4240
);
4341
};

src/stores/EnvStore.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { create } from 'zustand';
2+
import { useTabStore } from './TabStore';
3+
4+
const useEnvStore = create((set, get) => ({
5+
variables: {},
6+
setVariables: (variables) => {
7+
set({ variables });
8+
},
9+
handleAddRow: () => {
10+
set({
11+
variables: {
12+
...get().variables,
13+
'': '',
14+
},
15+
});
16+
useTabStore.getState().updateEnvTab(get().variables);
17+
},
18+
handleKeyChange: ({ newKey, previousKey }) => {
19+
set({
20+
variables: Object.keys(get().variables).reduce((newObj, key) => {
21+
if (key === previousKey) {
22+
newObj[newKey] = get().variables[key];
23+
} else {
24+
newObj[key] = get().variables[key];
25+
}
26+
return newObj;
27+
}, {}),
28+
});
29+
useTabStore.getState().updateEnvTab(get().variables);
30+
},
31+
handleValueChange: ({ key, newValue }) => {
32+
set({
33+
variables: Object.keys(get().variables).reduce((newObj, k) => {
34+
if (k === key) {
35+
newObj[k] = newValue;
36+
} else {
37+
newObj[k] = get().variables[k];
38+
}
39+
return newObj;
40+
}, {}),
41+
});
42+
useTabStore.getState().updateEnvTab(get().variables);
43+
},
44+
}));
45+
46+
export default useEnvStore;

src/stores/TabStore.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const useTabStore = create((set, get) => ({
4444
console.log(existingTab);
4545
}
4646
},
47+
// these state changes are meant to be triggered by canvas in focus
4748
updateFlowTestEdges: (edges) => {
4849
if (get().focusTabId) {
4950
const existingTab = get().tabs.find((t) => t.id === get().focusTabId);
@@ -68,6 +69,19 @@ export const useTabStore = create((set, get) => ({
6869
set((state) => ({ tabs: [...state.tabs, newTab] }));
6970
set(() => ({ focusTabId: newTab.id }));
7071
},
72+
// these state changes are meant to be triggered by env tab in focus
73+
updateEnvTab: (variables) => {
74+
if (get().focusTabId) {
75+
const existingTab = get().tabs.find((t) => t.id === get().focusTabId);
76+
if (existingTab) {
77+
if (!existingTab.variablesDraft) {
78+
existingTab.variablesDraft = cloneDeep(existingTab.variables);
79+
}
80+
existingTab.variablesDraft = variables;
81+
}
82+
console.log(existingTab);
83+
}
84+
},
7185
closeTab: (id, collectionId) => {
7286
set((state) => ({ tabs: state.tabs.filter((t) => t.id !== id) }));
7387
if (get().focusTabId === id) {

0 commit comments

Comments
 (0)