Skip to content

Commit 8d57fc3

Browse files
committed
Small changes, solved merge conflicts
2 parents 0cf00ff + f728b73 commit 8d57fc3

File tree

24 files changed

+717
-106
lines changed

24 files changed

+717
-106
lines changed

app/back-end/gunicorn_config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,8 @@
2323
# Use Gevent worker class for handling asynchronous requests with WebSocket support
2424
worker_class = "geventwebsocket.gunicorn.workers.GeventWebSocketWorker"
2525

26+
# Maximum number of simultaneous connections
27+
worker_connections = 1
28+
2629
# Number of worker processes
2730
workers = multiprocessing.cpu_count() * 2 + 1

app/back-end/src/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@
3131

3232
# Events
3333
CONSOLE_FEEDBACK_EVENT = "console_feedback"
34+
WORKSPACE_FILE_SAVE_FEEDBACK_EVENT = "workspace_file_save_feedback"

app/back-end/src/routes/workspace_route.py

Lines changed: 310 additions & 19 deletions
Large diffs are not rendered by default.

app/front-end/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
"@mui/x-tree-view": "^7.12.1",
1919
"@react-spring/web": "^9.7.4",
2020
"axios": "^1.7.4",
21-
"papaparse": "^5.4.1",
2221
"react": "^18.3.1",
2322
"react-dom": "^18.3.1",
2423
"react-router-dom": "^6.26.0",
@@ -27,7 +26,6 @@
2726
"devDependencies": {
2827
"@mui/x-data-grid-generator": "^7.12.1",
2928
"@types/node": "^22.2.0",
30-
"@types/papaparse": "^5.3.14",
3129
"@types/react": "^18.3.3",
3230
"@types/react-dom": "^18.3.0",
3331
"@typescript-eslint/eslint-plugin": "^7.15.0",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { SettingsDialog } from './settingsDialog/settingsDialog';
2+
export { ShortcutsDialog } from './shortcutsDialog/shortcutsDialog';
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { SettingsDialog } from './settingsDialog';
2+
export { SettingSpacer } from './settingSpacer';
3+
export { SettingsSelectField } from './settingsSelectField';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Box } from '@mui/material';
2+
3+
export const SettingSpacer = ({ size = 3 }) => {
4+
return <Box mb={size} />;
5+
};
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { SettingSpacer } from '@/components/dialogs/settingsDialog';
2+
import { ColorModeSetting, LanguageSetting, TimeZoneSetting } from '@/components/dialogs/settingsDialog/settingsFields';
3+
import { Close as CloseIcon } from '@mui/icons-material';
4+
import { alpha, Box, Dialog, DialogContent, DialogTitle, Grid, IconButton, styled, useTheme } from '@mui/material';
5+
6+
const BootstrapDialog = styled(Dialog)(({ theme }) => ({
7+
backdropFilter: 'blur(5px)',
8+
'& .MuiDialogContent-root': {
9+
padding: '1.5rem',
10+
},
11+
'& .MuiDialogActions-root': {
12+
padding: '1.5rem',
13+
},
14+
'& .MuiDialog-paper': {
15+
borderRadius: '1.5rem',
16+
minWidth: '25%',
17+
backgroundColor: theme.palette.background.paper,
18+
backgroundImage: 'none',
19+
},
20+
}));
21+
22+
interface SettingsDialogProps {
23+
open: boolean;
24+
onClose: () => void;
25+
}
26+
27+
export const SettingsDialog: React.FC<SettingsDialogProps> = ({ open, onClose }) => {
28+
const Theme = useTheme();
29+
30+
return (
31+
<BootstrapDialog onClose={onClose} open={open}>
32+
<Grid container spacing={2} justifyContent='center' alignItems='center'>
33+
<Grid item xs={8}>
34+
<DialogTitle sx={{ color: Theme.palette.primary.main, pl: '1.5rem', pt: '1.5rem', fontWeight: '700' }}>
35+
Settings
36+
</DialogTitle>
37+
</Grid>
38+
<Grid item xs={4}>
39+
<Box display='flex' justifyContent='flex-end'>
40+
<IconButton
41+
aria-label='close'
42+
onClick={onClose}
43+
sx={{
44+
color: Theme.palette.primary.main,
45+
mt: '0.5rem',
46+
mr: '1.5rem',
47+
}}
48+
>
49+
<CloseIcon />
50+
</IconButton>
51+
</Box>
52+
</Grid>
53+
</Grid>
54+
<DialogContent sx={{ borderTop: `1px solid ${alpha(Theme.palette.text.secondary, 0.3)}` }}>
55+
<ColorModeSetting />
56+
<SettingSpacer />
57+
<LanguageSetting />
58+
<SettingSpacer />
59+
<TimeZoneSetting />
60+
</DialogContent>
61+
</BootstrapDialog>
62+
);
63+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { SettingsSelectField } from '@/components/dialogs/settingsDialog';
2+
import { useThemeContext } from '@/hooks';
3+
4+
export const ColorModeSetting = () => {
5+
const ThemeContext = useThemeContext();
6+
7+
const handleThemeChange = () => {
8+
ThemeContext.update();
9+
};
10+
11+
return (
12+
<SettingsSelectField
13+
title='Color mode'
14+
description='Toggle between light and dark modes'
15+
settings={[
16+
{ value: 'light', label: 'Light' },
17+
{ value: 'dark', label: 'Dark' },
18+
]}
19+
value={ThemeContext.mode}
20+
onChange={handleThemeChange}
21+
/>
22+
);
23+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { ColorModeSetting } from './colorModeSetting';
2+
export { LanguageSetting } from './languageSetting';
3+
export { TimeZoneSetting } from './timeZoneSetting';
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { SettingsSelectField } from '@/components/dialogs/settingsDialog';
2+
import { SelectChangeEvent } from '@mui/material';
3+
import { useState } from 'react';
4+
5+
export const LanguageSetting = () => {
6+
// TODO: Implement language switching functionality and replace with correct values
7+
8+
const [switchLanguage, setSwitchLanguage] = useState('en');
9+
10+
const handleLanguageChange = (event: SelectChangeEvent<string>) => {
11+
const selectedLanguage = event.target.value;
12+
setSwitchLanguage(selectedLanguage);
13+
};
14+
15+
return (
16+
<SettingsSelectField
17+
title='Language'
18+
description='Change the language of the application'
19+
settings={[
20+
{ value: 'en', label: 'English' },
21+
{ value: 'lt', label: 'Lithuanian' },
22+
{ value: 'it', label: 'Italian' },
23+
]}
24+
value={switchLanguage}
25+
onChange={handleLanguageChange}
26+
/>
27+
);
28+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { SettingsSelectField } from '@/components/dialogs/settingsDialog';
2+
import { SelectChangeEvent } from '@mui/material';
3+
import { useState } from 'react';
4+
5+
export const TimeZoneSetting = () => {
6+
// TODO: Implement time zone switching functionality and replace with correct values
7+
8+
const [switchTimeZone, setSwitchTimeZone] = useState('GMT+3');
9+
10+
const handleTimeZoneChange = (event: SelectChangeEvent<string>) => {
11+
const selectedValue = event.target.value;
12+
setSwitchTimeZone(selectedValue);
13+
};
14+
15+
return (
16+
<SettingsSelectField
17+
title='Time zone'
18+
description='Change the time zone of the application'
19+
settings={[{ value: 'GMT+3', label: 'GMT+3' }]}
20+
value={switchTimeZone}
21+
onChange={handleTimeZoneChange}
22+
/>
23+
);
24+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { Box, FormControl, Grid, MenuItem, Select, SelectChangeEvent, Typography, useTheme } from '@mui/material';
2+
import React from 'react';
3+
4+
interface Setting {
5+
value: string | undefined;
6+
label: string;
7+
}
8+
9+
interface SettingsSelectFieldProps {
10+
title: string;
11+
description: string;
12+
settings: Setting[];
13+
value: string | undefined;
14+
onChange: (event: SelectChangeEvent) => void;
15+
}
16+
17+
export const SettingsSelectField: React.FC<SettingsSelectFieldProps> = ({
18+
title,
19+
description,
20+
settings,
21+
value,
22+
onChange,
23+
}) => {
24+
const Theme = useTheme();
25+
26+
return (
27+
<Grid container spacing={2} justifyContent='center' alignItems='center'>
28+
<Grid item xs={8}>
29+
<Typography sx={{ fontSize: '1.1rem', fontWeight: '500' }}>{title}</Typography>
30+
<Typography sx={{ fontSize: '0.9rem', color: Theme.palette.text.secondary }}>{description}</Typography>
31+
</Grid>
32+
<Grid item xs={4}>
33+
<Box display='flex' justifyContent='flex-end'>
34+
<FormControl sx={{ minWidth: 120 }}>
35+
<Select
36+
value={value}
37+
onChange={onChange}
38+
displayEmpty
39+
size='small'
40+
inputProps={{ 'aria-label': 'Without label' }}
41+
>
42+
{settings.map((setting) => (
43+
<MenuItem key={setting.value} value={setting.value}>
44+
{setting.label}
45+
</MenuItem>
46+
))}
47+
</Select>
48+
</FormControl>
49+
</Box>
50+
</Grid>
51+
</Grid>
52+
);
53+
};

app/front-end/src/components/layouts/baseLayout.tsx

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { IconTitleButton } from '@/components/buttons/IconTitleButton';
2-
import { ShortcutsDialog } from '@/components/dialogs/shortcutsDialog';
3-
import { useThemeContext } from '@/hooks';
2+
import { SettingsDialog, ShortcutsDialog } from '@/components/dialogs';
43
import { Colors } from '@/types';
5-
import { AutoMode, DarkMode, Home, LightMode, SettingsOutlined, SwitchAccessShortcut } from '@mui/icons-material';
4+
import {
5+
AutoMode as AutoModeIcon,
6+
Home as HomeIcon,
7+
SettingsOutlined as SettingsOutlinedIcon,
8+
SwitchAccessShortcut as SwitchAccessShortcutIcon,
9+
} from '@mui/icons-material';
610
import { Box, Typography, useTheme } from '@mui/material';
711
import { useState } from 'react';
812

@@ -28,7 +32,6 @@ interface Props {
2832
*/
2933
export const BaseLayout: React.FC<Props> = ({ children }) => {
3034
const Theme = useTheme();
31-
const ThemeContext = useThemeContext();
3235

3336
const [isShortcutsMenuOpen, setIsShortcutsMenuOpen] = useState(false);
3437
const handleShortcutsMenuOpen = () => {
@@ -38,6 +41,14 @@ export const BaseLayout: React.FC<Props> = ({ children }) => {
3841
setIsShortcutsMenuOpen(false);
3942
};
4043

44+
const [isSettingsDialogOpen, setIsSettingsDialogOpen] = useState(false);
45+
const handleSettingsDialogOpen = () => {
46+
setIsSettingsDialogOpen(true);
47+
};
48+
const handleSettingsDialogClose = () => {
49+
setIsSettingsDialogOpen(false);
50+
};
51+
4152
return (
4253
<Box
4354
sx={{
@@ -110,11 +121,11 @@ export const BaseLayout: React.FC<Props> = ({ children }) => {
110121
}}
111122
>
112123
<IconTitleButton
113-
icon={<Home sx={{ width: '1.5rem', height: '1.5rem', color: Colors.backgroundPrimaryLight }} />}
124+
icon={<HomeIcon sx={{ width: '1.5rem', height: '1.5rem', color: Colors.backgroundPrimaryLight }} />}
114125
title={'Home'}
115126
/>
116127
<IconTitleButton
117-
icon={<AutoMode sx={{ width: '1.5rem', height: '1.5rem', color: Colors.backgroundPrimaryLight }} />}
128+
icon={<AutoModeIcon sx={{ width: '1.5rem', height: '1.5rem', color: Colors.backgroundPrimaryLight }} />}
118129
title={'Macros'}
119130
/>
120131
</Box>
@@ -131,34 +142,27 @@ export const BaseLayout: React.FC<Props> = ({ children }) => {
131142
>
132143
<IconTitleButton
133144
icon={
134-
<SettingsOutlined sx={{ width: '1.5rem', height: '1.5rem', color: Colors.backgroundPrimaryLight }} />
145+
<SettingsOutlinedIcon
146+
sx={{ width: '1.5rem', height: '1.5rem', color: Colors.backgroundPrimaryLight }}
147+
/>
135148
}
149+
onClick={handleSettingsDialogOpen}
136150
/>
137151
<IconTitleButton
138152
icon={
139-
<SwitchAccessShortcut
153+
<SwitchAccessShortcutIcon
140154
sx={{ width: '1.5rem', height: '1.5rem', color: Colors.backgroundPrimaryLight }}
141155
/>
142156
}
143157
onClick={handleShortcutsMenuOpen}
144158
/>
145-
{ThemeContext.mode === 'light' ? (
146-
<IconTitleButton
147-
icon={<DarkMode sx={{ width: '1.5rem', height: '1.5rem', color: Colors.backgroundPrimaryLight }} />}
148-
onClick={() => ThemeContext.update()}
149-
/>
150-
) : (
151-
<IconTitleButton
152-
icon={<LightMode sx={{ width: '1.5rem', height: '1.5rem', color: Colors.backgroundPrimaryLight }} />}
153-
onClick={() => ThemeContext.update()}
154-
/>
155-
)}
156159
</Box>
157160
</Box>
158161
<Box sx={{ width: '95.75%', height: '99.5%', borderRadius: '0.625rem', bgcolor: Theme.palette.secondary.main }}>
159-
<ShortcutsDialog open={isShortcutsMenuOpen} handleClose={handleShortcutsMenuClose} />
160162
{children}
161163
</Box>
164+
<SettingsDialog open={isSettingsDialogOpen} onClose={handleSettingsDialogClose} />
165+
<ShortcutsDialog open={isShortcutsMenuOpen} handleClose={handleShortcutsMenuClose} />
162166
</Box>
163167
</Box>
164168
);

app/front-end/src/features/editor/components/consoleView/consoleView.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ConsoleGroup, ConsoleGroupItem } from '@/features/editor/components/consoleView';
22
import { ConsoleFeedback } from '@/features/editor/types';
33
import { socket } from '@/lib';
4+
import { Events } from '@/types';
45
import { useEffect, useRef, useState } from 'react';
56

67
/**
@@ -29,10 +30,10 @@ export const ConsoleView: React.FC = () => {
2930
setConsoleFeedback((prev) => [...prev, data]);
3031
};
3132

32-
socket.on('console_feedback', handleConsoleFeedback);
33+
socket.on(Events.CONSOLE_FEEDBACK_EVENT, handleConsoleFeedback);
3334

3435
return () => {
35-
socket.off('console_feedback');
36+
socket.off(Events.CONSOLE_FEEDBACK_EVENT);
3637
};
3738
}, []);
3839

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { styled } from '@mui/material/styles';
2+
import { GridColumnMenuContainer, GridColumnMenuHideItem, GridColumnMenuProps } from '@mui/x-data-grid';
3+
4+
const StyledGridColumnMenuContainer = styled(GridColumnMenuContainer)(({ theme }) => ({
5+
backgroundColor: theme.palette.secondary.main,
6+
}));
7+
8+
interface GridColumnMenuContainerProps extends GridColumnMenuProps {}
9+
10+
/**
11+
* `EditorColumnMenu` component customizes the column menu in a DataGrid with a styled container.
12+
*
13+
* @description This component extends the default column menu functionality of the DataGrid by applying custom styles
14+
* to the menu container. The `StyledGridColumnMenuContainer` applies a background color from the theme's secondary palette
15+
* to the menu. The menu includes a `GridColumnMenuHideItem` for hiding the column, which invokes the `hideMenu` function
16+
* when clicked.
17+
*
18+
* @component
19+
*
20+
* @param {GridColumnMenuContainerProps} props - The props for the component.
21+
* @param {() => void} props.hideMenu - A callback function to hide the column menu.
22+
* @param {object} props.colDef - Column definition object passed to the menu.
23+
* @param {GridColumnMenuProps} [other] - Other props that are passed to the `GridColumnMenuContainer`.
24+
*
25+
* @example
26+
* // Example usage of the EditorColumnMenu component
27+
* <EditorColumnMenu
28+
* hideMenu={() => console.log('Hide menu')}
29+
* colDef={columnDefinition}
30+
* />
31+
*
32+
* @returns {JSX.Element} A styled `GridColumnMenuContainer` containing a `GridColumnMenuHideItem`.
33+
*/
34+
export const EditorColumnMenu: React.FC<GridColumnMenuContainerProps> = ({ hideMenu, colDef, ...other }) => {
35+
return (
36+
<StyledGridColumnMenuContainer hideMenu={hideMenu} colDef={colDef} {...other}>
37+
<GridColumnMenuHideItem onClick={hideMenu} colDef={colDef!} />
38+
</StyledGridColumnMenuContainer>
39+
);
40+
};

0 commit comments

Comments
 (0)