1
0
mirror of https://github.com/sasjs/server.git synced 2025-12-11 03:34:35 +00:00

fix(appstream): app logo + improvements

This commit is contained in:
Saad Jutt
2022-03-22 03:55:51 +05:00
parent 98a00ec7ac
commit df6003df94
10 changed files with 70 additions and 22 deletions

View File

@@ -88,5 +88,10 @@
}, },
"configuration": { "configuration": {
"sasPath": "/opt/sas/sas9/SASHome/SASFoundation/9.4/sas" "sasPath": "/opt/sas/sas9/SASHome/SASFoundation/9.4/sas"
},
"nodemonConfig": {
"ignore": [
"tmp/appStreamConfig.json"
]
} }
} }

View File

@@ -214,6 +214,8 @@ components:
type: string type: string
message: message:
type: string type: string
streamServiceName:
type: string
example: example:
$ref: '#/components/schemas/FileTree' $ref: '#/components/schemas/FileTree'
required: required:

View File

@@ -36,6 +36,7 @@ interface DeployPayload {
interface DeployResponse { interface DeployResponse {
status: string status: string
message: string message: string
streamServiceName?: string
example?: FileTree example?: FileTree
} }

View File

@@ -22,12 +22,15 @@ driveRouter.post('/deploy', async (req, res) => {
try { try {
const response = await controller.deploy(body) const response = await controller.deploy(body)
if (body.streamWebFolder) if (body.streamWebFolder) {
publishAppStream( const { streamServiceName } = await publishAppStream(
body.appLoc, body.appLoc,
body.streamWebFolder, body.streamWebFolder,
body.streamServiceName body.streamServiceName,
body.streamLogo
) )
response.streamServiceName = streamServiceName
}
res.send(response) res.send(response)
} catch (err: any) { } catch (err: any) {

View File

@@ -17,13 +17,20 @@ const style = `<style>
border-radius: 10px 10px 0 0; border-radius: 10px 10px 0 0;
text-align: center; text-align: center;
} }
.app-container .app img{
width: 100%;
}
</style>` </style>`
const defaultAppLogo = '/sasjs-logo.svg' const defaultAppLogo = '/sasjs-logo.svg'
const singleAppStreamHtml = (streamServiceName: string, logo?: string) => const singleAppStreamHtml = (
` <a class="app" href="${streamServiceName}"> streamServiceName: string,
<img src="${logo ?? defaultAppLogo}" /> appLoc: string,
logo?: string
) =>
` <a class="app" href="${streamServiceName}" title="${appLoc}">
<img src="${logo ? streamServiceName + '/' + logo : defaultAppLogo}" />
${streamServiceName} ${streamServiceName}
</a>` </a>`
@@ -36,12 +43,11 @@ export const appStreamHtml = (appStreamConfig: AppStreamConfig) => `
<body> <body>
<h1>App Stream</h1> <h1>App Stream</h1>
<div class="app-container"> <div class="app-container">
${Object.entries(appStreamConfig).map(([streamServiceName, entry]) => ${Object.entries(appStreamConfig)
singleAppStreamHtml(streamServiceName, entry.logo) .map(([streamServiceName, entry]) =>
)} singleAppStreamHtml(streamServiceName, entry.appLoc, entry.streamLogo)
<a class="app" href="#"><img src="/sasjs-logo.svg" />App Name here</a> )
<a class="app" href="#"><img src="/sasjs-logo.svg" />App Name here</a> .join('')}
<a class="app" href="#"><img src="/sasjs-logo.svg" />App Name here</a>
</div> </div>
</body> </body>
</html>` </html>`

View File

@@ -17,6 +17,7 @@ export const publishAppStream = async (
appLoc: string, appLoc: string,
streamWebFolder: string, streamWebFolder: string,
streamServiceName?: string, streamServiceName?: string,
streamLogo?: string,
addEntryToFile: boolean = true addEntryToFile: boolean = true
) => { ) => {
const driveFilesPath = getTmpFilesFolderPath() const driveFilesPath = getTmpFilesFolderPath()
@@ -37,8 +38,19 @@ export const publishAppStream = async (
? Object.keys(process.appStreamConfig).length ? Object.keys(process.appStreamConfig).length
: 0 : 0
if (!streamServiceName || process.appStreamConfig[streamServiceName]) { if (!streamServiceName) {
streamServiceName = `AppStreamName${appCount + 1}` streamServiceName = `AppStreamName${appCount + 1}`
} else {
const alreadyDeployed = process.appStreamConfig[streamServiceName]
if (alreadyDeployed) {
if (alreadyDeployed.appLoc === appLoc) {
// redeploying to same streamServiceName
} else {
// trying to deploy to another existing streamServiceName
// assign new streamServiceName
streamServiceName = `${streamServiceName}-${appCount + 1}`
}
}
} }
router.use(`/${streamServiceName}`, express.static(pathToDeployment)) router.use(`/${streamServiceName}`, express.static(pathToDeployment))
@@ -47,7 +59,7 @@ export const publishAppStream = async (
streamServiceName, streamServiceName,
appLoc, appLoc,
streamWebFolder, streamWebFolder,
undefined, streamLogo,
addEntryToFile addEntryToFile
) )
@@ -56,7 +68,9 @@ export const publishAppStream = async (
'Serving Stream App: ', 'Serving Stream App: ',
`http://localhost:${sasJsPort}/AppStream/${streamServiceName}` `http://localhost:${sasJsPort}/AppStream/${streamServiceName}`
) )
return { streamServiceName }
} }
return {}
} }
export default router export default router

View File

@@ -2,6 +2,6 @@ export interface AppStreamConfig {
[key: string]: { [key: string]: {
appLoc: string appLoc: string
streamWebFolder: string streamWebFolder: string
logo?: string streamLogo?: string
} }
} }

View File

@@ -22,9 +22,15 @@ export const loadAppStreamConfig = async () => {
process.appStreamConfig = {} process.appStreamConfig = {}
for (const [streamServiceName, entry] of Object.entries(appStreamConfig)) { for (const [streamServiceName, entry] of Object.entries(appStreamConfig)) {
const { appLoc, streamWebFolder } = entry const { appLoc, streamWebFolder, streamLogo } = entry
publishAppStream(appLoc, streamWebFolder, streamServiceName, false) publishAppStream(
appLoc,
streamWebFolder,
streamServiceName,
streamLogo,
false
)
} }
console.log('App Stream Config loaded!') console.log('App Stream Config loaded!')
@@ -34,14 +40,14 @@ export const addEntryToAppStreamConfig = (
streamServiceName: string, streamServiceName: string,
appLoc: string, appLoc: string,
streamWebFolder: string, streamWebFolder: string,
logo?: string, streamLogo?: string,
addEntryToFile: boolean = true addEntryToFile: boolean = true
) => { ) => {
if (streamServiceName && appLoc && streamWebFolder) { if (streamServiceName && appLoc && streamWebFolder) {
process.appStreamConfig[streamServiceName] = { process.appStreamConfig[streamServiceName] = {
appLoc, appLoc,
streamWebFolder, streamWebFolder,
logo streamLogo
} }
if (addEntryToFile) saveAppStreamConfig() if (addEntryToFile) saveAppStreamConfig()
} }
@@ -68,7 +74,7 @@ const saveAppStreamConfig = async () => {
const isValidAppStreamConfig = (config: any) => { const isValidAppStreamConfig = (config: any) => {
if (config) { if (config) {
return !Object.entries(config).some(([streamServiceName, entry]) => { return !Object.entries(config).some(([streamServiceName, entry]) => {
const { appLoc, streamWebFolder, logo } = entry as any const { appLoc, streamWebFolder, streamLogo } = entry as any
return ( return (
typeof streamServiceName !== 'string' || typeof streamServiceName !== 'string' ||

View File

@@ -73,6 +73,7 @@ export const deployValidation = (data: any): Joi.ValidationResult =>
appLoc: Joi.string().pattern(/^\//).required().min(2), appLoc: Joi.string().pattern(/^\//).required().min(2),
streamServiceName: Joi.string(), streamServiceName: Joi.string(),
streamWebFolder: Joi.string(), streamWebFolder: Joi.string(),
streamLogo: Joi.string(),
fileTree: Joi.any().required() fileTree: Joi.any().required()
}).validate(data) }).validate(data)

View File

@@ -66,11 +66,21 @@ const Header = (props: any) => {
variant="contained" variant="contained"
color="primary" color="primary"
size="large" size="large"
startIcon={<OpenInNewIcon />} endIcon={<OpenInNewIcon />}
style={{ marginLeft: '50px' }}
> >
API Docs API Docs
</Button> </Button>
<Button
href={`${baseUrl}/AppStream`}
target="_blank"
rel="noreferrer"
variant="contained"
color="primary"
size="large"
endIcon={<OpenInNewIcon />}
>
App Stream
</Button>
</Toolbar> </Toolbar>
</AppBar> </AppBar>
) )