diff --git a/api/package.json b/api/package.json index d23cfba..346bb49 100644 --- a/api/package.json +++ b/api/package.json @@ -88,5 +88,10 @@ }, "configuration": { "sasPath": "/opt/sas/sas9/SASHome/SASFoundation/9.4/sas" + }, + "nodemonConfig": { + "ignore": [ + "tmp/appStreamConfig.json" + ] } } diff --git a/api/public/swagger.yaml b/api/public/swagger.yaml index b7c04c0..5aaa786 100644 --- a/api/public/swagger.yaml +++ b/api/public/swagger.yaml @@ -214,6 +214,8 @@ components: type: string message: type: string + streamServiceName: + type: string example: $ref: '#/components/schemas/FileTree' required: diff --git a/api/src/controllers/drive.ts b/api/src/controllers/drive.ts index ca055a3..1b11684 100644 --- a/api/src/controllers/drive.ts +++ b/api/src/controllers/drive.ts @@ -36,6 +36,7 @@ interface DeployPayload { interface DeployResponse { status: string message: string + streamServiceName?: string example?: FileTree } diff --git a/api/src/routes/api/drive.ts b/api/src/routes/api/drive.ts index 1e5e7e4..bd6af29 100644 --- a/api/src/routes/api/drive.ts +++ b/api/src/routes/api/drive.ts @@ -22,12 +22,15 @@ driveRouter.post('/deploy', async (req, res) => { try { const response = await controller.deploy(body) - if (body.streamWebFolder) - publishAppStream( + if (body.streamWebFolder) { + const { streamServiceName } = await publishAppStream( body.appLoc, body.streamWebFolder, - body.streamServiceName + body.streamServiceName, + body.streamLogo ) + response.streamServiceName = streamServiceName + } res.send(response) } catch (err: any) { diff --git a/api/src/routes/appStream/appStreamHtml.ts b/api/src/routes/appStream/appStreamHtml.ts index e15994d..70f7d59 100644 --- a/api/src/routes/appStream/appStreamHtml.ts +++ b/api/src/routes/appStream/appStreamHtml.ts @@ -17,13 +17,20 @@ const style = `` const defaultAppLogo = '/sasjs-logo.svg' -const singleAppStreamHtml = (streamServiceName: string, logo?: string) => - ` - +const singleAppStreamHtml = ( + streamServiceName: string, + appLoc: string, + logo?: string +) => + ` + ${streamServiceName} ` @@ -36,12 +43,11 @@ export const appStreamHtml = (appStreamConfig: AppStreamConfig) => `

App Stream

- ${Object.entries(appStreamConfig).map(([streamServiceName, entry]) => - singleAppStreamHtml(streamServiceName, entry.logo) - )} - App Name here - App Name here - App Name here + ${Object.entries(appStreamConfig) + .map(([streamServiceName, entry]) => + singleAppStreamHtml(streamServiceName, entry.appLoc, entry.streamLogo) + ) + .join('')}
` diff --git a/api/src/routes/appStream/index.ts b/api/src/routes/appStream/index.ts index ee9dcd1..793efbd 100644 --- a/api/src/routes/appStream/index.ts +++ b/api/src/routes/appStream/index.ts @@ -17,6 +17,7 @@ export const publishAppStream = async ( appLoc: string, streamWebFolder: string, streamServiceName?: string, + streamLogo?: string, addEntryToFile: boolean = true ) => { const driveFilesPath = getTmpFilesFolderPath() @@ -37,8 +38,19 @@ export const publishAppStream = async ( ? Object.keys(process.appStreamConfig).length : 0 - if (!streamServiceName || process.appStreamConfig[streamServiceName]) { + if (!streamServiceName) { 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)) @@ -47,7 +59,7 @@ export const publishAppStream = async ( streamServiceName, appLoc, streamWebFolder, - undefined, + streamLogo, addEntryToFile ) @@ -56,7 +68,9 @@ export const publishAppStream = async ( 'Serving Stream App: ', `http://localhost:${sasJsPort}/AppStream/${streamServiceName}` ) + return { streamServiceName } } + return {} } export default router diff --git a/api/src/types/AppStreamConfig.ts b/api/src/types/AppStreamConfig.ts index 3b41633..8907634 100644 --- a/api/src/types/AppStreamConfig.ts +++ b/api/src/types/AppStreamConfig.ts @@ -2,6 +2,6 @@ export interface AppStreamConfig { [key: string]: { appLoc: string streamWebFolder: string - logo?: string + streamLogo?: string } } diff --git a/api/src/utils/appStreamConfig.ts b/api/src/utils/appStreamConfig.ts index 4558953..39c02af 100644 --- a/api/src/utils/appStreamConfig.ts +++ b/api/src/utils/appStreamConfig.ts @@ -22,9 +22,15 @@ export const loadAppStreamConfig = async () => { process.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!') @@ -34,14 +40,14 @@ export const addEntryToAppStreamConfig = ( streamServiceName: string, appLoc: string, streamWebFolder: string, - logo?: string, + streamLogo?: string, addEntryToFile: boolean = true ) => { if (streamServiceName && appLoc && streamWebFolder) { process.appStreamConfig[streamServiceName] = { appLoc, streamWebFolder, - logo + streamLogo } if (addEntryToFile) saveAppStreamConfig() } @@ -68,7 +74,7 @@ const saveAppStreamConfig = async () => { const isValidAppStreamConfig = (config: any) => { if (config) { return !Object.entries(config).some(([streamServiceName, entry]) => { - const { appLoc, streamWebFolder, logo } = entry as any + const { appLoc, streamWebFolder, streamLogo } = entry as any return ( typeof streamServiceName !== 'string' || diff --git a/api/src/utils/validation.ts b/api/src/utils/validation.ts index 45ae5fb..c33fcbe 100644 --- a/api/src/utils/validation.ts +++ b/api/src/utils/validation.ts @@ -73,6 +73,7 @@ export const deployValidation = (data: any): Joi.ValidationResult => appLoc: Joi.string().pattern(/^\//).required().min(2), streamServiceName: Joi.string(), streamWebFolder: Joi.string(), + streamLogo: Joi.string(), fileTree: Joi.any().required() }).validate(data) diff --git a/web/src/components/header.tsx b/web/src/components/header.tsx index 9efefa2..d536b7e 100644 --- a/web/src/components/header.tsx +++ b/web/src/components/header.tsx @@ -66,11 +66,21 @@ const Header = (props: any) => { variant="contained" color="primary" size="large" - startIcon={} - style={{ marginLeft: '50px' }} + endIcon={} > API Docs + )