From b981275b8139133e6c85b738ee7400862f2eea99 Mon Sep 17 00:00:00 2001 From: Liav Weiss <74174727+liavweiss@users.noreply.github.com> Date: Thu, 20 Feb 2025 14:58:43 +0200 Subject: [PATCH] feat(ws): Notebooks 2.0 // Frontend // Workspaces details // Pod template tab #173 (#197) * feat(ws): Notebooks 2.0 // Frontend // Workspaces details // Pod template tab #173 Signed-off-by: Liav Weiss (EXT-Nokia) * feat(ws): Notebooks 2.0 // Frontend // Workspaces details // Pod template tab kubeflow#173 Signed-off-by: Liav Weiss (EXT-Nokia) * feat(ws): Notebooks 2.0 // Frontend // Workspaces details // Pod template tab kubeflow#173 Signed-off-by: Liav Weiss (EXT-Nokia) --------- Signed-off-by: Liav Weiss (EXT-Nokia) Co-authored-by: Liav Weiss (EXT-Nokia) --- workspaces/frontend/package-lock.json | 142 +++++++++++++----- workspaces/frontend/package.json | 3 + .../Workspaces/Details/WorkspaceDetails.tsx | 91 ++++++++--- .../Details/WorkspaceDetailsPodTemplate.tsx | 41 +++++ 4 files changed, 216 insertions(+), 61 deletions(-) create mode 100644 workspaces/frontend/src/app/pages/Workspaces/Details/WorkspaceDetailsPodTemplate.tsx diff --git a/workspaces/frontend/package-lock.json b/workspaces/frontend/package-lock.json index a5db00e2..8ad33128 100644 --- a/workspaces/frontend/package-lock.json +++ b/workspaces/frontend/package-lock.json @@ -9,10 +9,13 @@ "version": "0.0.1", "license": "Apache-2.0", "dependencies": { + "@patternfly/react-code-editor": "^6.0.0", "@patternfly/react-core": "^6.0.0", "@patternfly/react-icons": "^6.0.0", "@patternfly/react-styles": "^6.0.0", "@patternfly/react-table": "^6.0.0", + "@types/js-yaml": "^4.0.9", + "js-yaml": "^4.1.0", "npm-run-all": "^4.1.5", "react": "^18", "react-dom": "^18", @@ -3373,6 +3376,32 @@ "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==", "dev": true }, + "node_modules/@monaco-editor/loader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", + "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", + "license": "MIT", + "dependencies": { + "state-local": "^1.0.6" + }, + "peerDependencies": { + "monaco-editor": ">= 0.21.0 < 1" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", + "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", + "license": "MIT", + "dependencies": { + "@monaco-editor/loader": "^1.4.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@mui/core-downloads-tracker": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.3.1.tgz", @@ -4008,18 +4037,36 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@patternfly/react-core": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-6.0.0.tgz", - "integrity": "sha512-UKFj9+YzBY+FfEDsLONgOM4N0e8SPV/27/UzNRiJ0gpgqbw2POuXwLpjGSRTTIUuCaLaGGM5PeTSj7mMB73ykw==", + "node_modules/@patternfly/react-code-editor": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-code-editor/-/react-code-editor-6.1.0.tgz", + "integrity": "sha512-ae04+DdkgXFn3wEzvNCncNa78ZK3Swh5ng8p7yqFrD6lhW69NoJf+DdQlHi8gM8Qy05DNnIemSbQWpWLpInyzw==", "license": "MIT", "dependencies": { - "@patternfly/react-icons": "^6.0.0", - "@patternfly/react-styles": "^6.0.0", - "@patternfly/react-tokens": "^6.0.0", - "focus-trap": "7.6.0", - "react-dropzone": "^14.2.3", - "tslib": "^2.7.0" + "@monaco-editor/react": "^4.6.0", + "@patternfly/react-core": "^6.1.0", + "@patternfly/react-icons": "^6.1.0", + "@patternfly/react-styles": "^6.1.0", + "react-dropzone": "14.3.5", + "tslib": "^2.8.1" + }, + "peerDependencies": { + "react": "^17 || ^18", + "react-dom": "^17 || ^18" + } + }, + "node_modules/@patternfly/react-core": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-6.1.0.tgz", + "integrity": "sha512-zj0lJPZxQanXKD8ae2kYnweT0kpp1CzpHYAkaBjTrw2k6ZMfr/UPlp0/ugCjWEokBqh79RUADLkKJJPce/yoSQ==", + "license": "MIT", + "dependencies": { + "@patternfly/react-icons": "^6.1.0", + "@patternfly/react-styles": "^6.1.0", + "@patternfly/react-tokens": "^6.1.0", + "focus-trap": "7.6.2", + "react-dropzone": "^14.3.5", + "tslib": "^2.8.1" }, "peerDependencies": { "react": "^17 || ^18", @@ -4027,9 +4074,9 @@ } }, "node_modules/@patternfly/react-icons": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-6.0.0.tgz", - "integrity": "sha512-ZFrsBVKrAp0DZrPOss98OA/EVUL4F0frXhR1uBId9+3ZrRArdKTgYgmQUCeSzMbxnSlxpmm3a2L05XQ36VUVbw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-6.1.0.tgz", + "integrity": "sha512-V1w/j19YmOgvh72IRRf1p07k+u4M5+9P+o/IxunlF0fWzLDX4Hf+utBI11A8cRfUzpQN7eLw/vZIS3BLM8Ge3Q==", "license": "MIT", "peerDependencies": { "react": "^17 || ^18", @@ -4037,9 +4084,9 @@ } }, "node_modules/@patternfly/react-styles": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-6.0.0.tgz", - "integrity": "sha512-fJFMB89sTRGlZTzTLmpRmthgOXqcN078scHMFJ3ttfi2D2btnem5oZrxmQ/gPZkZOxR+9MqwKDB6l3F5x1SqLQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-6.1.0.tgz", + "integrity": "sha512-JQ3zIl5SFiSB0YWVYibcUwgZdsp6Wn8hkfZ7KhtCjHFccSDdJexPOXVV1O9f2h4PfxTlY3YntZ81ZsguBx/Q7A==", "license": "MIT" }, "node_modules/@patternfly/react-table": { @@ -4061,9 +4108,9 @@ } }, "node_modules/@patternfly/react-tokens": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-6.0.0.tgz", - "integrity": "sha512-xd0ynDkiIW2rp8jz4TNvR4Dyaw9kSMkZdsuYcLlFXCVmvX//Mnl4rhBnid/2j2TaqK0NbkyTTPnPY/BU7SfLVQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-6.1.0.tgz", + "integrity": "sha512-t1UcHbOa4txczTR5UlnG4XcAAdnDSfSlCaOddw/HTqRF59pn2ks2JUu9sfnFRZ8SiAAxKRiYdX5bT7Mf4R24+w==", "license": "MIT" }, "node_modules/@pkgjs/parseargs": { @@ -4749,6 +4796,12 @@ "pretty-format": "^29.0.0" } }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "license": "MIT" + }, "node_modules/@types/jsdom": { "version": "20.0.1", "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", @@ -5629,8 +5682,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "devOptional": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/aria-query": { "version": "5.3.0", @@ -5867,9 +5919,10 @@ } }, "node_modules/attr-accept": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", - "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", + "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==", + "license": "MIT", "engines": { "node": ">=4" } @@ -10642,11 +10695,12 @@ } }, "node_modules/file-selector": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", - "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.2.tgz", + "integrity": "sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==", + "license": "MIT", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.7.0" }, "engines": { "node": ">= 12" @@ -10907,9 +10961,9 @@ "optional": true }, "node_modules/focus-trap": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.0.tgz", - "integrity": "sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.2.tgz", + "integrity": "sha512-9FhUxK1hVju2+AiQIDJ5Dd//9R2n2RAfJ0qfhF4IHGHgcoEUTMpbTeG/zbEuwaiYXfuAH6XE0/aCyxDdRM+W5w==", "license": "MIT", "dependencies": { "tabbable": "^6.2.0" @@ -14492,7 +14546,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "devOptional": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -16211,6 +16265,13 @@ "node": ">=8" } }, + "node_modules/monaco-editor": { + "version": "0.52.2", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", + "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==", + "license": "MIT", + "peer": true + }, "node_modules/mri": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", @@ -18196,12 +18257,13 @@ } }, "node_modules/react-dropzone": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz", - "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==", + "version": "14.3.5", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.5.tgz", + "integrity": "sha512-9nDUaEEpqZLOz5v5SUcFA0CjM4vq8YbqO0WRls+EYT7+DvxUdzDPKNCPLqGfj3YL9MsniCLCD4RFA6M95V6KMQ==", + "license": "MIT", "dependencies": { - "attr-accept": "^2.2.2", - "file-selector": "^0.6.0", + "attr-accept": "^2.2.4", + "file-selector": "^2.1.0", "prop-types": "^15.8.1" }, "engines": { @@ -19858,6 +19920,12 @@ "node": ">=8" } }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", + "license": "MIT" + }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", diff --git a/workspaces/frontend/package.json b/workspaces/frontend/package.json index 88553576..9abd9591 100644 --- a/workspaces/frontend/package.json +++ b/workspaces/frontend/package.json @@ -94,10 +94,13 @@ "webpack-merge": "^5.10.0" }, "dependencies": { + "@patternfly/react-code-editor": "^6.0.0", "@patternfly/react-core": "^6.0.0", "@patternfly/react-icons": "^6.0.0", "@patternfly/react-styles": "^6.0.0", "@patternfly/react-table": "^6.0.0", + "@types/js-yaml": "^4.0.9", + "js-yaml": "^4.1.0", "npm-run-all": "^4.1.5", "react": "^18", "react-dom": "^18", diff --git a/workspaces/frontend/src/app/pages/Workspaces/Details/WorkspaceDetails.tsx b/workspaces/frontend/src/app/pages/Workspaces/Details/WorkspaceDetails.tsx index 2c794894..05990f3c 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/Details/WorkspaceDetails.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/Details/WorkspaceDetails.tsx @@ -16,6 +16,7 @@ import { Workspace } from '~/shared/types'; import { WorkspaceDetailsOverview } from '~/app/pages/Workspaces/Details/WorkspaceDetailsOverview'; import { WorkspaceDetailsActions } from '~/app/pages/Workspaces/Details/WorkspaceDetailsActions'; import { WorkspaceDetailsActivity } from '~/app/pages/Workspaces/Details/WorkspaceDetailsActivity'; +import { WorkspaceDetailsPodTemplate } from '~/app/pages/Workspaces/Details/WorkspaceDetailsPodTemplate'; type WorkspaceDetailsProps = { workspace: Workspace; @@ -48,43 +49,85 @@ export const WorkspaceDetails: React.FunctionComponent = + - Overview} aria-label="Overview"> - - - - - - + Overview} + tabContentId="overviewTabContent" + aria-label="Overview" + /> Activity} + tabContentId="activityTabContent" aria-label="Activity" data-testid="activityTab" - > - - - - - - - Logs} aria-label="Logs"> - - Logs - - + /> + Logs} + tabContentId="logsTabContent" + aria-label="Logs" + /> Pod template} + tabContentId="podTemplateTabContent" aria-label="Pod template" - > - - Pod template - - + /> + + + + + + + + + + ); }; diff --git a/workspaces/frontend/src/app/pages/Workspaces/Details/WorkspaceDetailsPodTemplate.tsx b/workspaces/frontend/src/app/pages/Workspaces/Details/WorkspaceDetailsPodTemplate.tsx new file mode 100644 index 00000000..3a73e2d0 --- /dev/null +++ b/workspaces/frontend/src/app/pages/Workspaces/Details/WorkspaceDetailsPodTemplate.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { CodeEditor, Language } from '@patternfly/react-code-editor'; +import yaml from 'js-yaml'; + +const mockYaml = `apiVersion: kubeflow.org/v1beta1 +kind: Workspace +metadata: + name: jupyterlab-workspace +spec: + paused: false + deferUpdates: false + kind: "jupyterlab" + podTemplate: + podMetadata: + labels: {} + annotations: {} + volumes: + home: "workspace-home-pvc" + data: + - pvcName: "workspace-data-pvc" + mountPath: "/data/my-data" + readOnly: false + options: + imageConfig: "jupyterlab_scipy_190" + podConfig: "tiny_cpu"`; + +export const WorkspaceDetailsPodTemplate: React.FunctionComponent = () => { + const parsedYaml = yaml.load(mockYaml); + const podTemplateYaml = yaml.dump(parsedYaml || {}); + + return ( + + ); +};