diff --git a/src/app/Layout/Layout.tsx b/src/app/Layout/Layout.tsx index b9d9ece4792ce221712f7667db33e77396e0950b..2ce8d9135fd1163b32ea30a1967d8ade13c4e732 100644 --- a/src/app/Layout/Layout.tsx +++ b/src/app/Layout/Layout.tsx @@ -17,7 +17,7 @@ const Layout = (): JSX.Element => { <NavigationBar /> {/*Create a Stack container to hold the main content and footer*/} <Stack direction="column" margin={0} justifyContent="flex-start" spacing={1} sx={{ mt: 8, p: 1, width: '100%' }}> - <DemoBar /> + {/*<DemoBar />*/} {/*Use a Switch to render the appropriate route component*/} <Switch> {routes.map(({ path, Component }, key) => ( diff --git a/src/const.ts b/src/const.ts index c6f44c36814dfd089f801958057773a613a40753..9bdd260595177e25b2b7a8acc96145ac05766692 100644 --- a/src/const.ts +++ b/src/const.ts @@ -2,7 +2,7 @@ export const DEMO_MODE = true; export const EXPERIMENTAL_MODE = true; export const DEV_MODE = process.env.NODE_ENV === 'development'; export const BASE_URL = DEV_MODE ? "http://localhost:3000" : "https://iot.wzl-mq.rwth-aachen.de/soil"; -export const DATA_BACKEND = DEV_MODE ? "http://localhost:8002" : "https://iot.wzl-mq.rwth-aachen.de/soil-data" +export const DATA_BACKEND = DEV_MODE ? "http://localhost:8402" : "https://iot.wzl-mq.rwth-aachen.de/soil-data" // export const SOIL_BACKEND = DEV_MODE ? "http://localhost:8001" : "https://iot.wzl-mq.rwth-aachen.de/soil-backend" -export const SOIL_BACKEND = DEV_MODE ? "http://localhost:8001" : "http://localhost:8412" +export const SOIL_BACKEND = DEV_MODE ? "http://localhost:8412" : "https://iot.wzl-mq.rwth-aachen.de/soil-backend" // export const SOIL_BACKEND = DEV_MODE ? "https://iot.wzl-mq.rwth-aachen.de/soil-backend" : "https://iot.wzl-mq.rwth-aachen.de/soil-backend" \ No newline at end of file diff --git a/src/features/demoProjects/DemoProjects.tsx b/src/features/demoProjects/DemoProjects.tsx index 8fcea6c3882849d2720678948bab51e3b6917ed1..aedbe0bf43add073a9644c523e1959bfa80fd2b5 100644 --- a/src/features/demoProjects/DemoProjects.tsx +++ b/src/features/demoProjects/DemoProjects.tsx @@ -5,6 +5,7 @@ import CloudDownloadIcon from '@mui/icons-material/CloudDownload'; import { useAppDispatch } from '../../store/hooks'; import { addTextModel, importPrivateProject, Project, selectPrivateProjects } from '../soil-editor/soileditorSlice'; import { Tooltip, Divider, Avatar, ListItemAvatar, ListItem, ListItemText, List} from '@mui/material'; + export function DemoProjects() { const dispatch = useAppDispatch() diff --git a/src/features/privateProjects/PrivateProjects.tsx b/src/features/privateProjects/PrivateProjects.tsx index c44ad6fb2d39741979c767dd979450f23ca59ef9..f0194c439157180dc86917034e7055a647043690 100644 --- a/src/features/privateProjects/PrivateProjects.tsx +++ b/src/features/privateProjects/PrivateProjects.tsx @@ -7,6 +7,7 @@ import { deleteProjectById, importPrivateProject, Project, selectPrivateProjects import { Tooltip, Divider, Avatar, ListItemAvatar, ListItem, ListItemText, List} from '@mui/material'; import DeleteIcon from '@mui/icons-material/Delete'; import { DeleteWarningeDialog } from './deleteWarningDialog'; + export function PrivateProjects() { const privateProjects = useAppSelector(selectPrivateProjects); const dispatch = useAppDispatch(); diff --git a/src/features/soil-editor/SoilTextEditor/SoilHighlight.ts b/src/features/soil-editor/SoilTextEditor/SoilHighlight.ts index 0344ff53e21b4f8c4704c6ac35d83ba726932bad..fd82779327e48ffe50a4c6a5d4b7ebc5200faf9f 100644 --- a/src/features/soil-editor/SoilTextEditor/SoilHighlight.ts +++ b/src/features/soil-editor/SoilTextEditor/SoilHighlight.ts @@ -36,6 +36,9 @@ export const soilHighlight = { } }, + "list": { + pattern: /\bList\b/ + }, "event": { pattern: /\b(critical|debug|error|if|info|warning)\b/ }, diff --git a/src/features/soil-editor/SoilTextEditor/styles.css b/src/features/soil-editor/SoilTextEditor/styles.css index de66e2267b519db895589f7c606e5494f6055adb..a7a9b42ed320d79899688800aebf0c4287b9e553 100644 --- a/src/features/soil-editor/SoilTextEditor/styles.css +++ b/src/features/soil-editor/SoilTextEditor/styles.css @@ -128,14 +128,17 @@ body { color: #A8859E } -.light-theme .token.event { +.light-theme .token.event, +.light-theme .token.list { color: #E30066 } -.dark-theme .token.event { +.dark-theme .token.event, +.dark-theme .token.list { color: #F19EB1 } + .light-theme .token.warning { color: #CC071E } diff --git a/src/features/soil-editor/SoilToolbar/SemanticSwitch.tsx b/src/features/soil-editor/SoilToolbar/SemanticSwitch.tsx new file mode 100644 index 0000000000000000000000000000000000000000..939d2600e40b38a610c54b02233a1c03161fd9c9 --- /dev/null +++ b/src/features/soil-editor/SoilToolbar/SemanticSwitch.tsx @@ -0,0 +1,53 @@ +import { Switch } from '@mui/material'; +import { styled } from '@mui/material/styles'; +import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh'; + + +const SemanticSwitch = styled(Switch)(({ theme }) => ({ + width: 62, + height: 34, + padding: 7, + '& .MuiSwitch-switchBase': { + margin: 1, + padding: 0, + transform: 'translateX(6px)', + '&.Mui-checked': { + color: '#fff', + transform: 'translateX(22px)', + '& .MuiSwitch-thumb:before': { + backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24"><path fill="${encodeURIComponent( + '#fff', + )}" d="M7.5 5.6 10 7 8.6 4.5 10 2 7.5 3.4 5 2l1.4 2.5L5 7zm12 9.8L17 14l1.4 2.5L17 19l2.5-1.4L22 19l-1.4-2.5L22 14zM22 2l-2.5 1.4L17 2l1.4 2.5L17 7l2.5-1.4L22 7l-1.4-2.5zm-7.63 5.29a.9959.9959 0 0 0-1.41 0L1.29 18.96c-.39.39-.39 1.02 0 1.41l2.34 2.34c.39.39 1.02.39 1.41 0L16.7 11.05c.39-.39.39-1.02 0-1.41zm-1.03 5.49-2.12-2.12 2.44-2.44 2.12 2.12z"/></svg>')`, + }, + '& + .MuiSwitch-track': { + opacity: 1, + backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : '#aab4be', + }, + }, + }, + '& .MuiSwitch-thumb': { + backgroundColor: theme.palette.mode === 'dark' ? '#003892' : '#00549f', + width: 32, + height: 32, + '&:before': { + content: "''", + position: 'absolute', + width: '100%', + height: '100%', + left: 0, + top: 0, + backgroundRepeat: 'no-repeat', + backgroundPosition: 'center', + backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24"><path fill="${encodeURIComponent( + '#fff', + )}" d="m23 1-2.5 1.4L18 1l1.4 2.5L18 6l2.5-1.4L23 6l-1.4-2.5zm-8.34 6.22 2.12 2.12-2.44 2.44.81.81 2.55-2.55c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 0 0-1.41 0L11.4 8.84l.81.81zm-.78 6.65-3.75-3.75-6.86-6.86L2 4.53l6.86 6.86-6.57 6.57c-.39.39-.39 1.02 0 1.41l2.34 2.34c.39.39 1.02.39 1.41 0l6.57-6.57L19.47 22l1.27-1.27z"/></svg>')`, + }, + }, + '& .MuiSwitch-track': { + opacity: 1, + backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : '#aab4be', + borderRadius: 20 / 2, + }, +})); + +export default SemanticSwitch \ No newline at end of file diff --git a/src/features/soil-editor/SoilToolbar/SoilToolbar.tsx b/src/features/soil-editor/SoilToolbar/SoilToolbar.tsx index eb3ebfe778444661e4a32d8345f7c9b53037d7da..86a7e19fd4e1081192db7ed94a274e51c0b542ca 100644 --- a/src/features/soil-editor/SoilToolbar/SoilToolbar.tsx +++ b/src/features/soil-editor/SoilToolbar/SoilToolbar.tsx @@ -10,13 +10,14 @@ import TextGraphSwitch from './TextGraphSwitch'; import { SOIL_BACKEND } from '../../../const'; import { useAppDispatch, useAppSelector } from '../../../store/hooks'; import { selectCurrentTab } from "../TopNavigationBar/topnavigationSlice"; -import { changeTextOfFile, selectProjects, setGraphModel, setImports, toggleModelRepresentation } from '../soileditorSlice'; +import { changeTextOfFile, selectProjects, setGraphModel, setImports, toggleModelRepresentation, switchSemantics } from '../soileditorSlice'; import DownloadProject from './DownloadProject'; import GenerateButton from './GenerateButton'; import PublishModal from './PublishModal'; import VerifyButton from './VerifyButton'; import { toggleErrorLog } from './toolbarSlice'; import SaveButton from './SaveButton'; +import SemanticSwitch from './SemanticSwitch'; const SoilToolbar = (): JSX.Element => { @@ -84,6 +85,8 @@ const SoilToolbar = (): JSX.Element => { const graphSwitch = <TextGraphSwitch checked={!soilProjects[projectId].showTextModel} onClick={() => { dispatch(toggleModelRepresentation(projectId)); loadNewText(soilProjects[projectId].showTextModel) }}/>; + const semanticSwitch = <SemanticSwitch checked={soilProjects[projectId].semanticsEnabled} onClick={() => { dispatch(switchSemantics(projectId));}}/>; + return ( <Toolbar> <Stack spacing={1} direction="row"> @@ -100,6 +103,9 @@ const SoilToolbar = (): JSX.Element => { <GenerateButton /> </Tooltip> <SaveButton projectId={projectId} /> + <Tooltip title={soilProjects[projectId].semanticsEnabled?"Semantics enabled":"Semantics disabled"}> + {semanticSwitch} + </Tooltip> </Stack> <Stack style={{ marginLeft: "auto" }} direction="row" spacing={1}> diff --git a/src/features/soil-editor/soileditorSlice.ts b/src/features/soil-editor/soileditorSlice.ts index 7c21c0bcc6ba502ff6e2b5ab51cdceb91177c4c0..4e215d4c4445f14761ae79c6dcec36fcb127f7c0 100644 --- a/src/features/soil-editor/soileditorSlice.ts +++ b/src/features/soil-editor/soileditorSlice.ts @@ -162,6 +162,7 @@ export type Project = { showTextModel: boolean; loading: boolean; timestamp: string; + semanticsEnabled: boolean; }; // Define the SoileditorState interface @@ -264,7 +265,7 @@ export const generateModelById = createAsyncThunk<GenerationReportResponse, Gene fData.append("files", tempFile); } - let response = fetch(SOIL_BACKEND + "/generate?model=" + fName + "&target=" + settings.target, { + let response = fetch(SOIL_BACKEND + "/generate?model=" + fName + "&target=" + settings.target + "&semantic="+state.projects[settings.projectId].semanticsEnabled, { method: 'POST', body: fData, redirect: 'follow', @@ -305,7 +306,7 @@ export const validateModelById = createAsyncThunk<GenerationReportResponse, stri } } - let response = fetch(SOIL_BACKEND + "/validate?model=" + fName + "&target=python", { + let response = fetch(SOIL_BACKEND + "/validate?model=" + fName + "&target=python&semantic="+state.projects[projectId].semanticsEnabled, { method: 'POST', body: fData, redirect: 'follow', @@ -459,7 +460,7 @@ export const soileditorSlice = createSlice({ // Add a new project to the state with a given text model and filename. addTextModel: (state, action: PayloadAction<string[]>) => { const newUUID = uuidv4() - state.projects[newUUID] = { name: action.payload[0], projectId: newUUID, files: {}, version: "1.0", showTextModel: true, loading: false, timestamp: new Date().toISOString() } + state.projects[newUUID] = { name: action.payload[0], projectId: newUUID, files: {}, version: "1.0", showTextModel: true, loading: false, timestamp: new Date().toISOString(), semanticsEnabled: false } const files = state.projects[newUUID].files; var counter = 1; while (counter < action.payload.length - 1) { @@ -472,6 +473,9 @@ export const soileditorSlice = createSlice({ state.projects[action.payload].loading = true; state.projects[action.payload].showTextModel = !state.projects[action.payload].showTextModel }, + switchSemantics: (state, action: PayloadAction<string>) => { + state.projects[action.payload].semanticsEnabled = !state.projects[action.payload].semanticsEnabled; + }, // Import a project into the state. importPublicProject: (state, action: PayloadAction<Project>) => { const newUUID = uuidv4() @@ -778,7 +782,7 @@ export const soileditorSlice = createSlice({ }, }); -export const { addTextModel, addFileToProject, removeFileFromProject, setGraphModel, setImports, addEnumToFile, addFunctionToFile, addVariableToFile, addComponentToFile, deleteSoilElementFromGraph, addImportToFile, removeImportFromFile, setCardsOpen, toggleSnackbar, changeTextOfFile, importPublicProject, importPrivateProject, removeProject, removePrivateProject, clearPrivateProjects, setGraphModelCard, toggleModelRepresentation, saveProject, updateImports } = soileditorSlice.actions; +export const { addTextModel, addFileToProject, removeFileFromProject, setGraphModel, setImports, addEnumToFile, addFunctionToFile, addVariableToFile, addComponentToFile, deleteSoilElementFromGraph, addImportToFile, removeImportFromFile, setCardsOpen, toggleSnackbar, changeTextOfFile, importPublicProject, importPrivateProject, removeProject, removePrivateProject, clearPrivateProjects, setGraphModelCard, toggleModelRepresentation, saveProject, updateImports, switchSemantics } = soileditorSlice.actions; export const selectProjects = (state: RootState) => state.soileditor.projects; export const selectPrivateProjects = (state: RootState) => state.soileditor.privateProjects;