diff --git a/package-lock.json b/package-lock.json index 4d8377a14743..7875554e4ba6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "@siemens/ngx-datatable": "22.4.1", "@swimlane/ngx-charts": "22.0.0", "@swimlane/ngx-graph": "10.0.0", + "@tumaet/apollon": "4.0.0-alpha.0", "@vscode/codicons": "0.0.36", "@vscode/markdown-it-katex": "1.1.1", "bootstrap": "5.3.6", @@ -145,6 +146,33 @@ "npm": ">=10.9.2" } }, + "../Apollon2/library": { + "name": "@tumaet/apollon", + "version": "4.0.0-alpha.0", + "extraneous": true, + "dependencies": { + "@mui/icons-material": "6.3.1", + "@mui/material": "6.3.1", + "@types/node": "22.13.8", + "@xyflow/react": "12.3.6", + "react": "18.3.1", + "react-dom": "18.3.1", + "uuid": "11.0.3", + "y-websocket": "2.1.0", + "zustand": "5.0.3" + }, + "devDependencies": { + "@eslint/js": "9.17.0", + "@vitejs/plugin-react": "4.3.4", + "eslint": "9.17.0", + "eslint-plugin-react": "7.37.2", + "globals": "15.13.0", + "typescript": "5.7.2", + "typescript-eslint": "8.18.1", + "vite": "6.3.3", + "vite-plugin-dts": "4.3.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -3241,6 +3269,25 @@ "node": ">=14.17.0" } }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, "node_modules/@emotion/is-prop-valid": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", @@ -3256,6 +3303,31 @@ "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", "license": "MIT" }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/serialize/node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, "node_modules/@emotion/stylis": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", @@ -3268,6 +3340,18 @@ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", "license": "MIT" }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.4", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", @@ -5401,6 +5485,267 @@ "win32" ] }, + "node_modules/@mui/core-downloads-tracker": { + "version": "6.4.11", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.11.tgz", + "integrity": "sha512-CzAQs9CTzlwbsF9ZYB4o4lLwBv1/qNE264NjuYao+ctAXsmlPtYa8RtER4UsUXSMxNN9Qi+aQdYcKl2sUpnmAw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.3.1.tgz", + "integrity": "sha512-nJmWj1PBlwS3t1PnoqcixIsftE+7xrW3Su7f0yrjPw4tVjYrgkhU0hrRp+OlURfZ3ptdSkoBkalee9Bhf1Erfw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^6.3.1", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.3.1.tgz", + "integrity": "sha512-ynG9ayhxgCsHJ/dtDcT1v78/r2GwQyP3E0hPz3GdPRl0uFJz/uUTtI5KFYwadXmbC+Uv3bfB8laZ6+Cpzh03gA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/core-downloads-tracker": "^6.3.1", + "@mui/system": "^6.3.1", + "@mui/types": "^7.2.21", + "@mui/utils": "^6.3.1", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.0.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^6.3.1", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.9.tgz", + "integrity": "sha512-LktcVmI5X17/Q5SkwjCcdOLBzt1hXuc14jYa7NPShog0GBDCDvKtcnP0V7a2s6EiVRlv7BzbWEJzH6+l/zaCxw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/utils": "^6.4.9", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "6.4.11", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.11.tgz", + "integrity": "sha512-74AUmlHXaGNbyUqdK/+NwDJOZqgRQw6BcNvhoWYLq3LGbLTkE+khaJ7soz6cIabE4CPYqO2/QAIU1Z/HEjjpcw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "6.4.11", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.11.tgz", + "integrity": "sha512-gibtsrZEwnDaT5+I/KloOj/yHluX5G8heknuxBpQOdEQ3Gc0avjSImn5hSeKp8D4thiwZiApuggIjZw1dQguUA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/private-theming": "^6.4.9", + "@mui/styled-engine": "^6.4.11", + "@mui/types": "~7.2.24", + "@mui/utils": "^6.4.9", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/system/node_modules/@mui/types": { + "version": "7.2.24", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", + "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.2.tgz", + "integrity": "sha512-edRc5JcLPsrlNFYyTPxds+d5oUovuUxnnDtpJUbP6WMeV4+6eaX/mqai1ZIWT62lCOe0nlrON0s9HDiv5en5bA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.9.tgz", + "integrity": "sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/types": "~7.2.24", + "@types/prop-types": "^15.7.14", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/@mui/types": { + "version": "7.2.24", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", + "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@napi-rs/canvas": { "version": "0.1.70", "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.70.tgz", @@ -6625,7 +6970,6 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -7440,6 +7784,75 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/@tumaet/apollon": { + "version": "4.0.0-alpha.0", + "resolved": "https://registry.npmjs.org/@tumaet/apollon/-/apollon-4.0.0-alpha.0.tgz", + "integrity": "sha512-aHc+oRq7uyFNgdx9xBn7BixrzPAcS0uphjOUu/pfHoy37mTOYjKFFmEPb+BMLBHuBo+O6HxsT6wGt8LhRK3l6A==", + "dependencies": { + "@mui/icons-material": "6.3.1", + "@mui/material": "6.3.1", + "@types/node": "22.13.8", + "@xyflow/react": "12.3.6", + "react": "18.3.1", + "react-dom": "18.3.1", + "uuid": "11.0.3", + "y-websocket": "2.1.0", + "zustand": "5.0.3" + } + }, + "node_modules/@tumaet/apollon/node_modules/@types/node": { + "version": "22.13.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.8.tgz", + "integrity": "sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@tumaet/apollon/node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@tumaet/apollon/node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/@tumaet/apollon/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" + }, + "node_modules/@tumaet/apollon/node_modules/uuid": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz", + "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/@types/aria-query": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", @@ -7542,6 +7955,30 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, "node_modules/@types/d3-path": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", @@ -7549,6 +7986,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" + }, "node_modules/@types/d3-shape": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", @@ -7559,6 +8002,25 @@ "@types/d3-path": "*" } }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/dompurify": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", @@ -7886,6 +8348,15 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, "node_modules/@types/retry": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", @@ -8556,6 +9027,64 @@ "license": "Apache-2.0", "peer": true }, + "node_modules/@xyflow/react": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.3.6.tgz", + "integrity": "sha512-9GS+cz8hDZahpvTrVCmySAEgKUL8oN4b2q1DluHrKtkqhAMWfH2s7kblhbM4Y4Y4SUnH2lt4drXKZ/4/Lot/2Q==", + "license": "MIT", + "dependencies": { + "@xyflow/system": "0.0.47", + "classcat": "^5.0.3", + "zustand": "^4.4.0" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@xyflow/react/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@xyflow/system": { + "version": "0.0.47", + "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.47.tgz", + "integrity": "sha512-aUXJPIvsCFxGX70ccRG8LPsR+A8ExYXfh/noYNpqn8udKerrLdSHxMG2VsvUrQ1PGex10fOpbJwFU4A+I/Xv8w==", + "license": "MIT", + "dependencies": { + "@types/d3-drag": "^3.0.7", + "@types/d3-selection": "^3.0.10", + "@types/d3-transition": "^3.0.8", + "@types/d3-zoom": "^3.0.8", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" + } + }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -8573,6 +9102,31 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/abstract-leveldown/node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "license": "MIT", + "optional": true + }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -9192,7 +9746,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -9444,7 +9998,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -9835,6 +10389,12 @@ "dev": true, "license": "MIT" }, + "node_modules/classcat": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz", + "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==", + "license": "MIT" + }, "node_modules/cli-cursor": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", @@ -9991,6 +10551,15 @@ "node": ">=0.10.0" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -10790,6 +11359,22 @@ "d3-selection": "2 - 3" } }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/dagre": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz", @@ -10925,10 +11510,25 @@ "dev": true, "license": "MIT", "dependencies": { - "clone": "^1.0.2" + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deferred-leveldown": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "license": "MIT", + "optional": true, + "dependencies": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=6" } }, "node_modules/define-data-property": { @@ -11085,6 +11685,16 @@ "license": "MIT", "peer": true }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -11273,6 +11883,23 @@ "iconv-lite": "^0.6.2" } }, + "node_modules/encoding-down": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", + "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "license": "MIT", + "optional": true, + "dependencies": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/encoding/node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -11348,10 +11975,8 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "prr": "~1.0.1" }, @@ -13272,7 +13897,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -13806,6 +14431,16 @@ "node": ">=0.10.0" } }, + "node_modules/isomorphic.js": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.2.5.tgz", + "integrity": "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==", + "license": "MIT", + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -15477,6 +16112,183 @@ "node": ">=0.10.0" } }, + "node_modules/level": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/level/-/level-6.0.1.tgz", + "integrity": "sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==", + "license": "MIT", + "optional": true, + "dependencies": { + "level-js": "^5.0.0", + "level-packager": "^5.1.0", + "leveldown": "^5.4.0" + }, + "engines": { + "node": ">=8.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" + } + }, + "node_modules/level-codec": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "deprecated": "Superseded by level-transcoder (https://github.com/Level/community#faq)", + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-concat-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "license": "MIT", + "optional": true, + "dependencies": { + "errno": "~0.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-iterator-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-iterator-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/level-js": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/level-js/-/level-js-5.0.2.tgz", + "integrity": "sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==", + "deprecated": "Superseded by browser-level (https://github.com/Level/community#faq)", + "license": "MIT", + "optional": true, + "dependencies": { + "abstract-leveldown": "~6.2.3", + "buffer": "^5.5.0", + "inherits": "^2.0.3", + "ltgt": "^2.1.2" + } + }, + "node_modules/level-packager": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", + "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "license": "MIT", + "optional": true, + "dependencies": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-supports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "license": "MIT", + "optional": true, + "dependencies": { + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/leveldown": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.6.0.tgz", + "integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==", + "deprecated": "Superseded by classic-level (https://github.com/Level/community#faq)", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "abstract-leveldown": "~6.2.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "~4.1.0" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/leveldown/node_modules/node-gyp-build": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", + "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/levelup": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "license": "MIT", + "optional": true, + "dependencies": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -15501,6 +16313,27 @@ "node": ">= 0.8.0" } }, + "node_modules/lib0": { + "version": "0.2.108", + "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.108.tgz", + "integrity": "sha512-+3eK/B0SqYoZiQu9fNk4VEc6EX8cb0Li96tPGKgugzoGj/OdRdREtuTLvUW+mtinoB2mFiJjSqOJBIaMkAGhxQ==", + "license": "MIT", + "dependencies": { + "isomorphic.js": "^0.2.4" + }, + "bin": { + "0ecdsa-generate-keypair": "bin/0ecdsa-generate-keypair.js", + "0gentesthtml": "bin/gentesthtml.js", + "0serve": "bin/0serve.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/license-webpack-plugin": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", @@ -15860,9 +16693,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -16052,6 +16883,13 @@ "yallist": "^3.0.2" } }, + "node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", + "license": "MIT", + "optional": true + }, "node_modules/lz-string": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", @@ -16700,6 +17538,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "license": "MIT", + "optional": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -18352,10 +19197,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true, "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/punycode": { "version": "2.3.1", @@ -18530,8 +19373,7 @@ "version": "19.1.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz", "integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/react-redux": { "version": "8.1.3", @@ -18604,6 +19446,22 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/reactcss": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", @@ -20350,6 +21208,12 @@ "node": ">=4" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -22767,7 +23631,7 @@ "version": "8.18.2", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -22821,6 +23685,84 @@ "dev": true, "license": "MIT" }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y-leveldb": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/y-leveldb/-/y-leveldb-0.1.2.tgz", + "integrity": "sha512-6ulEn5AXfXJYi89rXPEg2mMHAyyw8+ZfeMMdOtBbV8FJpQ1NOrcgi6DTAcXof0dap84NjHPT2+9d0rb6cFsjEg==", + "license": "MIT", + "optional": true, + "dependencies": { + "level": "^6.0.1", + "lib0": "^0.2.31" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + }, + "peerDependencies": { + "yjs": "^13.0.0" + } + }, + "node_modules/y-protocols": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/y-protocols/-/y-protocols-1.0.6.tgz", + "integrity": "sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q==", + "license": "MIT", + "dependencies": { + "lib0": "^0.2.85" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + }, + "peerDependencies": { + "yjs": "^13.0.0" + } + }, + "node_modules/y-websocket": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/y-websocket/-/y-websocket-2.1.0.tgz", + "integrity": "sha512-WHYDRqomaGkkaujtowCDwL8KYk+t1zQCGIgKyvxvchhjTQlMgWXRHJK+FDEcWmHA7I7o/4fy0eniOrtmz0e4mA==", + "license": "MIT", + "dependencies": { + "lib0": "^0.2.52", + "lodash.debounce": "^4.0.8", + "y-protocols": "^1.0.5" + }, + "bin": { + "y-websocket": "bin/server.cjs", + "y-websocket-server": "bin/server.cjs" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + }, + "optionalDependencies": { + "ws": "^6.2.1", + "y-leveldb": "^0.1.0" + }, + "peerDependencies": { + "yjs": "^13.5.6" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -22905,6 +23847,24 @@ "node": ">=8" } }, + "node_modules/yjs": { + "version": "13.6.27", + "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.27.tgz", + "integrity": "sha512-OIDwaflOaq4wC6YlPBy2L6ceKeKuF7DeTxx+jPzv1FHn9tCZ0ZwSRnUBxD05E3yed46fv/FWJbvR+Ud7x0L7zw==", + "license": "MIT", + "peer": true, + "dependencies": { + "lib0": "^0.2.99" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -22946,6 +23906,35 @@ "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", "license": "MIT" + }, + "node_modules/zustand": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.3.tgz", + "integrity": "sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } } } } diff --git a/package.json b/package.json index eab8173536fc..96a6e8222756 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@siemens/ngx-datatable": "22.4.1", "@swimlane/ngx-charts": "22.0.0", "@swimlane/ngx-graph": "10.0.0", + "@tumaet/apollon": "4.0.0-alpha.0", "@vscode/codicons": "0.0.36", "@vscode/markdown-it-katex": "1.1.1", "bootstrap": "5.3.6", diff --git a/src/main/java/de/tum/cit/aet/artemis/modeling/domain/ModelingSubmission.java b/src/main/java/de/tum/cit/aet/artemis/modeling/domain/ModelingSubmission.java index cbc22a008e38..24330f73cdfb 100644 --- a/src/main/java/de/tum/cit/aet/artemis/modeling/domain/ModelingSubmission.java +++ b/src/main/java/de/tum/cit/aet/artemis/modeling/domain/ModelingSubmission.java @@ -88,7 +88,7 @@ public boolean isEmpty(ObjectMapper jacksonObjectMapper) { return false; } // TODO: further improve this!! - return model == null || model.isBlank() || jacksonObjectMapper.readTree(getModel()).get("elements").isEmpty(); + return model == null || model.isBlank() || jacksonObjectMapper.readTree(getModel()).get("nodes").isEmpty(); } catch (JsonProcessingException ex) { return false; diff --git a/src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.html b/src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.html index 47c600031279..858166b837c6 100644 --- a/src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.html +++ b/src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.html @@ -80,6 +80,7 @@

@if (isAssessor && (!hasComplaint || exercise?.isAtLeastInstructor)) { } + @if (!isProgrammingExercise && result && correctionRound > 0) { } diff --git a/src/main/webapp/app/assessment/manage/assessment-instructions/assessment-instructions/assessment-instructions.component.ts b/src/main/webapp/app/assessment/manage/assessment-instructions/assessment-instructions/assessment-instructions.component.ts index 12b0a883ab47..c9621643083f 100644 --- a/src/main/webapp/app/assessment/manage/assessment-instructions/assessment-instructions/assessment-instructions.component.ts +++ b/src/main/webapp/app/assessment/manage/assessment-instructions/assessment-instructions/assessment-instructions.component.ts @@ -1,6 +1,6 @@ import { Component, Input, inject } from '@angular/core'; import { SafeHtml } from '@angular/platform-browser'; -import { UMLDiagramType, UMLModel } from '@ls1intum/apollon'; +import { UMLDiagramType, UMLModel } from '@tumaet/apollon'; import { ArtemisMarkdownService } from 'app/shared/service/markdown.service'; import { Exercise, ExerciseType } from 'app/exercise/shared/entities/exercise/exercise.model'; import { TextExercise } from 'app/text/shared/entities/text-exercise.model'; diff --git a/src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/exercise-assessment-dashboard.component.ts b/src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/exercise-assessment-dashboard.component.ts index bbdeab922592..3e25c8545258 100644 --- a/src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/exercise-assessment-dashboard.component.ts +++ b/src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/exercise-assessment-dashboard.component.ts @@ -12,7 +12,7 @@ import { ExampleSubmission } from 'app/assessment/shared/entities/example-submis import { ArtemisMarkdownService } from 'app/shared/service/markdown.service'; import { TextExercise } from 'app/text/shared/entities/text-exercise.model'; import { ModelingExercise } from 'app/modeling/shared/entities/modeling-exercise.model'; -import { UMLModel } from '@ls1intum/apollon'; +import { UMLModel } from '@tumaet/apollon'; import { ComplaintService } from 'app/assessment/shared/services/complaint.service'; import { Complaint, ComplaintType } from 'app/assessment/shared/entities/complaint.model'; import { diff --git a/src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.ts b/src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.ts index d7d334935c7c..fc87a1687779 100644 --- a/src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.ts +++ b/src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component, OnInit, input, output, viewChild } from '@angular/core'; -import { UMLModel } from '@ls1intum/apollon'; +import { UMLModel } from '@tumaet/apollon'; import dayjs from 'dayjs/esm'; import { ModelingSubmission } from 'app/modeling/shared/entities/modeling-submission.model'; import { ModelingExercise } from 'app/modeling/shared/entities/modeling-exercise.model'; @@ -108,8 +108,8 @@ export class ModelingExamSubmissionComponent extends ExamSubmissionComponent imp if (!this.modelingEditor() || !this.modelingEditor().getCurrentModel()) { return; } - const currentApollonModel = this.modelingEditor().getCurrentModel(); - const diagramJson = JSON.stringify(currentApollonModel); + + const diagramJson = JSON.stringify(this.modelingEditor().getCurrentModel()); if (this.studentSubmission()) { if (diagramJson) { @@ -158,7 +158,6 @@ export class ModelingExamSubmissionComponent extends ExamSubmissionComponent imp // and need to remove the content that was added before the string is saved to the db to get valid JSON let model = this.submissionVersion.content.substring(0, this.submissionVersion.content.indexOf('; Explanation:')); // if we do not wait here for apollon, the redux store might be undefined - await this.modelingEditor()!.apollonEditor!.nextRender; model = model.replace('Model: ', ''); // updates the Apollon editor model state (view) with the latest modeling submission this.umlModel = JSON.parse(model); diff --git a/src/main/webapp/app/modeling/manage/assess/modeling-assessment-editor/modeling-assessment-editor.component.html b/src/main/webapp/app/modeling/manage/assess/modeling-assessment-editor/modeling-assessment-editor.component.html index d12ac24ee1a5..2b807a0e8008 100644 --- a/src/main/webapp/app/modeling/manage/assess/modeling-assessment-editor/modeling-assessment-editor.component.html +++ b/src/main/webapp/app/modeling/manage/assess/modeling-assessment-editor/modeling-assessment-editor.component.html @@ -42,6 +42,7 @@ }
+ before assessment @if (submission) {
@if (result && result.id) { - +
+ +
} @if ((hasAutomaticFeedback || highlightMissingFeedback) && !result?.completionDate) {
diff --git a/src/main/webapp/app/modeling/manage/assess/modeling-assessment-editor/modeling-assessment-editor.component.ts b/src/main/webapp/app/modeling/manage/assess/modeling-assessment-editor/modeling-assessment-editor.component.ts index 32554f96d0c7..4c42f73f53b3 100644 --- a/src/main/webapp/app/modeling/manage/assess/modeling-assessment-editor/modeling-assessment-editor.component.ts +++ b/src/main/webapp/app/modeling/manage/assess/modeling-assessment-editor/modeling-assessment-editor.component.ts @@ -3,7 +3,7 @@ import { Location } from '@angular/common'; import { UnreferencedFeedbackComponent } from 'app/exercise/unreferenced-feedback/unreferenced-feedback.component'; import { firstValueFrom } from 'rxjs'; import { AlertService } from 'app/shared/service/alert.service'; -import { UMLDiagramType, UMLModel } from '@ls1intum/apollon'; +import { UMLDiagramType, UMLModel } from '@tumaet/apollon'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { AccountService } from 'app/core/auth/account.service'; import { HttpErrorResponse } from '@angular/common/http'; @@ -191,6 +191,7 @@ export class ModelingAssessmentEditorComponent implements OnInit { private loadSubmission(submissionId: number): void { this.modelingSubmissionService.getSubmission(submissionId, this.correctionRound, this.resultId).subscribe({ next: (submission: ModelingSubmission) => { + // console.log('DEBUG received submission,', submission); this.handleReceivedSubmission(submission); this.validateFeedback(); }, @@ -427,7 +428,9 @@ export class ModelingAssessmentEditorComponent implements OnInit { } onSubmitAssessment() { - if ((this.model && this.referencedFeedback.length < Object.keys(this.model.elements).length) || !this.assessmentsAreValid) { + const totalNumberOfElements = (this.model?.nodes.length ?? 0) + (this.model?.edges.length ?? 0); + // console.log('DEBUG onSubmit assessment is triggered totalNumberOfElements:', totalNumberOfElements); + if ((this.model && this.referencedFeedback.length < totalNumberOfElements) || !this.assessmentsAreValid) { const confirmationMessage = this.translateService.instant('artemisApp.modelingAssessmentEditor.messages.confirmSubmission'); // if the assessment is before the assessment due date, don't show the confirm submission button @@ -454,6 +457,7 @@ export class ModelingAssessmentEditorComponent implements OnInit { return; } + // console.log('DEBUG before modelingAssessmentService.saveAssessment is called', this.feedback); this.modelingAssessmentService.saveAssessment(this.result!.id!, this.feedback, this.submission!.id!, this.result!.assessmentNote?.note, true).subscribe({ next: (result: Result) => { result.participation!.results = [result]; @@ -530,6 +534,7 @@ export class ModelingAssessmentEditorComponent implements OnInit { * @param feedback The feedback present in the editor. */ onFeedbackChanged(feedback: Feedback[]) { + // console.log('DEBUG on feedbackChanged,', feedback); this.updateApollonEditorWithFeedback(feedback); } @@ -590,7 +595,12 @@ export class ModelingAssessmentEditorComponent implements OnInit { : new Map(); const referenceIds = this.referencedFeedback.map((feedback) => feedback.referenceId); - for (const element of Object.values(this.model.elements)) { + for (const element of Object.values(this.model.nodes)) { + if (!referenceIds.includes(element.id)) { + this.highlightedElements.set(element.id, FeedbackHighlightColor.RED); + } + } + for (const element of Object.values(this.model.edges)) { if (!referenceIds.includes(element.id)) { this.highlightedElements.set(element.id, FeedbackHighlightColor.RED); } diff --git a/src/main/webapp/app/modeling/manage/assess/modeling-assessment.component.scss b/src/main/webapp/app/modeling/manage/assess/modeling-assessment.component.scss index 48a4b6396d1a..166d5c8205e7 100644 --- a/src/main/webapp/app/modeling/manage/assess/modeling-assessment.component.scss +++ b/src/main/webapp/app/modeling/manage/assess/modeling-assessment.component.scss @@ -29,6 +29,8 @@ $draggable-width: 15px; } .apollon-container { + display: flex; + flex-grow: 1; height: 100%; width: 100%; } diff --git a/src/main/webapp/app/modeling/manage/assess/modeling-assessment.component.ts b/src/main/webapp/app/modeling/manage/assess/modeling-assessment.component.ts index 3e9668cae863..c010b90a6cb4 100644 --- a/src/main/webapp/app/modeling/manage/assess/modeling-assessment.component.ts +++ b/src/main/webapp/app/modeling/manage/assess/modeling-assessment.component.ts @@ -1,5 +1,5 @@ import { AfterViewInit, Component, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges, inject } from '@angular/core'; -import { ApollonEditor, ApollonMode, Assessment, Selection, UMLDiagramType, UMLElementType, UMLModel, UMLRelationshipType, addOrUpdateAssessment } from '@ls1intum/apollon'; +import { ApollonEditor, ApollonMode, Assessment, Selection, UMLDiagramType, UMLModel } from '@tumaet/apollon'; import { Feedback, FeedbackType } from 'app/assessment/shared/entities/feedback.model'; import { ModelElementCount } from 'app/modeling/shared/entities/modeling-submission.model'; import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe'; @@ -78,12 +78,14 @@ export class ModelingAssessmentComponent extends ModelingComponent implements Af } ngOnDestroy() { + // console.log('DEUBUG Modelin-assessment component ngOnDestroy'); if (this.apollonEditor) { this.apollonEditor.destroy(); } } async ngOnChanges(changes: SimpleChanges): Promise { + // console.log('DEBUG ngOnChanges, ', changes); if (changes.umlModel && changes.umlModel.currentValue && this.apollonEditor) { this.apollonEditor!.model = changes.umlModel.currentValue; this.handleFeedback(); @@ -99,7 +101,7 @@ export class ModelingAssessmentComponent extends ModelingComponent implements Af } if ((changes.highlightedElements || changes.highlightDifferences) && this.apollonEditor) { - await this.updateApollonAssessments(this.referencedFeedbacks); + this.updateApollonAssessments(this.referencedFeedbacks); await this.applyStateConfiguration(); } } @@ -110,7 +112,8 @@ export class ModelingAssessmentComponent extends ModelingComponent implements Af */ private initializeApollonEditor() { if (this.apollonEditor) { - this.apollonEditor.destroy(); + // console.log('DEBUG modelling assessment component initializeApollonEditor disposing Apollon Editor'); + // this.apollonEditor.destroy(); } this.handleFeedback(); @@ -122,17 +125,25 @@ export class ModelingAssessmentComponent extends ModelingComponent implements Af type: this.diagramType || UMLDiagramType.ClassDiagram, enablePopups: this.enablePopups, }); - this.apollonEditor!.subscribeToSelectionChange((selection: Selection) => { - if (this.readOnly) { - this.selectionChanged.emit(selection); + + this.apollonEditor.subscribeToModelChange((state) => { + if (!this.readOnly) { + const assessmentsArray = Object.values(state.assessments); + this.referencedFeedbacks = this.generateFeedbackFromAssessment(assessmentsArray); + this.feedbackChanged.emit(this.referencedFeedbacks); } }); - if (!this.readOnly) { - this.apollonEditor!.subscribeToAssessmentChange((assessments: Assessment[]) => { - this.referencedFeedbacks = this.generateFeedbackFromAssessment(assessments); - this.feedbackChanged.emit(this.referencedFeedbacks); - }); - } + // this.apollonEditor!.subscribeToSelectionChange((selection: Selection) => { + // if (this.readOnly) { + // this.selectionChanged.emit(selection); + // } + // }); + // if (!this.readOnly) { + // this.apollonEditor!.subscribeToAssessmentChange((assessments: Assessment[]) => { + // this.referencedFeedbacks = this.generateFeedbackFromAssessment(assessments); + // this.feedbackChanged.emit(this.referencedFeedbacks); + // }); + // } } private async applyStateConfiguration() { @@ -156,14 +167,15 @@ export class ModelingAssessmentComponent extends ModelingComponent implements Af } feedback.credits = assessment.score; feedback.text = assessment.feedback; - if (assessment.dropInfo && assessment.dropInfo.instruction?.id) { - feedback.gradingInstruction = assessment.dropInfo.instruction; - } - if (feedback.gradingInstruction && assessment.dropInfo == undefined) { - feedback.gradingInstruction = undefined; - } + // if (assessment.dropInfo && assessment.dropInfo.instruction?.id) { + // feedback.gradingInstruction = assessment.dropInfo.instruction; + // } + // if (feedback.gradingInstruction && assessment.dropInfo == undefined) { + // feedback.gradingInstruction = undefined; + // } } else { - feedback = Feedback.forModeling(assessment.score, assessment.feedback, assessment.modelElementId, assessment.elementType, assessment.dropInfo); + // feedback = Feedback.forModeling(assessment.score, assessment.feedback, assessment.modelElementId, assessment.elementType, assessment.dropInfo); + feedback = Feedback.forModeling(assessment.score, assessment.feedback, assessment.modelElementId, assessment.elementType, undefined); } newElementFeedback.set(assessment.modelElementId, feedback); } @@ -212,15 +224,15 @@ export class ModelingAssessmentComponent extends ModelingComponent implements Af } if (this.apollonEditor != undefined) { - await this.apollonEditor.nextRender; - const model: UMLModel = this.apollonEditor!.model; - for (const element of Object.values(model!.elements)) { - element.highlight = newElements.get(element.id); - } - for (const relationship of Object.values(model!.relationships)) { - relationship.highlight = newElements.get(relationship.id); - } - this.apollonEditor!.model = model!; + // console.log('DEBUG updateHighlightedElements', JSON.stringify(newElements)); + // const model: UMLModel = this.apollonEditor!.model; + // for (const element of Object.values(model!.nodes)) { + // element.highlight = newElements.get(element.id); + // } + // for (const relationship of Object.values(model!.relationships)) { + // relationship.highlight = newElements.get(relationship.id); + // } + // this.apollonEditor!.model = model!; } } @@ -239,13 +251,12 @@ export class ModelingAssessmentComponent extends ModelingComponent implements Af newElementCounts.forEach((elementCount) => elementCountMap.set(elementCount.elementId, elementCount.numberOfOtherElements)); if (this.apollonEditor != undefined) { - await this.apollonEditor.nextRender; const model: UMLModel = this.apollonEditor.model; - for (const element of Object.values(model.elements)) { - element.assessmentNote = this.calculateNote(elementCountMap.get(element.id)); + for (const node of Object.values(model.nodes)) { + node.data.assessmentNote = this.calculateNote(elementCountMap.get(node.id)); } - for (const relationship of Object.values(model.relationships)) { - relationship.assessmentNote = this.calculateNote(elementCountMap.get(relationship.id)); + for (const edge of Object.values(model.edges)) { + edge.data.assessmentNote = this.calculateNote(elementCountMap.get(edge.id)); } this.apollonEditor.model = model; } @@ -255,27 +266,31 @@ export class ModelingAssessmentComponent extends ModelingComponent implements Af * Converts a given feedback list to Apollon assessments and updates the model of Apollon with the new assessments. * @param feedbacks the feedback list to convert and pass on to Apollon */ - private async updateApollonAssessments(feedbacks: Feedback[]) { + private updateApollonAssessments(feedbacks: Feedback[]) { if (!feedbacks || !this.umlModel) { return; } + // console.log('DEBUG updateApollonAssessments feedbacks:', JSON.stringify(feedbacks)); + feedbacks.forEach((feedback) => { - addOrUpdateAssessment(this.umlModel, { + const newAssessment: Assessment = { modelElementId: feedback.referenceId!, - elementType: feedback.referenceType! as UMLElementType | UMLRelationshipType, + elementType: feedback.referenceType!, score: feedback.credits!, feedback: feedback.text || undefined, label: this.calculateLabel(feedback), labelColor: this.calculateLabelColor(feedback), correctionStatus: this.calculateCorrectionStatusForFeedback(feedback), dropInfo: this.calculateDropInfo(feedback), - }); + }; + if (this.apollonEditor) { + this.apollonEditor.addOrUpdateAssessment(newAssessment); + } }); if (this.apollonEditor) { - await this.apollonEditor.nextRender; - this.apollonEditor.model = this.umlModel; + // this.apollonEditor.model = this.umlModel; } } diff --git a/src/main/webapp/app/modeling/manage/assess/modeling-assessment.util.ts b/src/main/webapp/app/modeling/manage/assess/modeling-assessment.util.ts index 5e6008d2cd0d..833d7f1c7290 100644 --- a/src/main/webapp/app/modeling/manage/assess/modeling-assessment.util.ts +++ b/src/main/webapp/app/modeling/manage/assess/modeling-assessment.util.ts @@ -1,5 +1,5 @@ import { Result } from 'app/exercise/shared/entities/result/result.model'; -import { UMLElementType, UMLModelCompat, UMLRelationshipType, findElement, findRelationship } from '@ls1intum/apollon'; +import { UMLModel } from '@tumaet/apollon'; import { Feedback } from 'app/assessment/shared/entities/feedback.model'; export type AssessmentNamesForModelId = { [modelId: string]: { type: string; name: string } | undefined }; @@ -8,110 +8,112 @@ export type AssessmentNamesForModelId = { [modelId: string]: { type: string; nam * Creates the labels for the assessment elements for displaying them in the modeling and assessment editor. */ // TODO: define a mapping or simplify this complex monster in a another way so that we can support other diagram types as well -export function getNamesForAssessments(result: Result, model: UMLModelCompat): AssessmentNamesForModelId { - const assessmentsNames: AssessmentNamesForModelId = {}; - for (const feedback of result.feedbacks!) { - const referencedModelType = feedback.referenceType! as UMLElementType; - const referencedModelId = feedback.referenceId!; - if (referencedModelType in UMLElementType) { - const element = findElement(model, referencedModelId); - if (!element) { - // prevent errors when element could not be found, should never happen - assessmentsNames[referencedModelId] = { name: '', type: '' }; - continue; - } - - const name = element.name; - let type: string; - switch (element.type) { - case UMLElementType.Class: - type = 'class'; - break; - case UMLElementType.Package: - type = 'package'; - break; - case UMLElementType.Interface: - type = 'interface'; - break; - case UMLElementType.AbstractClass: - type = 'abstract class'; - break; - case UMLElementType.Enumeration: - type = 'enum'; - break; - case UMLElementType.ClassAttribute: - type = 'attribute'; - break; - case UMLElementType.ClassMethod: - type = 'method'; - break; - case UMLElementType.ActivityInitialNode: - type = 'initial node'; - break; - case UMLElementType.ActivityFinalNode: - type = 'final node'; - break; - case UMLElementType.ActivityObjectNode: - type = 'object'; - break; - case UMLElementType.ActivityActionNode: - type = 'action'; - break; - case UMLElementType.ActivityForkNode: - type = 'fork node'; - break; - case UMLElementType.ActivityMergeNode: - type = 'merge node'; - break; - default: - type = ''; - break; - } - assessmentsNames[referencedModelId] = { type, name }; - } else if (referencedModelType in UMLRelationshipType) { - const relationship = findRelationship(model, referencedModelId); - if (!relationship) { - // prevent errors when relationship could not be found, should never happen - assessmentsNames[referencedModelId] = { name: '', type: '' }; - continue; - } - const source = findElement(model, relationship.source.element)?.name ?? '?'; - const target = findElement(model, relationship.target.element)?.name ?? '?'; - const relationshipType = relationship.type; - let type = 'association'; - let relation: string; - switch (relationshipType) { - case UMLRelationshipType.ClassBidirectional: - relation = ' <-> '; - break; - case UMLRelationshipType.ClassUnidirectional: - relation = ' --> '; - break; - case UMLRelationshipType.ClassAggregation: - relation = ' --◇ '; - break; - case UMLRelationshipType.ClassInheritance: - relation = ' --▷ '; - break; - case UMLRelationshipType.ClassDependency: - relation = ' ╌╌> '; - break; - case UMLRelationshipType.ClassComposition: - relation = ' --◆ '; - break; - case UMLRelationshipType.ActivityControlFlow: - relation = ' --> '; - type = 'control flow'; - break; - default: - relation = ' --- '; - } - assessmentsNames[referencedModelId] = { type, name: source + relation + target }; - } else { - assessmentsNames[referencedModelId] = { type: `${referencedModelType}`, name: '' }; - } - } - return assessmentsNames; +export function getNamesForAssessments(result: Result, model: UMLModel): AssessmentNamesForModelId { + return {}; + // const assessmentsNames: AssessmentNamesForModelId = {}; + // for (const feedback of result.feedbacks!) { + // + // const referencedModelType = feedback.referenceType! as UMLElementType; + // const referencedModelId = feedback.referenceId!; + // if (referencedModelType in UMLElementType) { + // const element = findElement(model, referencedModelId); + // if (!element) { + // // prevent errors when element could not be found, should never happen + // assessmentsNames[referencedModelId] = { name: '', type: '' }; + // continue; + // } + // + // const name = element.name; + // let type: string; + // switch (element.type) { + // case UMLElementType.Class: + // type = 'class'; + // break; + // case UMLElementType.Package: + // type = 'package'; + // break; + // case UMLElementType.Interface: + // type = 'interface'; + // break; + // case UMLElementType.AbstractClass: + // type = 'abstract class'; + // break; + // case UMLElementType.Enumeration: + // type = 'enum'; + // break; + // case UMLElementType.ClassAttribute: + // type = 'attribute'; + // break; + // case UMLElementType.ClassMethod: + // type = 'method'; + // break; + // case UMLElementType.ActivityInitialNode: + // type = 'initial node'; + // break; + // case UMLElementType.ActivityFinalNode: + // type = 'final node'; + // break; + // case UMLElementType.ActivityObjectNode: + // type = 'object'; + // break; + // case UMLElementType.ActivityActionNode: + // type = 'action'; + // break; + // case UMLElementType.ActivityForkNode: + // type = 'fork node'; + // break; + // case UMLElementType.ActivityMergeNode: + // type = 'merge node'; + // break; + // default: + // type = ''; + // break; + // } + // assessmentsNames[referencedModelId] = { type, name }; + // } else if (referencedModelType in UMLRelationshipType) { + // const relationship = findRelationship(model, referencedModelId); + // if (!relationship) { + // // prevent errors when relationship could not be found, should never happen + // assessmentsNames[referencedModelId] = { name: '', type: '' }; + // continue; + // } + // const source = findElement(model, relationship.source.element)?.name ?? '?'; + // const target = findElement(model, relationship.target.element)?.name ?? '?'; + // const relationshipType = relationship.type; + // let type = 'association'; + // let relation: string; + // switch (relationshipType) { + // case UMLRelationshipType.ClassBidirectional: + // relation = ' <-> '; + // break; + // case UMLRelationshipType.ClassUnidirectional: + // relation = ' --> '; + // break; + // case UMLRelationshipType.ClassAggregation: + // relation = ' --◇ '; + // break; + // case UMLRelationshipType.ClassInheritance: + // relation = ' --▷ '; + // break; + // case UMLRelationshipType.ClassDependency: + // relation = ' ╌╌> '; + // break; + // case UMLRelationshipType.ClassComposition: + // relation = ' --◆ '; + // break; + // case UMLRelationshipType.ActivityControlFlow: + // relation = ' --> '; + // type = 'control flow'; + // break; + // default: + // relation = ' --- '; + // } + // assessmentsNames[referencedModelId] = { type, name: source + relation + target }; + // } else { + // assessmentsNames[referencedModelId] = { type: `${referencedModelType}`, name: '' }; + // } + // } + // return assessmentsNames; } /** @@ -119,17 +121,21 @@ export function getNamesForAssessments(result: Result, model: UMLModelCompat): A * @param feedbacks the list of feedback to filter * @param umlModel the UML model containing the references */ -export function filterInvalidFeedback(feedbacks: Feedback[], umlModel: UMLModelCompat): Feedback[] { +export function filterInvalidFeedback(feedbacks: Feedback[], umlModel: UMLModel): Feedback[] { if (!feedbacks) { return feedbacks; } - if (!umlModel || !umlModel.elements) { - return []; - } - - let availableIds: string[] = Object.values(umlModel.elements).map((el) => el.id); - if (umlModel.relationships) { - availableIds = availableIds.concat(Object.values(umlModel.relationships).map((rel) => rel.id)); - } - return feedbacks.filter((feedback) => availableIds.includes(feedback.referenceId!)); + return []; + // if (!feedbacks) { + // return feedbacks; + // } + // if (!umlModel || !umlModel.elements) { + // return []; + // } + // + // let availableIds: string[] = Object.values(umlModel.elements).map((el) => el.id); + // if (umlModel.relationships) { + // availableIds = availableIds.concat(Object.values(umlModel.relationships).map((rel) => rel.id)); + // } + // return feedbacks.filter((feedback) => availableIds.includes(feedback.referenceId!)); } diff --git a/src/main/webapp/app/modeling/manage/detail/modeling-exercise-detail.component.ts b/src/main/webapp/app/modeling/manage/detail/modeling-exercise-detail.component.ts index 51677821e098..120b6a8653d7 100644 --- a/src/main/webapp/app/modeling/manage/detail/modeling-exercise-detail.component.ts +++ b/src/main/webapp/app/modeling/manage/detail/modeling-exercise-detail.component.ts @@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit, inject } from '@angular/core'; import { SafeHtml } from '@angular/platform-browser'; import { ActivatedRoute } from '@angular/router'; import { HttpResponse } from '@angular/common/http'; -import { UMLModel } from '@ls1intum/apollon'; +import { UMLModel } from '@tumaet/apollon'; import { NonProgrammingExerciseDetailCommonActionsComponent } from 'app/exercise/exercise-detail-common-actions/non-programming-exercise-detail-common-actions.component'; import { ExerciseDetailStatisticsComponent } from 'app/exercise/statistics/exercise-detail-statistic/exercise-detail-statistics.component'; import { Subscription } from 'rxjs'; diff --git a/src/main/webapp/app/modeling/manage/example-modeling/example-modeling-submission.component.ts b/src/main/webapp/app/modeling/manage/example-modeling/example-modeling-submission.component.ts index dc1c82c81f0d..d5ec8d6722cd 100644 --- a/src/main/webapp/app/modeling/manage/example-modeling/example-modeling-submission.component.ts +++ b/src/main/webapp/app/modeling/manage/example-modeling/example-modeling-submission.component.ts @@ -4,7 +4,7 @@ import { AlertService } from 'app/shared/service/alert.service'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; import { ExampleSubmissionService } from 'app/assessment/shared/services/example-submission.service'; import { Result } from 'app/exercise/shared/entities/result/result.model'; -import { UMLModel } from '@ls1intum/apollon'; +import { UMLModel } from '@tumaet/apollon'; import { ModelingEditorComponent } from 'app/modeling/shared/modeling-editor/modeling-editor.component'; import { ExampleSubmission, ExampleSubmissionMode } from 'app/assessment/shared/entities/example-submission.model'; import { Feedback, FeedbackCorrectionError, FeedbackType } from 'app/assessment/shared/entities/feedback.model'; diff --git a/src/main/webapp/app/modeling/manage/update/modeling-exercise-update.component.ts b/src/main/webapp/app/modeling/manage/update/modeling-exercise-update.component.ts index 2c402d06e930..d281d4eec751 100644 --- a/src/main/webapp/app/modeling/manage/update/modeling-exercise-update.component.ts +++ b/src/main/webapp/app/modeling/manage/update/modeling-exercise-update.component.ts @@ -1,7 +1,6 @@ import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { HttpErrorResponse } from '@angular/common/http'; -import { ModelingExercise } from 'app/modeling/shared/entities/modeling-exercise.model'; import { ExerciseFeedbackSuggestionOptionsComponent } from 'app/exercise/feedback-suggestion/exercise-feedback-suggestion-options.component'; import { IncludedInOverallScorePickerComponent } from 'app/exercise/included-in-overall-score-picker/included-in-overall-score-picker.component'; import { PresentationScoreComponent } from 'app/exercise/presentation-score/presentation-score.component'; @@ -20,8 +19,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ExerciseUpdateWarningService } from 'app/exercise/exercise-update-warning/exercise-update-warning.service'; import { onError } from 'app/shared/util/global.utils'; import { EditType, SaveExerciseCommand } from 'app/exercise/util/exercise.utils'; -import { UMLDiagramType, UMLModel } from '@ls1intum/apollon'; -import { ModelingEditorComponent } from 'app/modeling/shared/modeling-editor/modeling-editor.component'; +import { UMLDiagramType, UMLModel } from '@tumaet/apollon'; import { AlertService } from 'app/shared/service/alert.service'; import { EventManager } from 'app/shared/service/event-manager.service'; import { DocumentationButtonComponent, DocumentationType } from 'app/shared/components/buttons/documentation-button/documentation-button.component'; @@ -44,6 +42,8 @@ import { loadCourseExerciseCategories } from 'app/exercise/course-exercises/cour import { FormSectionStatus, FormStatusBarComponent } from 'app/shared/form/form-status-bar/form-status-bar.component'; import { CompetencySelectionComponent } from 'app/atlas/shared/competency-selection/competency-selection.component'; import { FormFooterComponent } from 'app/shared/form/form-footer/form-footer.component'; +import { ModelingEditorComponent } from 'app/modeling/shared/modeling-editor/modeling-editor.component'; +import { ModelingExercise } from 'app/modeling/shared/entities/modeling-exercise.model'; @Component({ selector: 'jhi-modeling-exercise-update', @@ -150,6 +150,7 @@ export class ModelingExerciseUpdateComponent implements AfterViewInit, OnDestroy // Get the modelingExercise this.activatedRoute.data.subscribe(({ modelingExercise }) => { + // console.log('DEBUG modelingExercise,', JSON.stringify(modelingExercise)); this.modelingExercise = modelingExercise; if (this.modelingExercise.exampleSolutionModel != undefined) { @@ -193,8 +194,9 @@ export class ModelingExerciseUpdateComponent implements AfterViewInit, OnDestroy if (this.isExamMode) { // The target exerciseGroupId where we want to import into - const exerciseGroupId = params['exerciseGroupId']; - const examId = params['examId']; + // const exerciseGroupId = params['exerciseGroupId']; + // const examId = params['examId']; + const { exerciseGroupId, examId } = params; this.exerciseGroupService.find(courseId, examId, exerciseGroupId).subscribe((res) => (this.modelingExercise.exerciseGroup = res.body!)); // We reference exam exercises by their exercise group, not their course. Having both would lead to conflicts on the server @@ -225,19 +227,25 @@ export class ModelingExerciseUpdateComponent implements AfterViewInit, OnDestroy } async calculateFormSectionStatus() { - await this.modelingEditor?.apollonEditor?.nextRender; this.formSectionStatus = [ { title: 'artemisApp.exercise.sections.general', valid: Boolean(this.exerciseTitleChannelNameComponent?.titleChannelNameComponent.formValid), }, - { title: 'artemisApp.exercise.sections.mode', valid: Boolean(this.teamConfigFormGroupComponent?.formValid) }, - { title: 'artemisApp.exercise.sections.problem', valid: true, empty: !this.modelingExercise.problemStatement }, + { + title: 'artemisApp.exercise.sections.mode', + valid: Boolean(this.teamConfigFormGroupComponent?.formValid), + }, + { + title: 'artemisApp.exercise.sections.problem', + valid: true, + empty: !this.modelingExercise.problemStatement, + }, { title: 'artemisApp.exercise.sections.solution', valid: Boolean(this.isExamMode || (!this.modelingExercise.exampleSolutionPublicationDateError && this.solutionPublicationDateField?.dateInput.valid)), empty: - isEmpty(this.modelingEditor?.getCurrentModel()?.elements) || + isEmpty(this.modelingEditor?.getCurrentModel()?.nodes) || (!this.isExamMode && !this.modelingExercise.exampleSolutionPublicationDate) || !this.modelingExercise.exampleSolutionExplanation, }, diff --git a/src/main/webapp/app/modeling/overview/modeling-submission/modeling-submission.component.html b/src/main/webapp/app/modeling/overview/modeling-submission/modeling-submission.component.html index 1f288d2d3779..389c4e973a02 100644 --- a/src/main/webapp/app/modeling/overview/modeling-submission/modeling-submission.component.html +++ b/src/main/webapp/app/modeling/overview/modeling-submission/modeling-submission.component.html @@ -92,9 +92,8 @@ [(explanation)]="explanation" [resizeOptions]="resizeOptions" [savedStatus]="{ isChanged, isSaving }" - (onModelPatch)="onModelPatch($event)" /> - + @if (modelingExercise.teamMode) { }
diff --git a/src/main/webapp/app/modeling/overview/modeling-submission/modeling-submission.component.ts b/src/main/webapp/app/modeling/overview/modeling-submission/modeling-submission.component.ts index e54f3db874fd..8a30f43a7ddd 100644 --- a/src/main/webapp/app/modeling/overview/modeling-submission/modeling-submission.component.ts +++ b/src/main/webapp/app/modeling/overview/modeling-submission/modeling-submission.component.ts @@ -1,7 +1,7 @@ import { HttpErrorResponse } from '@angular/common/http'; import { Component, HostListener, Input, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; import { ActivatedRoute, RouterLink } from '@angular/router'; -import { Patch, Selection, UMLDiagramType, UMLElementType, UMLModel, UMLRelationshipType } from '@ls1intum/apollon'; +import { Selection, UMLDiagramType, UMLModel } from '@tumaet/apollon'; import { WebsocketService } from 'app/shared/service/websocket.service'; import { ComplaintType } from 'app/assessment/shared/entities/complaint.model'; import { Feedback, buildFeedbackTextForReview, checkSubsequentFeedbackInAssessment } from 'app/assessment/shared/entities/feedback.model'; @@ -381,7 +381,7 @@ export class ModelingSubmissionComponent implements OnInit, OnDestroy, Component private updateModelAndExplanation(): void { if (this.submission.model) { this.umlModel = JSON.parse(this.submission.model); - this.hasElements = this.umlModel.elements && Object.values(this.umlModel.elements).length !== 0; + this.hasElements = this.umlModel.nodes && Object.values(this.umlModel.nodes).length !== 0; } this.explanation = this.submission.explanationText ?? ''; } @@ -416,7 +416,7 @@ export class ModelingSubmissionComponent implements OnInit, OnDestroy, Component this.submission = submission; if (this.submission.model) { this.umlModel = JSON.parse(this.submission.model); - this.hasElements = this.umlModel.elements && Object.values(this.umlModel.elements).length !== 0; + this.hasElements = this.umlModel.nodes && Object.values(this.umlModel.nodes).length !== 0; } const latestResult = getLatestSubmissionResult(this.submission); if (latestResult && latestResult.completionDate && (this.isAfterAssessmentDueDate || latestResult.assessmentType === AssessmentType.AUTOMATIC_ATHENA)) { @@ -524,23 +524,23 @@ export class ModelingSubmissionComponent implements OnInit, OnDestroy, Component this.cleanup(() => clearInterval(teamSyncInterval)); } - /** - * Emits submission patches when receiving patches from the modeling editor. - * These patches need to be synced with other team members in team exercises. - * The observable through which the patches are emitted is passed to the team sync - * component, who then sends the patches to the server and other team members. - * @param patch The patch to update the submission with. - */ - onModelPatch(patch: Patch) { - if (this.modelingExercise.teamMode) { - const submissionPatch = new SubmissionPatch(patch); - submissionPatch.participation = this.participation; - if (submissionPatch.participation?.exercise) { - submissionPatch.participation.exercise.studentParticipations = []; - } - this.submissionPatchObservable.next(Object.assign({}, submissionPatch)); - } - } + // /** + // * Emits submission patches when receiving patches from the modeling editor. + // * These patches need to be synced with other team members in team exercises. + // * The observable through which the patches are emitted is passed to the team sync + // * component, who then sends the patches to the server and other team members. + // * @param patch The patch to update the submission with. + // */ + // onModelPatch(patch: Patch) { + // if (this.modelingExercise.teamMode) { + // const submissionPatch = new SubmissionPatch(patch); + // submissionPatch.participation = this.participation; + // if (submissionPatch.participation?.exercise) { + // submissionPatch.participation.exercise.studentParticipations = []; + // } + // this.submissionPatchObservable.next(Object.assign({}, submissionPatch)); + // } + // } /** * Runs given cleanup logic when the component is destroyed. @@ -604,7 +604,7 @@ export class ModelingSubmissionComponent implements OnInit, OnDestroy, Component this.submission = response.body!; if (this.submission.model) { this.umlModel = JSON.parse(this.submission.model); - this.hasElements = this.umlModel.elements && Object.values(this.umlModel.elements).length !== 0; + this.hasElements = this.umlModel.nodes && Object.values(this.umlModel.nodes).length !== 0; } this.submissionChange.next(this.submission); this.participation = this.submission.participation as StudentParticipation; @@ -670,18 +670,18 @@ export class ModelingSubmissionComponent implements OnInit, OnDestroy, Component this.updateModelingSubmission(submission); } - /** - * This is called when the team sync component receives - * patches from the server. Updates the modeling editor with the received patch. - * @param submissionPatch - */ - onReceiveSubmissionPatchFromTeam(submissionPatch: SubmissionPatch) { - this.modelingEditor.importPatch(submissionPatch.patch); - } + // /** + // * This is called when the team sync component receives + // * patches from the server. Updates the modeling editor with the received patch. + // * @param submissionPatch + // */ + // onReceiveSubmissionPatchFromTeam(submissionPatch: SubmissionPatch) { + // this.modelingEditor.importPatch(submissionPatch.patch); + // } private isModelEmpty(model?: string): boolean { const umlModel: UMLModel = model ? JSON.parse(model) : undefined; - return !umlModel || !umlModel.elements || Object.values(umlModel.elements).length === 0; + return !umlModel || !umlModel.nodes || Object.values(umlModel.nodes).length === 0; } ngOnDestroy(): void { @@ -742,7 +742,7 @@ export class ModelingSubmissionComponent implements OnInit, OnDestroy, Component return; } const umlModel = this.modelingEditor.getCurrentModel(); - this.hasElements = umlModel.elements && Object.values(umlModel.elements).length !== 0; + this.hasElements = umlModel.nodes && Object.values(umlModel.nodes).length !== 0; const diagramJson = JSON.stringify(umlModel); if (this.submission && diagramJson) { this.submission.model = diagramJson; @@ -776,43 +776,45 @@ export class ModelingSubmissionComponent implements OnInit, OnDestroy, Component * @param selection the new selection */ onSelectionChanged(selection: Selection) { - this.selectedEntities = Object.entries(selection.elements) - .filter(([, selected]) => selected) - .map(([elementId]) => elementId); - for (const selectedEntity of this.selectedEntities) { - this.selectedEntities.push(...this.getSelectedChildren(selectedEntity)); - } - this.selectedRelationships = Object.entries(selection.relationships) - .filter(([, selected]) => selected) - .map(([elementId]) => elementId); - } - - /** - * Returns the elementIds of all the children of the element with the given elementId - * or an empty list, if no children exist for this element. - */ - private getSelectedChildren(elementId: string): string[] { - if (!this.umlModel || !this.umlModel.elements) { - return []; - } - return Object.values(this.umlModel.elements) - .filter((element) => element.owner === elementId) - .map((element) => element.id); - } + // console.log('DEBUG Modeling-submission onSelectionChanged ', JSON.stringify(selection)); + // this.selectedEntities = Object.entries(selection.nodes) + // .filter(([, selected]) => selected) + // .map(([elementId]) => elementId); + // for (const selectedEntity of this.selectedEntities) { + // this.selectedEntities.push(...this.getSelectedChildren(selectedEntity)); + // } + // this.selectedRelationships = Object.entries(selection.relationships) + // .filter(([, selected]) => selected) + // .map(([elementId]) => elementId); + } + + // /** + // * Returns the elementIds of all the children of the element with the given elementId + // * or an empty list, if no children exist for this element. + // */ + // private getSelectedChildren(elementId: string): string[] { + // if (!this.umlModel || !this.umlModel.nodes) { + // return []; + // } + // return Object.values(this.umlModel.nodes) + // .filter((element) => element.parentId === elementId) + // .map((element) => element.id); + // } /** * Checks whether a model element in the modeling editor is selected. */ shouldBeDisplayed(feedback: Feedback): boolean { - if ((!this.selectedEntities || this.selectedEntities.length === 0) && (!this.selectedRelationships || this.selectedRelationships.length === 0)) { - return true; - } - const referencedModelType = feedback.referenceType! as UMLElementType; - if (referencedModelType in UMLRelationshipType) { - return this.selectedRelationships.indexOf(feedback.referenceId!) > -1; - } else { - return this.selectedEntities.indexOf(feedback.referenceId!) > -1; - } + return false; + // if ((!this.selectedEntities || this.selectedEntities.length === 0) && (!this.selectedRelationships || this.selectedRelationships.length === 0)) { + // return true; + // } + // const referencedModelType = feedback.referenceType! as UMLElementType; + // if (referencedModelType in UMLRelationshipType) { + // return this.selectedRelationships.indexOf(feedback.referenceId!) > -1; + // } else { + // return this.selectedEntities.indexOf(feedback.referenceId!) > -1; + // } } canDeactivate(): boolean { @@ -843,7 +845,7 @@ export class ModelingSubmissionComponent implements OnInit, OnDestroy, Component */ private modelHasUnsavedChanges(model: UMLModel): boolean { if (!this.submission || !this.submission.model) { - return Object.values(model.elements).length > 0 && JSON.stringify(model) !== ''; + return Object.values(model.nodes).length > 0 && JSON.stringify(model) !== ''; } else if (this.submission && this.submission.model) { const currentModel = JSON.parse(this.submission.model); const versionMatch = currentModel.version === model.version; diff --git a/src/main/webapp/app/modeling/shared/entities/apollon-diagram.model.ts b/src/main/webapp/app/modeling/shared/entities/apollon-diagram.model.ts index 3a12c71daf5a..92b29107e8e7 100644 --- a/src/main/webapp/app/modeling/shared/entities/apollon-diagram.model.ts +++ b/src/main/webapp/app/modeling/shared/entities/apollon-diagram.model.ts @@ -1,4 +1,4 @@ -import { UMLDiagramType } from '@ls1intum/apollon'; +import { UMLDiagramType } from '@tumaet/apollon'; import { BaseEntity } from 'app/shared/model/base-entity'; export class ApollonDiagram implements BaseEntity { diff --git a/src/main/webapp/app/modeling/shared/entities/modeling-exercise.model.ts b/src/main/webapp/app/modeling/shared/entities/modeling-exercise.model.ts index 465b55694c76..4e41eaa6086b 100644 --- a/src/main/webapp/app/modeling/shared/entities/modeling-exercise.model.ts +++ b/src/main/webapp/app/modeling/shared/entities/modeling-exercise.model.ts @@ -2,7 +2,7 @@ import { Exercise, ExerciseType } from 'app/exercise/shared/entities/exercise/ex import { Course } from 'app/core/course/shared/entities/course.model'; import { AssessmentType } from 'app/assessment/shared/entities/assessment-type.model'; import { ExerciseGroup } from 'app/exam/shared/entities/exercise-group.model'; -import { type UMLDiagramType, UMLDiagramType as UMLDiagramTypes } from '@ls1intum/apollon'; +import { UMLDiagramType } from '@tumaet/apollon'; export class ModelingExercise extends Exercise { public diagramType?: UMLDiagramType; @@ -17,7 +17,7 @@ export class ModelingExercise extends Exercise { // default value this.assessmentType = AssessmentType.MANUAL; - if (this.diagramType === UMLDiagramTypes.ClassDiagram || this.diagramType === UMLDiagramTypes.ActivityDiagram) { + if (this.diagramType === UMLDiagramType.ClassDiagram || this.diagramType === UMLDiagramType.ActivityDiagram) { this.assessmentType = AssessmentType.SEMI_AUTOMATIC; } } diff --git a/src/main/webapp/app/modeling/shared/modeling-editor/modeling-editor.component.scss b/src/main/webapp/app/modeling/shared/modeling-editor/modeling-editor.component.scss index 802e39226865..061d99156a39 100644 --- a/src/main/webapp/app/modeling/shared/modeling-editor/modeling-editor.component.scss +++ b/src/main/webapp/app/modeling/shared/modeling-editor/modeling-editor.component.scss @@ -43,6 +43,8 @@ $draggable-width: 15px; } .apollon-container { + display: flex; + flex: 1; height: 100%; min-height: 750px; overflow: hidden; diff --git a/src/main/webapp/app/modeling/shared/modeling-editor/modeling-editor.component.ts b/src/main/webapp/app/modeling/shared/modeling-editor/modeling-editor.component.ts index 01f5363abd66..0ab57c2ca8ca 100644 --- a/src/main/webapp/app/modeling/shared/modeling-editor/modeling-editor.component.ts +++ b/src/main/webapp/app/modeling/shared/modeling-editor/modeling-editor.component.ts @@ -1,12 +1,12 @@ import { AfterViewInit, Component, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges, ViewEncapsulation, inject } from '@angular/core'; -import { ApollonEditor, ApollonMode, SVG, UMLDiagramType, UMLElementType, UMLModel } from '@ls1intum/apollon'; +import { ApollonEditor, ApollonMode, SVG, UMLDiagramType, UMLModel } from '@tumaet/apollon'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { isFullScreen } from 'app/shared/util/fullscreen.util'; import { faCheck, faCircleNotch, faTimes } from '@fortawesome/free-solid-svg-icons'; import { faQuestionCircle } from '@fortawesome/free-regular-svg-icons'; import { ModelingComponent } from 'app/modeling/shared/modeling/modeling.component'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; -import { Patch } from '@ls1intum/apollon'; +// import { Patch } from '@ls1intum/apollon'; import { TranslateDirective } from 'app/shared/language/translate.directive'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { NgClass, NgStyle } from '@angular/common'; @@ -29,12 +29,12 @@ export class ModelingEditorComponent extends ModelingComponent implements AfterV @Input() savedStatus?: { isChanged?: boolean; isSaving?: boolean }; @Output() private onModelChanged: EventEmitter = new EventEmitter(); - @Output() onModelPatch = new EventEmitter(); + // @Output() onModelPatch = new EventEmitter(); @Output() explanationChange = new EventEmitter(); private modelSubscription: number; - private modelPatchSubscription: number; + // private modelPatchSubscription: number; // Icons faCheck = faCheck; @@ -60,14 +60,13 @@ export class ModelingEditorComponent extends ModelingComponent implements AfterV async ngAfterViewInit(): Promise { this.initializeApollonEditor(); if (this.readOnly) { - await this.apollonEditor?.nextRender; - this.readonlyApollonDiagram = await this.apollonEditor?.exportAsSVG(); - if (this.readonlyApollonDiagram?.svg) { - this.readOnlySVG = this.sanitizer.bypassSecurityTrustHtml(this.readonlyApollonDiagram.svg); + if (this.apollonEditor) { + await ApollonEditor.exportModelAsSvg(this.apollonEditor?.model); + this.readonlyApollonDiagram = await this.apollonEditor?.exportAsSVG(); + if (this.readonlyApollonDiagram?.svg) { + this.readOnlySVG = this.sanitizer.bypassSecurityTrustHtml(this.readonlyApollonDiagram.svg); + } } - - // Destroy the Apollon editor after exporting the SVG, to avoid SVG id collisions - this.destroyApollonEditor(); } else { this.setupInteract(); this.setupSafariScrollFix(); @@ -80,7 +79,6 @@ export class ModelingEditorComponent extends ModelingComponent implements AfterV private initializeApollonEditor(): void { if (this.apollonEditor) { this.apollonEditor.unsubscribeFromModelChange(this.modelSubscription); - this.apollonEditor.unsubscribeFromModelChangePatches(this.modelPatchSubscription); this.apollonEditor.destroy(); } @@ -100,9 +98,9 @@ export class ModelingEditorComponent extends ModelingComponent implements AfterV this.onModelChanged.emit(model); }); - this.modelPatchSubscription = this.apollonEditor.subscribeToModelChangePatches((patch: Patch) => { - this.onModelPatch.emit(patch); - }); + // this.modelPatchSubscription = this.apollonEditor.subscribeToModelChangePatches((patch: Patch) => { + // this.onModelPatch.emit(patch); + // }); } } @@ -149,9 +147,9 @@ export class ModelingEditorComponent extends ModelingComponent implements AfterV if (this.modelSubscription) { this.apollonEditor.unsubscribeFromModelChange(this.modelSubscription); } - if (this.modelPatchSubscription) { - this.apollonEditor.unsubscribeFromModelChangePatches(this.modelPatchSubscription); - } + // if (this.modelPatchSubscription) { + // this.apollonEditor.unsubscribeFromModelChangePatches(this.modelPatchSubscription); + // } this.apollonEditor.destroy(); this.apollonEditor = undefined; } @@ -209,7 +207,7 @@ export class ModelingEditorComponent extends ModelingComponent implements AfterV this.umlModel = changes.umlModel.currentValue; // Apollon doesn't need assessments in Modeling mode ModelingEditorComponent.removeAssessments(this.umlModel); - this.apollonEditor.model = this.umlModel; + // this.apollonEditor.model = this.umlModel; } } @@ -224,33 +222,6 @@ export class ModelingEditorComponent extends ModelingComponent implements AfterV } } - /** - * Return the UMLModelElement of the type class with the @param name - * @param name class name - * @param umlModel current model that is assessed - */ - elementWithClass(name: string, umlModel: UMLModel) { - return Object.values(umlModel.elements).find((element) => element.name.trim() === name && element.type === UMLElementType.Class); - } - - /** - * Return the UMLModelElement of the type ClassAttribute with the @param attribute - * @param attribute name - * @param umlModel current model that is assessed - */ - elementWithAttribute(attribute: string, umlModel: UMLModel) { - return Object.values(umlModel.elements).find((element) => element.name.includes(attribute) && element.type === UMLElementType.ClassAttribute); - } - - /** - * Return the UMLModelElement of the type ClassMethod with the @param method - * @param method name - * @param umlModel current model that is assessed - */ - elementWithMethod(method: string, umlModel: UMLModel) { - return Object.values(umlModel.elements).find((element) => element.name.includes(method) && element.type === UMLElementType.ClassMethod); - } - /** * checks if this component is the current fullscreen component */ @@ -264,11 +235,11 @@ export class ModelingEditorComponent extends ModelingComponent implements AfterV this.explanation = newValue; } - /** - * Import a patch into the Apollon editor - * @param patch the patch to import - */ - importPatch(patch: Patch) { - this.apollonEditor?.importPatch(patch); - } + // /** + // * Import a patch into the Apollon editor + // * @param patch the patch to import + // */ + // importPatch(patch: Patch) { + // this.apollonEditor?.importPatch(patch); + // } } diff --git a/src/main/webapp/app/modeling/shared/modeling/modeling.component.ts b/src/main/webapp/app/modeling/shared/modeling/modeling.component.ts index 667f25718fc6..e72f06470ba5 100644 --- a/src/main/webapp/app/modeling/shared/modeling/modeling.component.ts +++ b/src/main/webapp/app/modeling/shared/modeling/modeling.component.ts @@ -1,6 +1,6 @@ import { Component, ElementRef, Input, ViewChild } from '@angular/core'; import { faGripLines, faGripLinesVertical } from '@fortawesome/free-solid-svg-icons'; -import { ApollonEditor, UMLDiagramType, UMLModel } from '@ls1intum/apollon'; +import { ApollonEditor, UMLDiagramType, UMLModel } from '@tumaet/apollon'; import { MODELING_EDITOR_MAX_HEIGHT, MODELING_EDITOR_MAX_WIDTH, MODELING_EDITOR_MIN_HEIGHT, MODELING_EDITOR_MIN_WIDTH } from 'app/shared/constants/modeling.constants'; import interact from 'interactjs'; diff --git a/src/main/webapp/app/quiz/manage/apollon-diagrams/detail/apollon-diagram-detail.component.html b/src/main/webapp/app/quiz/manage/apollon-diagrams/detail/apollon-diagram-detail.component.html index 65b59b45c255..12b63b459540 100644 --- a/src/main/webapp/app/quiz/manage/apollon-diagrams/detail/apollon-diagram-detail.component.html +++ b/src/main/webapp/app/quiz/manage/apollon-diagrams/detail/apollon-diagram-detail.component.html @@ -25,7 +25,7 @@
} -
+