1
0
mirror of https://github.com/sasjs/server.git synced 2026-01-16 02:10:05 +00:00

Merge pull request #122 from sasjs/issue121

Fixed couple of bugs + feature implemented
This commit is contained in:
Allan Bowe
2022-04-07 18:23:34 +03:00
committed by GitHub
8 changed files with 155 additions and 93 deletions

BIN
api/public/plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

View File

@@ -12,8 +12,7 @@ import {
createFile, createFile,
fileExists, fileExists,
generateTimestamp, generateTimestamp,
readFile, readFile
moveFile
} from '@sasjs/utils' } from '@sasjs/utils'
const execFilePromise = promisify(execFile) const execFilePromise = promisify(execFile)
@@ -41,6 +40,7 @@ export class SessionController {
const sessionFolder = path.join(getTmpSessionsFolderPath(), sessionId) const sessionFolder = path.join(getTmpSessionsFolderPath(), sessionId)
const creationTimeStamp = sessionId.split('-').pop() as string const creationTimeStamp = sessionId.split('-').pop() as string
// death time of session is 15 mins from creation
const deathTimeStamp = ( const deathTimeStamp = (
parseInt(creationTimeStamp) + parseInt(creationTimeStamp) +
15 * 60 * 1000 - 15 * 60 * 1000 -
@@ -140,7 +140,9 @@ ${autoExecContent}`
private scheduleSessionDestroy(session: Session) { private scheduleSessionDestroy(session: Session) {
setTimeout(async () => { setTimeout(async () => {
if (session.inUse) { if (session.inUse) {
session.deathTimeStamp = session.deathTimeStamp + 1000 * 10 // adding 10 more minutes
const newDeathTimeStamp = parseInt(session.deathTimeStamp) + 10 * 1000
session.deathTimeStamp = newDeathTimeStamp.toString()
this.scheduleSessionDestroy(session) this.scheduleSessionDestroy(session)
} else { } else {

View File

@@ -1,27 +1,6 @@
import { AppStreamConfig } from '../../types' import { AppStreamConfig } from '../../types'
import { script } from './script'
const style = `<style> import { style } from './style'
* {
font-family: 'Roboto', sans-serif;
}
.app-container {
display: flex;
flex-wrap: wrap;
align-items: baseline;
justify-content: center;
}
.app-container .app {
width: 150px;
margin: 10px;
overflow: hidden;
text-align: center;
}
.app-container .app img{
width: 100%;
margin-bottom: 10px;
border-radius: 10px;
}
</style>`
const defaultAppLogo = '/sasjs-logo.svg' const defaultAppLogo = '/sasjs-logo.svg'
@@ -52,6 +31,14 @@ export const appStreamHtml = (appStreamConfig: AppStreamConfig) => `
singleAppStreamHtml(streamServiceName, entry.appLoc, entry.streamLogo) singleAppStreamHtml(streamServiceName, entry.appLoc, entry.streamLogo)
) )
.join('')} .join('')}
<a class="app" title="Upload build.json">
<input id="fileId" type="file" hidden />
<button id="uploadButton" style="margin-bottom: 5px; cursor: pointer">
<img src="/plus.png" />
</button>
<span id="uploadMessage">Upload New App</span>
</a>
</div> </div>
${script}
</body> </body>
</html>` </html>`

View File

@@ -0,0 +1,58 @@
export const script = `<script>
const inputElement = document.getElementById('fileId')
document
.getElementById('uploadButton')
.addEventListener('click', function () {
inputElement.click()
})
inputElement.addEventListener(
'change',
function () {
const fileList = this.files /* now you can work with the file list */
updateFileUploadMessage('Requesting ...')
const file = fileList[0]
const formData = new FormData()
formData.append('file', file)
fetch('/SASjsApi/drive/deploy/upload', {
method: 'POST',
body: formData
})
.then(async (res) => {
const { status, ok } = res
if (status === 200 && ok) {
const data = await res.json()
return (
data.message +
'\\nstreamServiceName: ' +
data.streamServiceName +
'\\nrefreshing page once alert box closes.'
)
}
throw await res.text()
})
.then((message) => {
alert(message)
location.reload()
})
.catch((error) => {
alert(error)
resetFileUpload()
updateFileUploadMessage('Upload New App')
})
},
false
)
function updateFileUploadMessage(message) {
document.getElementById('uploadMessage').innerHTML = message
}
function resetFileUpload() {
inputElement.value = null
}
</script>`

View File

@@ -0,0 +1,22 @@
export const style = `<style>
* {
font-family: 'Roboto', sans-serif;
}
.app-container {
display: flex;
flex-wrap: wrap;
align-items: baseline;
justify-content: center;
}
.app-container .app {
width: 150px;
margin: 10px;
overflow: hidden;
text-align: center;
}
.app-container .app img{
width: 100%;
margin-bottom: 10px;
border-radius: 10px;
}
</style>`

View File

@@ -14,7 +14,6 @@ export * from './removeTokensInDB'
export * from './saveTokensInDB' export * from './saveTokensInDB'
export * from './setProcessVariables' export * from './setProcessVariables'
export * from './setupFolders' export * from './setupFolders'
export * from './sleep'
export * from './upload' export * from './upload'
export * from './validation' export * from './validation'
export * from './verifyTokenInDB' export * from './verifyTokenInDB'

View File

@@ -1,3 +0,0 @@
export const sleep = async (delay: number) => {
await new Promise((resolve) => setTimeout(resolve, delay))
}

View File

@@ -2,7 +2,7 @@ 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, Tab } from '@mui/material' import { Button, Paper, Stack, Tab, Tooltip } from '@mui/material'
import { makeStyles } from '@mui/styles' import { makeStyles } from '@mui/styles'
import Editor, { OnMount } from '@monaco-editor/react' import Editor, { OnMount } from '@monaco-editor/react'
import { useLocation } from 'react-router-dom' import { useLocation } from 'react-router-dom'
@@ -86,70 +86,67 @@ const Studio = () => {
const classes = useStyles() const classes = useStyles()
return ( return (
<> <Box sx={{ width: '100%', typography: 'body1', marginTop: '50px' }}>
<br /> <TabContext value={tab}>
<br /> <Box
<br /> sx={{
<Box sx={{ width: '100%', typography: 'body1' }}> borderBottom: 1,
<TabContext value={tab}> borderColor: 'divider'
<Box }}
sx={{ style={{ position: 'fixed', background: 'white', width: '100%' }}
borderBottom: 1, >
borderColor: 'divider' <TabList onChange={handleTabChange} centered>
}} <Tab className={classes.root} label="Code" value="1" />
style={{ position: 'fixed', background: 'white', width: '100%' }} <Tab className={classes.root} label="Log" value="2" />
> <Tooltip title="Displays content from the _webout fileref">
<TabList onChange={handleTabChange} centered>
<Tab className={classes.root} label="Code" value="1" />
<Tab className={classes.root} label="Log" value="2" />
<Tab className={classes.root} label="Webout" value="3" /> <Tab className={classes.root} label="Webout" value="3" />
</TabList> </Tooltip>
</Box> </TabList>
<TabPanel value="1"> </Box>
{/* <Toolbar /> */} <TabPanel value="1">
<Paper {/* <Toolbar /> */}
sx={{ <Paper
height: '70vh', sx={{
marginTop: '50px', height: '70vh',
padding: '10px', marginTop: '50px',
overflow: 'auto', padding: '10px',
position: 'relative' overflow: 'auto',
position: 'relative'
}}
elevation={3}
>
<Editor
height="95%"
value={fileContent}
onMount={handleEditorDidMount}
onChange={(val) => {
if (val) setFileContent(val)
}} }}
elevation={3} />
> </Paper>
<Editor <Stack
height="95%" spacing={3}
value={fileContent} direction="row"
onMount={handleEditorDidMount} sx={{ justifyContent: 'center', marginTop: '20px' }}
onChange={(val) => { >
if (val) setFileContent(val) <Button variant="contained" onClick={handleRunBtnClick}>
}} Run SAS Code
/> </Button>
</Paper> </Stack>
<Stack </TabPanel>
spacing={3} <TabPanel value="2">
direction="row" <div style={{ marginTop: '50px' }}>
sx={{ justifyContent: 'center', marginTop: '20px' }} <h2>SAS Log</h2>
> <pre>{log}</pre>
<Button variant="contained" onClick={handleRunBtnClick}> </div>
Run SAS Code </TabPanel>
</Button> <TabPanel value="3">
</Stack> <div style={{ marginTop: '50px' }}>
</TabPanel> <pre>{webout}</pre>
<TabPanel value="2"> </div>
<div style={{ marginTop: '50px' }}> </TabPanel>
<h2>SAS Log</h2> </TabContext>
<pre>{log}</pre> </Box>
</div>
</TabPanel>
<TabPanel value="3">
<div style={{ marginTop: '50px' }}>
<pre>{webout}</pre>
</div>
</TabPanel>
</TabContext>
</Box>
</>
) )
} }