Skip to content

Commit 36d9a5f

Browse files
committed
addd notification events chips
1 parent fa988b6 commit 36d9a5f

File tree

2 files changed

+147
-70
lines changed

2 files changed

+147
-70
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import React, { useState, useCallback } from 'react';
2+
3+
import { Cluster } from './cluster';
4+
import {
5+
FormControl,
6+
InputLabel,
7+
MenuItem,
8+
TextField,
9+
Chip
10+
} from '@mui/material';
11+
import { ICreateJobModel } from '../model';
12+
import Select, { SelectChangeEvent } from '@mui/material/Select';
13+
import { Stack } from './stack';
14+
import { useTranslator } from '../hooks';
15+
16+
interface INotificationPickerProps {
17+
notificationEvents: string[];
18+
id: string;
19+
model: ICreateJobModel;
20+
handleModelChange: (model: ICreateJobModel) => void;
21+
}
22+
23+
export function NotificationPicker({
24+
notificationEvents,
25+
id,
26+
model,
27+
handleModelChange: modelChange
28+
}: INotificationPickerProps): JSX.Element | null {
29+
const trans = useTranslator('jupyterlab');
30+
const [selectedEvents, setSelectedEvents] = useState<string[]>(
31+
model.notification?.selectedEvents || []
32+
);
33+
34+
const selectChange = useCallback(
35+
(e: SelectChangeEvent<string>) => {
36+
const newEvent = e.target.value;
37+
if (!selectedEvents.includes(newEvent)) {
38+
const updatedEvents = [...selectedEvents, newEvent];
39+
setSelectedEvents(updatedEvents);
40+
modelChange({
41+
...model,
42+
notification: {
43+
...model.notification,
44+
sendTo: model.notification?.sendTo || '',
45+
selectedEvents: updatedEvents
46+
}
47+
});
48+
}
49+
},
50+
[selectedEvents, model, modelChange]
51+
);
52+
53+
const sendToChange = useCallback(
54+
(e: React.ChangeEvent<HTMLInputElement>) => {
55+
const { value } = e.target;
56+
const updatedNotification = { ...model.notification, sendTo: value };
57+
modelChange({ ...model, notification: updatedNotification });
58+
},
59+
[model, modelChange]
60+
);
61+
62+
const deleteSelectedEvent = useCallback(
63+
(eventToDelete: string) => () => {
64+
const updatedEvents = selectedEvents.filter(
65+
event => event !== eventToDelete
66+
);
67+
setSelectedEvents(updatedEvents);
68+
modelChange({
69+
...model,
70+
notifications: { ...model.notification, selectedEvents: updatedEvents }
71+
});
72+
},
73+
[selectedEvents, model, modelChange]
74+
);
75+
76+
if (!notificationEvents.length) {
77+
return null;
78+
}
79+
80+
return (
81+
<Stack size={2}>
82+
<InputLabel>{trans.__('Notifications')}</InputLabel>
83+
<TextField
84+
label={trans.__('Send To')}
85+
value={model.notification?.sendTo || ''}
86+
name="sendTo"
87+
variant="outlined"
88+
onChange={sendToChange}
89+
/>
90+
<NotificationEventsSelect
91+
id={id}
92+
availableEvents={notificationEvents.filter(
93+
e => !selectedEvents.includes(e)
94+
)}
95+
selectChange={selectChange}
96+
/>
97+
<SelectedEventsChips
98+
selectedEvents={selectedEvents}
99+
deleteSelectedEvent={deleteSelectedEvent}
100+
/>
101+
</Stack>
102+
);
103+
}
104+
105+
const NotificationEventsSelect: React.FC<{
106+
id: string;
107+
availableEvents: string[];
108+
selectChange: (e: SelectChangeEvent<string>) => void;
109+
}> = ({ id, availableEvents, selectChange: handleSelectChange }) => {
110+
const trans = useTranslator('jupyterlab');
111+
const label = trans.__('Notification Events');
112+
const labelId = `${id}-label`;
113+
114+
return (
115+
<FormControl>
116+
<InputLabel id={labelId}>{label}</InputLabel>
117+
<Select
118+
labelId={labelId}
119+
id={id}
120+
label={label}
121+
onChange={handleSelectChange}
122+
>
123+
{availableEvents.map(e => (
124+
<MenuItem key={e} value={e}>
125+
{e}
126+
</MenuItem>
127+
))}
128+
</Select>
129+
</FormControl>
130+
);
131+
};
132+
133+
const SelectedEventsChips: React.FC<{
134+
selectedEvents: string[];
135+
deleteSelectedEvent: (eventToDelete: string) => () => void;
136+
}> = ({ selectedEvents, deleteSelectedEvent }) => (
137+
<Cluster gap={3} justifyContent="flex-start">
138+
{selectedEvents.map(e => (
139+
<Chip
140+
key={e}
141+
label={e}
142+
variant="outlined"
143+
onDelete={deleteSelectedEvent(e)}
144+
/>
145+
))}
146+
</Cluster>
147+
);

src/components/notifications-picker.tsx

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)