mirror of
https://github.com/sasjs/server.git
synced 2026-01-14 17:30:05 +00:00
fix(studio): web component updated
This commit is contained in:
@@ -92,6 +92,16 @@ components:
|
|||||||
- clientSecret
|
- clientSecret
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
ExecuteSASCodePayload:
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
description: 'Code of SAS program'
|
||||||
|
example: '* SAS Code HERE;'
|
||||||
|
required:
|
||||||
|
- code
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
MemberType.folder:
|
MemberType.folder:
|
||||||
enum:
|
enum:
|
||||||
- folder
|
- folder
|
||||||
@@ -358,16 +368,6 @@ components:
|
|||||||
- description
|
- description
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
RunSASPayload:
|
|
||||||
properties:
|
|
||||||
code:
|
|
||||||
type: string
|
|
||||||
description: 'Code of SAS program'
|
|
||||||
example: '* SAS Code HERE;'
|
|
||||||
required:
|
|
||||||
- code
|
|
||||||
type: object
|
|
||||||
additionalProperties: false
|
|
||||||
ExecuteReturnJsonResponse:
|
ExecuteReturnJsonResponse:
|
||||||
properties:
|
properties:
|
||||||
status:
|
status:
|
||||||
@@ -511,6 +511,30 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/ClientPayload'
|
$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:
|
/SASjsApi/drive/deploy:
|
||||||
post:
|
post:
|
||||||
operationId: Deploy
|
operationId: Deploy
|
||||||
@@ -982,30 +1006,6 @@ paths:
|
|||||||
format: double
|
format: double
|
||||||
type: number
|
type: number
|
||||||
example: '6789'
|
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:
|
/SASjsApi/session:
|
||||||
get:
|
get:
|
||||||
operationId: Session
|
operationId: Session
|
||||||
@@ -1107,5 +1107,5 @@ tags:
|
|||||||
name: STP
|
name: STP
|
||||||
description: 'Operations about STP'
|
description: 'Operations about STP'
|
||||||
-
|
-
|
||||||
name: RUN
|
name: CODE
|
||||||
description: 'Execute SAS code'
|
description: 'Operations on SAS code'
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const runRouter = express.Router()
|
|||||||
|
|
||||||
const controller = new CodeController()
|
const controller = new CodeController()
|
||||||
|
|
||||||
runRouter.post('/code', async (req, res) => {
|
runRouter.post('/execute', async (req, res) => {
|
||||||
const { error, value: body } = runSASValidation(req.body)
|
const { error, value: body } = runSASValidation(req.body)
|
||||||
if (error) return res.status(400).send(error.details[0].message)
|
if (error) return res.status(400).send(error.details[0].message)
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,32 @@ import React, { useEffect, useRef, useState } from 'react'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import Box from '@mui/material/Box'
|
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 Editor from '@monaco-editor/react'
|
||||||
import { useLocation } from 'react-router-dom'
|
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 Studio = () => {
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const [fileContent, setFileContent] = useState('')
|
const [fileContent, setFileContent] = useState('')
|
||||||
const [log, setLog] = useState('')
|
const [log, setLog] = useState('')
|
||||||
|
|
||||||
|
const [tab, setTab] = React.useState('1')
|
||||||
|
const handleTabChange = (_e: any, newValue: string) => {
|
||||||
|
setTab(newValue)
|
||||||
|
}
|
||||||
|
|
||||||
const editorRef = useRef(null)
|
const editorRef = useRef(null)
|
||||||
const handleEditorDidMount = (editor: any) => (editorRef.current = editor)
|
const handleEditorDidMount = (editor: any) => (editorRef.current = editor)
|
||||||
|
|
||||||
@@ -26,15 +43,10 @@ const Studio = () => {
|
|||||||
|
|
||||||
const runCode = (code: string) => {
|
const runCode = (code: string) => {
|
||||||
axios
|
axios
|
||||||
.post(`/SASjsApi/stp/run`, { code })
|
.post(`/SASjsApi/code/execute`, { code })
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
const data =
|
setLog(res.data)
|
||||||
typeof res.data === 'string'
|
setTab('2')
|
||||||
? res.data
|
|
||||||
: `<pre><code>${JSON.stringify(res.data, null, 4)}</code></pre>`
|
|
||||||
|
|
||||||
setLog(data)
|
|
||||||
document?.getElementById('sas_log')?.scrollIntoView()
|
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err))
|
.catch((err) => console.log(err))
|
||||||
}
|
}
|
||||||
@@ -50,48 +62,61 @@ const Studio = () => {
|
|||||||
.catch((err) => console.log(err))
|
.catch((err) => console.log(err))
|
||||||
}, [location.search])
|
}, [location.search])
|
||||||
|
|
||||||
|
const classes = useStyles()
|
||||||
return (
|
return (
|
||||||
<Box component="main" sx={{ flexGrow: 1, p: 3 }}>
|
<>
|
||||||
<Toolbar />
|
<br />
|
||||||
<Paper
|
<br />
|
||||||
sx={{
|
<br />
|
||||||
height: '75vh',
|
<Box sx={{ width: '100%', typography: 'body1' }}>
|
||||||
padding: '10px',
|
<TabContext value={tab}>
|
||||||
overflow: 'auto',
|
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||||||
position: 'relative'
|
<TabList onChange={handleTabChange} centered>
|
||||||
}}
|
<Tab className={classes.root} label="Code" value="1" />
|
||||||
elevation={3}
|
<Tab className={classes.root} label="Log" value="2" />
|
||||||
>
|
</TabList>
|
||||||
<Editor
|
</Box>
|
||||||
height="95%"
|
<TabPanel value="1">
|
||||||
value={fileContent}
|
{/* <Toolbar /> */}
|
||||||
onMount={handleEditorDidMount}
|
<Paper
|
||||||
onChange={(val) => {
|
sx={{
|
||||||
if (val) setFileContent(val)
|
height: '70vh',
|
||||||
}}
|
padding: '10px',
|
||||||
/>
|
overflow: 'auto',
|
||||||
</Paper>
|
position: 'relative'
|
||||||
<Stack
|
}}
|
||||||
spacing={3}
|
elevation={3}
|
||||||
direction="row"
|
>
|
||||||
sx={{ justifyContent: 'center', marginTop: '20px' }}
|
<Editor
|
||||||
>
|
height="95%"
|
||||||
<Button variant="contained" onClick={handleRunBtnClick}>
|
value={fileContent}
|
||||||
Run SAS Code
|
onMount={handleEditorDidMount}
|
||||||
</Button>
|
onChange={(val) => {
|
||||||
<Button variant="contained" onClick={handleRunSelectionBtnClick}>
|
if (val) setFileContent(val)
|
||||||
Run Selected SAS Code
|
}}
|
||||||
</Button>
|
/>
|
||||||
</Stack>
|
</Paper>
|
||||||
{log && (
|
<Stack
|
||||||
<>
|
spacing={3}
|
||||||
<br />
|
direction="row"
|
||||||
<h2 id="sas_log">Output</h2>
|
sx={{ justifyContent: 'center', marginTop: '20px' }}
|
||||||
<br />
|
>
|
||||||
<div dangerouslySetInnerHTML={{ __html: log }} />
|
<Button variant="contained" onClick={handleRunBtnClick}>
|
||||||
</>
|
Run SAS Code
|
||||||
)}
|
</Button>
|
||||||
</Box>
|
<Button variant="contained" onClick={handleRunSelectionBtnClick}>
|
||||||
|
Run Selected SAS Code
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel value="2">
|
||||||
|
<h2>Result</h2>
|
||||||
|
<br />
|
||||||
|
<div dangerouslySetInnerHTML={{ __html: log }} />
|
||||||
|
</TabPanel>
|
||||||
|
</TabContext>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user