Skip to content

Commit f8805a8

Browse files
committed
chore: create workspace environment selection component
Signed-off-by: amitamrutiya <[email protected]>
1 parent d9c2ae2 commit f8805a8

File tree

2 files changed

+179
-3
lines changed

2 files changed

+179
-3
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
/* eslint-disable @typescript-eslint/ban-ts-comment */
3+
import { FunctionComponent } from 'react';
4+
import { Autocomplete, Chip, TextField } from '../../base';
5+
6+
interface Environment {
7+
id: string;
8+
name: string;
9+
}
10+
11+
interface EnvironmentOption {
12+
label: string;
13+
value: string;
14+
}
15+
16+
interface WorkspaceEnvironmentSelectionProps {
17+
workspaceId: string;
18+
useAssignEnvironmentToWorkspaceMutation: any;
19+
useGetEnvironmentsOfWorkspaceQuery: any;
20+
useUnassignEnvironmentFromWorkspaceMutation: any;
21+
useNotificationHandlers: () => {
22+
handleSuccess: (message: string) => void;
23+
handleError: (message: string) => void;
24+
};
25+
isAssignedEnvironmentAllowed: boolean;
26+
}
27+
28+
const WorkspaceEnvironmentSelection: FunctionComponent<WorkspaceEnvironmentSelectionProps> = ({
29+
workspaceId,
30+
useAssignEnvironmentToWorkspaceMutation,
31+
useGetEnvironmentsOfWorkspaceQuery,
32+
useUnassignEnvironmentFromWorkspaceMutation,
33+
useNotificationHandlers,
34+
isAssignedEnvironmentAllowed
35+
}) => {
36+
const { handleSuccess, handleError } = useNotificationHandlers();
37+
38+
const { data: environmentsResponse, isLoading } = useGetEnvironmentsOfWorkspaceQuery({
39+
workspaceId,
40+
page: 0,
41+
pagesize: 'all',
42+
filter: '{"assigned":false}'
43+
});
44+
45+
const { data: environmentsOfWorkspace, isLoading: isEnvLoading } =
46+
useGetEnvironmentsOfWorkspaceQuery({
47+
workspaceId,
48+
page: 0,
49+
pagesize: 'all'
50+
});
51+
52+
const _environmentOptions: EnvironmentOption[] =
53+
environmentsResponse?.environments?.map((env: Environment) => ({
54+
label: env.name,
55+
value: env.id
56+
})) || [];
57+
58+
const _environmentValues: EnvironmentOption[] =
59+
environmentsOfWorkspace?.environments?.map((env: Environment) => ({
60+
label: env.name,
61+
value: env.id
62+
})) || [];
63+
64+
const [assignEnvironmentToWorkspace] = useAssignEnvironmentToWorkspaceMutation();
65+
const [unassignEnvironmentFromWorkspace] = useUnassignEnvironmentFromWorkspaceMutation();
66+
67+
const handleEnvironmentSelect = (
68+
selectedValues: EnvironmentOption[],
69+
unselectedValues: EnvironmentOption[]
70+
): void => {
71+
const selectedEnvs = selectedValues.map((env) => env.value);
72+
const unselectedEnvs = unselectedValues.map((env) => env.value);
73+
74+
if (unselectedEnvs.length > 0) {
75+
unselectedEnvs.forEach((envId) => {
76+
// Find environment name for the unassigned environment
77+
const envName =
78+
environmentsOfWorkspace?.environments?.find((env: Environment) => env.id === envId)
79+
?.name || 'Unknown';
80+
81+
unassignEnvironmentFromWorkspace({
82+
workspaceId,
83+
environmentId: envId
84+
})
85+
.unwrap()
86+
.then(() => handleSuccess(`Environment "${envName}" unassigned`))
87+
.catch((error: { data: string }) =>
88+
handleError(`Environment "${envName}" Unassign Error: ${error?.data}`)
89+
);
90+
});
91+
return;
92+
}
93+
94+
if (selectedEnvs.length > 0) {
95+
selectedEnvs.forEach((envId) => {
96+
if (_environmentValues.find((env) => env.value === envId)) {
97+
return;
98+
}
99+
100+
// Find environment name for the assigned environment
101+
const envName =
102+
environmentsResponse?.environments?.find((env: Environment) => env.id === envId)?.name ||
103+
'Unknown';
104+
105+
assignEnvironmentToWorkspace({
106+
workspaceId,
107+
environmentId: envId
108+
})
109+
.unwrap()
110+
.then(() => handleSuccess(`Environment "${envName}" assigned`))
111+
.catch((error: { data: string }) =>
112+
handleError(`Environment "${envName}" Assign Error: ${error?.data}`)
113+
);
114+
});
115+
return;
116+
}
117+
};
118+
119+
// Handle select change
120+
const handleChange = (
121+
_event: React.SyntheticEvent,
122+
selectedOptions: EnvironmentOption[]
123+
): void => {
124+
const currentValues = _environmentValues || [];
125+
const selectedValues = selectedOptions || [];
126+
127+
// Determine which items were selected and which were unselected
128+
const newlySelected = selectedValues.filter(
129+
(option) => !currentValues.some((item) => item.value === option.value)
130+
);
131+
132+
const newlyUnselected = currentValues.filter(
133+
(item) => !selectedValues.some((option) => option.value === item.value)
134+
);
135+
136+
handleEnvironmentSelect(newlySelected, newlyUnselected);
137+
};
138+
139+
return (
140+
<div onClick={(e) => e.stopPropagation()} style={{ marginBlock: '1rem', maxWidth: '15rem' }}>
141+
<Autocomplete
142+
//@ts-ignore
143+
multiple
144+
options={_environmentOptions}
145+
value={_environmentValues}
146+
loading={isLoading || isEnvLoading}
147+
//@ts-ignore
148+
onChange={handleChange}
149+
size="small"
150+
disableCloseOnSelect
151+
getOptionLabel={(option: unknown) => (option as EnvironmentOption).label}
152+
renderTags={(value: unknown) =>
153+
(value as EnvironmentOption[]).map((option) => (
154+
<Chip
155+
key={option.value}
156+
label={option.label}
157+
size="small"
158+
style={{
159+
margin: '0.15rem',
160+
borderRadius: '0.2rem'
161+
}}
162+
onDelete={() => {
163+
unassignEnvironmentFromWorkspace({
164+
workspaceId,
165+
environmentId: option.value
166+
});
167+
}}
168+
/>
169+
))
170+
}
171+
renderInput={(params) => <TextField {...params} placeholder="Assigned Environment" />}
172+
popupIcon={null}
173+
disabled={!isAssignedEnvironmentAllowed}
174+
/>
175+
</div>
176+
);
177+
};
178+
179+
export default WorkspaceEnvironmentSelection;

src/custom/Workspaces/helper.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export const parseDeletionTimestamp = (data: {
2727
* formatShortDateTime("2024-01-01T09:30:00") // Returns "Jan 1, 2024, 09:30 AM"
2828
* formatShortDateTime(new Date()) // Returns current date-time in short format
2929
*
30-
* Generated by Copilot
3130
*/
3231
export const formatShortDateTime = (date: Date | string): string => {
3332
return new Date(date).toLocaleDateString('en-US', {
@@ -49,7 +48,6 @@ export const formatShortDateTime = (date: Date | string): string => {
4948
* formatShortDate("2024-01-01") // Returns "Jan 1, 2024"
5049
* formatShortDate(new Date()) // Returns current date in short format
5150
*
52-
* Generated by Copilot
5351
*/
5452
export const formatShortDate = (date: Date | string): string => {
5553
return new Date(date).toLocaleDateString('en-US', {
@@ -69,7 +67,6 @@ export const formatShortDate = (date: Date | string): string => {
6967
* formattoLongDate("2024-01-01") // Returns "January 1, 2024"
7068
* formattoLongDate(new Date()) // Returns current date in long format
7169
*
72-
* Generated by Copilot
7370
*/
7471
export const formattoLongDate = (date: Date | string): string => {
7572
return new Date(date).toLocaleDateString('en-US', {

0 commit comments

Comments
 (0)