From e1eb04494a5650726c95990f74fc719eced4ccb5 Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Tue, 21 Dec 2021 12:36:58 +0500 Subject: [PATCH 1/9] fix: updated route for sas code --- api/public/swagger.yaml | 91 +++++++++++++++++++----------------- api/src/controllers/index.ts | 3 +- api/src/controllers/run.ts | 61 ++++++++++++++++++++++++ api/src/controllers/stp.ts | 38 --------------- api/src/routes/api/index.ts | 2 + api/src/routes/api/run.ts | 25 ++++++++++ api/src/routes/api/stp.ts | 16 ------- api/tsoa.json | 4 ++ docker-compose.yml | 2 +- 9 files changed, 142 insertions(+), 100 deletions(-) create mode 100644 api/src/controllers/run.ts create mode 100644 api/src/routes/api/run.ts diff --git a/api/public/swagger.yaml b/api/public/swagger.yaml index 65b8c5a..83e67f2 100644 --- a/api/public/swagger.yaml +++ b/api/public/swagger.yaml @@ -982,6 +982,50 @@ paths: format: double type: number example: '6789' + /SASjsApi/run/code: + post: + operationId: RunSAS + responses: + '200': + description: Ok + content: + application/json: + schema: + type: string + description: 'Trigger a SAS program.' + summary: 'Run SAS Program, return raw content' + tags: + - RUN + security: + - + bearerAuth: [] + parameters: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RunSASPayload' + /SASjsApi/session: + get: + operationId: Session + responses: + '200': + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/UserResponse' + examples: + 'Example 1': + value: {id: 123, username: johnusername, displayName: John} + summary: 'Get session info (username).' + tags: + - Session + security: + - + bearerAuth: [] + parameters: [] /SASjsApi/stp/execute: get: operationId: ExecuteReturnRaw @@ -1037,50 +1081,6 @@ paths: application/json: schema: $ref: '#/components/schemas/ExecuteReturnJsonPayload' - /SASjsApi/stp/run: - post: - operationId: RunSAS - responses: - '200': - description: Ok - content: - application/json: - schema: - type: string - description: 'Trigger a SAS program.' - summary: 'Run SAS Program, return raw content' - tags: - - STP - security: - - - bearerAuth: [] - parameters: [] - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/RunSASPayload' - /SASjsApi/session: - get: - operationId: Session - responses: - '200': - description: Ok - content: - application/json: - schema: - $ref: '#/components/schemas/UserResponse' - examples: - 'Example 1': - value: {id: 123, username: johnusername, displayName: John} - summary: 'Get session info (username).' - tags: - - Session - security: - - - bearerAuth: [] - parameters: [] servers: - url: / @@ -1106,3 +1106,6 @@ tags: - name: STP description: 'Operations about STP' + - + name: RUN + description: 'Execute SAS code' diff --git a/api/src/controllers/index.ts b/api/src/controllers/index.ts index 805cc3c..4522358 100644 --- a/api/src/controllers/index.ts +++ b/api/src/controllers/index.ts @@ -2,6 +2,7 @@ export * from './auth' export * from './client' export * from './drive' export * from './group' +export * from './run' +export * from './session' export * from './stp' export * from './user' -export * from './session' diff --git a/api/src/controllers/run.ts b/api/src/controllers/run.ts new file mode 100644 index 0000000..7adb695 --- /dev/null +++ b/api/src/controllers/run.ts @@ -0,0 +1,61 @@ +import express from 'express' +import { Request, Security, Route, Tags, Post, Body } from 'tsoa' +import { ExecutionController } from './internal' +import { PreProgramVars } from '../types' + +interface RunSASPayload { + /** + * Code of SAS program + * @example "* SAS Code HERE;" + */ + code: string +} + +@Security('bearerAuth') +@Route('SASjsApi/run') +@Tags('RUN') +export class RUNController { + /** + * Trigger a SAS program. + * @summary Run SAS Program, return raw content + */ + @Post('/code') + public async runSAS( + @Request() request: express.Request, + @Body() body: RunSASPayload + ): Promise { + return runSAS(request, body) + } +} + +const runSAS = async (req: any, { code }: RunSASPayload) => { + try { + const result = await new ExecutionController().executeProgram( + code, + getPreProgramVariables(req), + { ...req.query, _debug: 131 } + ) + + return result as string + } catch (err: any) { + throw { + code: 400, + status: 'failure', + message: 'Job execution failed.', + error: typeof err === 'object' ? err.toString() : err + } + } +} + +const getPreProgramVariables = (req: any): PreProgramVars => { + const host = req.get('host') + const protocol = req.protocol + '://' + const { user, accessToken } = req + return { + username: user.username, + userId: user.userId, + displayName: user.displayName, + serverUrl: protocol + host, + accessToken + } +} diff --git a/api/src/controllers/stp.ts b/api/src/controllers/stp.ts index d94ac25..b0f78ac 100644 --- a/api/src/controllers/stp.ts +++ b/api/src/controllers/stp.ts @@ -5,13 +5,6 @@ import { ExecutionController } from './internal' import { PreProgramVars } from '../types' import { getTmpFilesFolderPath, makeFilesNamesMap } from '../utils' -interface RunSASPayload { - /** - * Code of SAS program - * @example "* SAS Code HERE;" - */ - code: string -} interface ExecuteReturnJsonPayload { /** * Location of SAS program @@ -48,18 +41,6 @@ export class STPController { return executeReturnRaw(request, _program) } - /** - * Trigger a SAS program. - * @summary Run SAS Program, return raw content - */ - @Post('/run') - public async runSAS( - @Request() request: express.Request, - @Body() body: RunSASPayload - ): Promise { - return runSAS(request, body) - } - /** * Trigger a SAS program using it's location in the _program parameter. * Enable debugging using the _debug parameter. @@ -109,25 +90,6 @@ const executeReturnRaw = async ( } } -const runSAS = async (req: any, { code }: RunSASPayload) => { - try { - const result = await new ExecutionController().executeProgram( - code, - getPreProgramVariables(req), - req.query - ) - - return result as string - } catch (err: any) { - throw { - code: 400, - status: 'failure', - message: 'Job execution failed.', - error: typeof err === 'object' ? err.toString() : err - } - } -} - const executeReturnJson = async ( req: any, _program: string diff --git a/api/src/routes/api/index.ts b/api/src/routes/api/index.ts index b91715c..650b01c 100644 --- a/api/src/routes/api/index.ts +++ b/api/src/routes/api/index.ts @@ -11,6 +11,7 @@ import { import driveRouter from './drive' import stpRouter from './stp' +import runRouter from './run' import userRouter from './user' import groupRouter from './group' import clientRouter from './client' @@ -31,6 +32,7 @@ router.use( router.use('/drive', authenticateAccessToken, driveRouter) router.use('/group', desktopRestrict, groupRouter) router.use('/stp', authenticateAccessToken, stpRouter) +router.use('/run', authenticateAccessToken, runRouter) router.use('/user', desktopRestrict, userRouter) router.use( '/', diff --git a/api/src/routes/api/run.ts b/api/src/routes/api/run.ts new file mode 100644 index 0000000..e45ad64 --- /dev/null +++ b/api/src/routes/api/run.ts @@ -0,0 +1,25 @@ +import express from 'express' +import { runSASValidation } from '../../utils' +import { RUNController } from '../../controllers/' + +const runRouter = express.Router() + +const controller = new RUNController() + +runRouter.post('/code', async (req, res) => { + const { error, value: body } = runSASValidation(req.body) + if (error) return res.status(400).send(error.details[0].message) + + try { + const response = await controller.runSAS(req, body) + res.send(response) + } catch (err: any) { + const statusCode = err.code + + delete err.code + + res.status(statusCode).send(err) + } +}) + +export default runRouter diff --git a/api/src/routes/api/stp.ts b/api/src/routes/api/stp.ts index b00707d..1ca4a18 100644 --- a/api/src/routes/api/stp.ts +++ b/api/src/routes/api/stp.ts @@ -24,22 +24,6 @@ stpRouter.get('/execute', async (req, res) => { } }) -stpRouter.post('/run', async (req, res) => { - const { error, value: body } = runSASValidation(req.body) - if (error) return res.status(400).send(error.details[0].message) - - try { - const response = await controller.runSAS(req, body) - res.send(response) - } catch (err: any) { - const statusCode = err.code - - delete err.code - - res.status(statusCode).send(err) - } -}) - stpRouter.post( '/execute', fileUploadController.preuploadMiddleware, diff --git a/api/tsoa.json b/api/tsoa.json index b1b912b..842e35b 100644 --- a/api/tsoa.json +++ b/api/tsoa.json @@ -38,6 +38,10 @@ { "name": "STP", "description": "Operations about STP" + }, + { + "name": "RUN", + "description": "Execute SAS code" } ], "yaml": true, diff --git a/docker-compose.yml b/docker-compose.yml index f7368c7..7bce991 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,7 +43,7 @@ services: - ./web:/usr/server/web mongodb: - image: mongo:latest + image: mongo:5.0.4 ports: - 27017:27017 volumes: From e6e5a5fd640957d2633f6d174b834395ad79e2f2 Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Tue, 21 Dec 2021 14:24:27 +0500 Subject: [PATCH 2/9] chore(code): updated route to code/execute --- api/src/controllers/{run.ts => code.ts} | 22 +++++++++++----------- api/src/controllers/index.ts | 2 +- api/src/routes/api/{run.ts => code.ts} | 6 +++--- api/src/routes/api/index.ts | 4 ++-- api/tsoa.json | 4 ++-- 5 files changed, 19 insertions(+), 19 deletions(-) rename api/src/controllers/{run.ts => code.ts} (74%) rename api/src/routes/api/{run.ts => code.ts} (74%) diff --git a/api/src/controllers/run.ts b/api/src/controllers/code.ts similarity index 74% rename from api/src/controllers/run.ts rename to api/src/controllers/code.ts index 7adb695..6aa8c17 100644 --- a/api/src/controllers/run.ts +++ b/api/src/controllers/code.ts @@ -3,7 +3,7 @@ import { Request, Security, Route, Tags, Post, Body } from 'tsoa' import { ExecutionController } from './internal' import { PreProgramVars } from '../types' -interface RunSASPayload { +interface ExecuteSASCodePayload { /** * Code of SAS program * @example "* SAS Code HERE;" @@ -12,23 +12,23 @@ interface RunSASPayload { } @Security('bearerAuth') -@Route('SASjsApi/run') -@Tags('RUN') -export class RUNController { +@Route('SASjsApi/code') +@Tags('CODE') +export class CodeController { /** - * Trigger a SAS program. - * @summary Run SAS Program, return raw content + * Execute SAS code. + * @summary Run SAS Code and returns log */ - @Post('/code') - public async runSAS( + @Post('/execute') + public async executeSASCode( @Request() request: express.Request, - @Body() body: RunSASPayload + @Body() body: ExecuteSASCodePayload ): Promise { - return runSAS(request, body) + return executeSASCode(request, body) } } -const runSAS = async (req: any, { code }: RunSASPayload) => { +const executeSASCode = async (req: any, { code }: ExecuteSASCodePayload) => { try { const result = await new ExecutionController().executeProgram( code, diff --git a/api/src/controllers/index.ts b/api/src/controllers/index.ts index 4522358..d2efa88 100644 --- a/api/src/controllers/index.ts +++ b/api/src/controllers/index.ts @@ -1,8 +1,8 @@ export * from './auth' export * from './client' +export * from './code' export * from './drive' export * from './group' -export * from './run' export * from './session' export * from './stp' export * from './user' diff --git a/api/src/routes/api/run.ts b/api/src/routes/api/code.ts similarity index 74% rename from api/src/routes/api/run.ts rename to api/src/routes/api/code.ts index e45ad64..ef4af95 100644 --- a/api/src/routes/api/run.ts +++ b/api/src/routes/api/code.ts @@ -1,17 +1,17 @@ import express from 'express' import { runSASValidation } from '../../utils' -import { RUNController } from '../../controllers/' +import { CodeController } from '../../controllers/' const runRouter = express.Router() -const controller = new RUNController() +const controller = new CodeController() runRouter.post('/code', async (req, res) => { const { error, value: body } = runSASValidation(req.body) if (error) return res.status(400).send(error.details[0].message) try { - const response = await controller.runSAS(req, body) + const response = await controller.executeSASCode(req, body) res.send(response) } catch (err: any) { const statusCode = err.code diff --git a/api/src/routes/api/index.ts b/api/src/routes/api/index.ts index 650b01c..e21022d 100644 --- a/api/src/routes/api/index.ts +++ b/api/src/routes/api/index.ts @@ -11,7 +11,7 @@ import { import driveRouter from './drive' import stpRouter from './stp' -import runRouter from './run' +import codeRouter from './code' import userRouter from './user' import groupRouter from './group' import clientRouter from './client' @@ -32,7 +32,7 @@ router.use( router.use('/drive', authenticateAccessToken, driveRouter) router.use('/group', desktopRestrict, groupRouter) router.use('/stp', authenticateAccessToken, stpRouter) -router.use('/run', authenticateAccessToken, runRouter) +router.use('/code', authenticateAccessToken, codeRouter) router.use('/user', desktopRestrict, userRouter) router.use( '/', diff --git a/api/tsoa.json b/api/tsoa.json index 842e35b..8fe396f 100644 --- a/api/tsoa.json +++ b/api/tsoa.json @@ -40,8 +40,8 @@ "description": "Operations about STP" }, { - "name": "RUN", - "description": "Execute SAS code" + "name": "CODE", + "description": "Operations on SAS code" } ], "yaml": true, From 2d77222ae8a139acd9d96466d0e68291c4ebd70e Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Tue, 28 Dec 2021 22:02:11 +0500 Subject: [PATCH 3/9] fix(studio): web component updated --- api/public/swagger.yaml | 72 ++++++++-------- api/src/routes/api/code.ts | 2 +- web/src/containers/Studio/index.tsx | 125 +++++++++++++++++----------- 3 files changed, 112 insertions(+), 87 deletions(-) diff --git a/api/public/swagger.yaml b/api/public/swagger.yaml index 83e67f2..18e34df 100644 --- a/api/public/swagger.yaml +++ b/api/public/swagger.yaml @@ -92,6 +92,16 @@ components: - clientSecret type: object additionalProperties: false + ExecuteSASCodePayload: + properties: + code: + type: string + description: 'Code of SAS program' + example: '* SAS Code HERE;' + required: + - code + type: object + additionalProperties: false MemberType.folder: enum: - folder @@ -358,16 +368,6 @@ components: - description type: object additionalProperties: false - RunSASPayload: - properties: - code: - type: string - description: 'Code of SAS program' - example: '* SAS Code HERE;' - required: - - code - type: object - additionalProperties: false ExecuteReturnJsonResponse: properties: status: @@ -511,6 +511,30 @@ paths: application/json: schema: $ref: '#/components/schemas/ClientPayload' + /SASjsApi/code/execute: + post: + operationId: ExecuteSASCode + responses: + '200': + description: Ok + content: + application/json: + schema: + type: string + description: 'Execute SAS code.' + summary: 'Run SAS Code and returns log' + tags: + - CODE + security: + - + bearerAuth: [] + parameters: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExecuteSASCodePayload' /SASjsApi/drive/deploy: post: operationId: Deploy @@ -982,30 +1006,6 @@ paths: format: double type: number example: '6789' - /SASjsApi/run/code: - post: - operationId: RunSAS - responses: - '200': - description: Ok - content: - application/json: - schema: - type: string - description: 'Trigger a SAS program.' - summary: 'Run SAS Program, return raw content' - tags: - - RUN - security: - - - bearerAuth: [] - parameters: [] - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/RunSASPayload' /SASjsApi/session: get: operationId: Session @@ -1107,5 +1107,5 @@ tags: name: STP description: 'Operations about STP' - - name: RUN - description: 'Execute SAS code' + name: CODE + description: 'Operations on SAS code' diff --git a/api/src/routes/api/code.ts b/api/src/routes/api/code.ts index ef4af95..fb751b5 100644 --- a/api/src/routes/api/code.ts +++ b/api/src/routes/api/code.ts @@ -6,7 +6,7 @@ const runRouter = express.Router() const controller = new CodeController() -runRouter.post('/code', async (req, res) => { +runRouter.post('/execute', async (req, res) => { const { error, value: body } = runSASValidation(req.body) if (error) return res.status(400).send(error.details[0].message) diff --git a/web/src/containers/Studio/index.tsx b/web/src/containers/Studio/index.tsx index 0e6d87a..bcb89d0 100644 --- a/web/src/containers/Studio/index.tsx +++ b/web/src/containers/Studio/index.tsx @@ -2,15 +2,32 @@ import React, { useEffect, useRef, useState } from 'react' import axios from 'axios' import Box from '@mui/material/Box' -import { Button, Paper, Stack, Toolbar } from '@mui/material' +import { Button, Paper, Stack, Tab, Toolbar } from '@mui/material' +import { makeStyles } from '@mui/styles' import Editor from '@monaco-editor/react' import { useLocation } from 'react-router-dom' +import { TabContext, TabList, TabPanel } from '@mui/lab' + +const useStyles = makeStyles(() => ({ + root: { + fontSize: '1rem', + color: 'gray', + '&.Mui-selected': { + color: 'black' + } + } +})) const Studio = () => { const location = useLocation() const [fileContent, setFileContent] = useState('') const [log, setLog] = useState('') + const [tab, setTab] = React.useState('1') + const handleTabChange = (_e: any, newValue: string) => { + setTab(newValue) + } + const editorRef = useRef(null) const handleEditorDidMount = (editor: any) => (editorRef.current = editor) @@ -26,15 +43,10 @@ const Studio = () => { const runCode = (code: string) => { axios - .post(`/SASjsApi/stp/run`, { code }) + .post(`/SASjsApi/code/execute`, { code }) .then((res: any) => { - const data = - typeof res.data === 'string' - ? res.data - : `
${JSON.stringify(res.data, null, 4)}
` - - setLog(data) - document?.getElementById('sas_log')?.scrollIntoView() + setLog(res.data) + setTab('2') }) .catch((err) => console.log(err)) } @@ -50,48 +62,61 @@ const Studio = () => { .catch((err) => console.log(err)) }, [location.search]) + const classes = useStyles() return ( - - - - { - if (val) setFileContent(val) - }} - /> - - - - - - {log && ( - <> -
-

Output

-
-
- - )} - + <> +
+
+
+ + + + + + + + + + {/* */} + + { + if (val) setFileContent(val) + }} + /> + + + + + + + +

Result

+
+
+ + + + ) } From f0ac996b3c0f3e82625b3af863f6f5ea56fde543 Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Tue, 28 Dec 2021 22:18:18 +0500 Subject: [PATCH 4/9] chore(web): build fix --- api/src/controllers/internal/Session.ts | 2 +- web/src/containers/Studio/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/controllers/internal/Session.ts b/api/src/controllers/internal/Session.ts index 38df221..e9bf581 100644 --- a/api/src/controllers/internal/Session.ts +++ b/api/src/controllers/internal/Session.ts @@ -110,7 +110,7 @@ export class SessionController { // TODO: don't wait forever while ((await fileExists(codeFilePath)) && !session.crashed) {} - console.log('session crashed?', !!session.crashed, session.crashed) + console.log('session crashed?', !!session.crashed, session.crashed || '') session.ready = true return Promise.resolve(session) diff --git a/web/src/containers/Studio/index.tsx b/web/src/containers/Studio/index.tsx index bcb89d0..b0326b5 100644 --- a/web/src/containers/Studio/index.tsx +++ b/web/src/containers/Studio/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from 'react' import axios from 'axios' import Box from '@mui/material/Box' -import { Button, Paper, Stack, Tab, Toolbar } from '@mui/material' +import { Button, Paper, Stack, Tab } from '@mui/material' import { makeStyles } from '@mui/styles' import Editor from '@monaco-editor/react' import { useLocation } from 'react-router-dom' From 679e9de245230b38e4ad52251793b9f65e2eb71b Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Wed, 29 Dec 2021 00:27:54 +0500 Subject: [PATCH 5/9] chore: return webout and log seperately --- api/src/controllers/code.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/src/controllers/code.ts b/api/src/controllers/code.ts index 6aa8c17..52e3266 100644 --- a/api/src/controllers/code.ts +++ b/api/src/controllers/code.ts @@ -33,7 +33,9 @@ const executeSASCode = async (req: any, { code }: ExecuteSASCodePayload) => { const result = await new ExecutionController().executeProgram( code, getPreProgramVariables(req), - { ...req.query, _debug: 131 } + { ...req.query, _debug: 131 }, + undefined, + true ) return result as string From f1f1e47f76e637e07656a07bbab9f6116e736872 Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Wed, 29 Dec 2021 01:00:53 +0500 Subject: [PATCH 6/9] chore(web): display webout as well --- web/src/containers/Studio/index.tsx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/web/src/containers/Studio/index.tsx b/web/src/containers/Studio/index.tsx index b0326b5..cdd7d64 100644 --- a/web/src/containers/Studio/index.tsx +++ b/web/src/containers/Studio/index.tsx @@ -22,6 +22,7 @@ const Studio = () => { const location = useLocation() const [fileContent, setFileContent] = useState('') const [log, setLog] = useState('') + const [webout, setWebout] = useState('') const [tab, setTab] = React.useState('1') const handleTabChange = (_e: any, newValue: string) => { @@ -45,7 +46,17 @@ const Studio = () => { axios .post(`/SASjsApi/code/execute`, { code }) .then((res: any) => { - setLog(res.data) + setLog(`

SAS Log

${res?.data?.log}
`) + + const webout = res?.data?.webout + ? JSON.parse( + res.data.webout + .split('>>weboutBEGIN<<')[1] + .split('>>weboutEND<<')[0] + ) + : '' + + setWebout(`
${JSON.stringify(webout, null, 4)}
`) setTab('2') }) .catch((err) => console.log(err)) @@ -74,6 +85,7 @@ const Studio = () => { + @@ -110,10 +122,11 @@ const Studio = () => { -

Result

-
+ +
+ From a1151606f21e0007e2b1ca1245d592d96866f62a Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Thu, 30 Dec 2021 12:18:48 +0500 Subject: [PATCH 7/9] fix(web): parsing of webout --- web/src/containers/Studio/index.tsx | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/web/src/containers/Studio/index.tsx b/web/src/containers/Studio/index.tsx index cdd7d64..d93defb 100644 --- a/web/src/containers/Studio/index.tsx +++ b/web/src/containers/Studio/index.tsx @@ -48,13 +48,21 @@ const Studio = () => { .then((res: any) => { setLog(`

SAS Log

${res?.data?.log}
`) - const webout = res?.data?.webout - ? JSON.parse( - res.data.webout - .split('>>weboutBEGIN<<')[1] - .split('>>weboutEND<<')[0] - ) - : '' + let weboutString: string + try { + weboutString = res.data.webout + .split('>>weboutBEGIN<<')[1] + .split('>>weboutEND<<')[0] + } catch (_) { + weboutString = res.data.webout + } + + let webout: any + try { + webout = JSON.parse(weboutString) + } catch (_) { + webout = weboutString + } setWebout(`
${JSON.stringify(webout, null, 4)}
`) setTab('2') From 51ee8c0825f021d1d67b2d765d5b434cbf248a1f Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Thu, 30 Dec 2021 12:56:23 +0500 Subject: [PATCH 8/9] fix(web): autosave and autofocus --- web/src/containers/Studio/index.tsx | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/web/src/containers/Studio/index.tsx b/web/src/containers/Studio/index.tsx index d93defb..23d6147 100644 --- a/web/src/containers/Studio/index.tsx +++ b/web/src/containers/Studio/index.tsx @@ -4,7 +4,7 @@ import axios from 'axios' import Box from '@mui/material/Box' import { Button, Paper, Stack, Tab } from '@mui/material' import { makeStyles } from '@mui/styles' -import Editor from '@monaco-editor/react' +import Editor, { OnMount } from '@monaco-editor/react' import { useLocation } from 'react-router-dom' import { TabContext, TabList, TabPanel } from '@mui/lab' @@ -23,14 +23,16 @@ const Studio = () => { const [fileContent, setFileContent] = useState('') const [log, setLog] = useState('') const [webout, setWebout] = useState('') - const [tab, setTab] = React.useState('1') const handleTabChange = (_e: any, newValue: string) => { setTab(newValue) } - const editorRef = useRef(null) - const handleEditorDidMount = (editor: any) => (editorRef.current = editor) + const editorRef = useRef(null as any) + const handleEditorDidMount: OnMount = (editor) => { + editor.focus() + editorRef.current = editor + } const getSelection = () => { const editor = editorRef.current as any @@ -54,22 +56,33 @@ const Studio = () => { .split('>>weboutBEGIN<<')[1] .split('>>weboutEND<<')[0] } catch (_) { - weboutString = res.data.webout + weboutString = res?.data?.webout ?? '' } - let webout: any + let webout: string try { - webout = JSON.parse(weboutString) + webout = JSON.stringify(JSON.parse(weboutString), null, 4) } catch (_) { webout = weboutString } - setWebout(`
${JSON.stringify(webout, null, 4)}
`) + setWebout(`
${webout}
`) setTab('2') }) .catch((err) => console.log(err)) } + useEffect(() => { + const content = localStorage.getItem('fileContent') ?? '' + setFileContent(content) + }, []) + + useEffect(() => { + if (fileContent.length) { + localStorage.setItem('fileContent', fileContent) + } + }, [fileContent]) + useEffect(() => { const params = new URLSearchParams(location.search) const programPath = params.get('_program') From 450d99f06e5929eb1679e6203284e4faa44e19b0 Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Wed, 5 Jan 2022 17:41:17 +0500 Subject: [PATCH 9/9] fix(web): sticky tabs on Studio + extra run code button removed --- web/src/containers/Studio/index.tsx | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/web/src/containers/Studio/index.tsx b/web/src/containers/Studio/index.tsx index 23d6147..7174d2e 100644 --- a/web/src/containers/Studio/index.tsx +++ b/web/src/containers/Studio/index.tsx @@ -40,9 +40,7 @@ const Studio = () => { return selection ?? '' } - const handleRunSelectionBtnClick = () => runCode(getSelection()) - - const handleRunBtnClick = () => runCode(fileContent) + const handleRunBtnClick = () => runCode(getSelection() || fileContent) const runCode = (code: string) => { axios @@ -102,7 +100,13 @@ const Studio = () => {
- + @@ -114,6 +118,7 @@ const Studio = () => { { - -
+
-
+