Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
a61e2de140 | |||
881d2b060e | |||
4830c6d219 | |||
4c3c9ac88c | |||
7e1c610a4d | |||
8139f495ce | |||
89ab296151 | |||
a0dc92c403 | |||
86134f478a | |||
9a2addc18e | |||
9264ce2a60 | |||
cbd69df708 | |||
ca7caa25b6 | |||
c10330627f | |||
d80c59afce | |||
abdbb67471 | |||
037a97b6ff | |||
a0a529ad38 | |||
72239558af | |||
d2097ad6dd | |||
1bd542cddb | |||
fb1c1ee874 | |||
624a7a8f37 |
@ -237,12 +237,12 @@ jobs:
|
|||||||
cd sas
|
cd sas
|
||||||
sasjs c -t viya
|
sasjs c -t viya
|
||||||
rm -rf sasjsbuild/tests
|
rm -rf sasjsbuild/tests
|
||||||
sed -i -e 's/servertype="SASJS"/servertype="SASVIYA"/g' sasjsbuild/services/clickme.html
|
sed -i -e 's/servertype="SASJS"/servertype="SASVIYA"/g' sasjsbuild/services/DC.html
|
||||||
sasjs b -t viya
|
sasjs b -t viya
|
||||||
cp sasjsbuild/viya.sas ./viya.sas
|
cp sasjsbuild/viya.sas ./viya.sas
|
||||||
# compile Viya Full deploy (without web)
|
# compile Viya Full deploy (without web)
|
||||||
rm -rf sasjsbuild/services/web
|
rm -rf sasjsbuild/services/web
|
||||||
rm sasjsbuild/services/clickme.html
|
rm sasjsbuild/services/DC.html
|
||||||
sasjs b -t viya
|
sasjs b -t viya
|
||||||
cp sasjsbuild/viya.sas ./viya_noweb.sas
|
cp sasjsbuild/viya.sas ./viya_noweb.sas
|
||||||
cp sasjsbuild/viya.json ./viya_noweb.json
|
cp sasjsbuild/viya.json ./viya_noweb.json
|
||||||
|
37
CHANGELOG.md
37
CHANGELOG.md
@ -1,3 +1,40 @@
|
|||||||
|
## [6.16.2](https://git.datacontroller.io/dc/dc/compare/v6.16.1...v6.16.2) (2025-06-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* streaming viya deploy `isStreaming` function stability fix ([4830c6d](https://git.datacontroller.io/dc/dc/commit/4830c6d2191cb47abcc7919bc1d49e55595e6121))
|
||||||
|
|
||||||
|
## [6.16.1](https://git.datacontroller.io/dc/dc/compare/v6.16.0...v6.16.1) (2025-06-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* viya deploy updating index html based on URL ([86134f4](https://git.datacontroller.io/dc/dc/commit/86134f478ae0b9426e01bfcc9ca4ee597ca733f7))
|
||||||
|
* viya streamed app deploy page flow fix ([89ab296](https://git.datacontroller.io/dc/dc/commit/89ab2961513b245eeea48d1867c6496d3261761e))
|
||||||
|
|
||||||
|
# [6.16.0](https://git.datacontroller.io/dc/dc/compare/v6.15.2...v6.16.0) (2025-06-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* adapter bump ([ca7caa2](https://git.datacontroller.io/dc/dc/commit/ca7caa25b6eea1bd4579fb8b67ec9b211a893079))
|
||||||
|
* automatic viya deploy timing issue ([037a97b](https://git.datacontroller.io/dc/dc/commit/037a97b6ffa27b40891531ae6812ebe5b5e71e34))
|
||||||
|
* bump core to ensure ff works on viya streaming deploy ([cbd69df](https://git.datacontroller.io/dc/dc/commit/cbd69df708edf3a8446115ca7315fac3557dcf97)), closes [#156](https://git.datacontroller.io/dc/dc/issues/156)
|
||||||
|
* viya deploy load data timing ([abdbb67](https://git.datacontroller.io/dc/dc/commit/abdbb674713796e5308eb4272197a5c253868a85))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* viya deploy, update the index.html contextname ([7223955](https://git.datacontroller.io/dc/dc/commit/72239558af2ee50cdfc71b7e185e6661ab568ba1))
|
||||||
|
|
||||||
|
## [6.15.2](https://git.datacontroller.io/dc/dc/compare/v6.15.1...v6.15.2) (2025-06-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* pipeline updates for DC.html ([624a7a8](https://git.datacontroller.io/dc/dc/commit/624a7a8f37f0265cf576da310ac330c75aa417cf))
|
||||||
|
|
||||||
## [6.15.1](https://git.datacontroller.io/dc/dc/compare/v6.15.0...v6.15.1) (2025-06-04)
|
## [6.15.1](https://git.datacontroller.io/dc/dc/compare/v6.15.0...v6.15.1) (2025-06-04)
|
||||||
|
|
||||||
|
|
||||||
|
8
client/package-lock.json
generated
8
client/package-lock.json
generated
@ -21,7 +21,7 @@
|
|||||||
"@clr/icons": "^13.0.2",
|
"@clr/icons": "^13.0.2",
|
||||||
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
|
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
|
||||||
"@handsontable/angular": "^15.3.0",
|
"@handsontable/angular": "^15.3.0",
|
||||||
"@sasjs/adapter": "^4.11.0",
|
"@sasjs/adapter": "^4.12.0",
|
||||||
"@sasjs/utils": "^3.4.0",
|
"@sasjs/utils": "^3.4.0",
|
||||||
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
|
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
|
||||||
"@types/d3-graphviz": "^2.6.7",
|
"@types/d3-graphviz": "^2.6.7",
|
||||||
@ -5912,9 +5912,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/adapter": {
|
"node_modules/@sasjs/adapter": {
|
||||||
"version": "4.11.3",
|
"version": "4.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.12.0.tgz",
|
||||||
"integrity": "sha512-KF6G4vzs4l4efjpCD02og3kB44uFfJ1u2UWu749VdHtLKNN9l+PO26/moR+YAmRmmz2I9sC3X09fZE1nlN6zgw==",
|
"integrity": "sha512-1W78CzWyovSNSgjJ36fyckAGrzYqaRyDpjyO+sTchv3JjY0G7ZKw2gaX+NVASDGhKvt4L9PEkJ/Gk7ZG2BSkJA==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
"@clr/icons": "^13.0.2",
|
"@clr/icons": "^13.0.2",
|
||||||
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
|
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
|
||||||
"@handsontable/angular": "^15.3.0",
|
"@handsontable/angular": "^15.3.0",
|
||||||
"@sasjs/adapter": "^4.11.0",
|
"@sasjs/adapter": "^4.12.0",
|
||||||
"@sasjs/utils": "^3.4.0",
|
"@sasjs/utils": "^3.4.0",
|
||||||
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
|
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
|
||||||
"@types/d3-graphviz": "^2.6.7",
|
"@types/d3-graphviz": "^2.6.7",
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import SASjs, { SASjsConfig } from '@sasjs/adapter'
|
import SASjs, { SASjsConfig } from '@sasjs/adapter'
|
||||||
import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings'
|
import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings'
|
||||||
|
import { HelperService } from 'src/app/services'
|
||||||
import { DeployService } from 'src/app/services/deploy.service'
|
import { DeployService } from 'src/app/services/deploy.service'
|
||||||
import { EventService } from 'src/app/services/event.service'
|
import { EventService } from 'src/app/services/event.service'
|
||||||
import { LoggerService } from 'src/app/services/logger.service'
|
import { LoggerService } from 'src/app/services/logger.service'
|
||||||
@ -82,23 +83,24 @@ export class AutomaticComponent implements OnInit {
|
|||||||
private deployService: DeployService,
|
private deployService: DeployService,
|
||||||
private sasService: SasService,
|
private sasService: SasService,
|
||||||
private sasViyaService: SasViyaService,
|
private sasViyaService: SasViyaService,
|
||||||
private loggerService: LoggerService
|
private loggerService: LoggerService,
|
||||||
|
private helperService: HelperService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
const promiseGetAadminGroups = this.getAdminGroups()
|
this.loadData()
|
||||||
const getCurrentUser = this.getCurrentUser()
|
}
|
||||||
const getComputeContexts = this.getComputeContexts()
|
|
||||||
|
|
||||||
Promise.all([
|
public async loadData() {
|
||||||
promiseGetAadminGroups,
|
await this.getAdminGroups()
|
||||||
getCurrentUser,
|
await this.getComputeContexts()
|
||||||
getComputeContexts
|
await this.getCurrentUser()
|
||||||
]).then(() => {
|
|
||||||
|
setTimeout(() => {
|
||||||
if (this.selectedComputeContext) {
|
if (this.selectedComputeContext) {
|
||||||
this.onComputeContextChange(this.selectedComputeContext)
|
this.onComputeContextChange(this.selectedComputeContext)
|
||||||
}
|
}
|
||||||
})
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getComputeContexts() {
|
public async getComputeContexts() {
|
||||||
@ -144,6 +146,7 @@ export class AutomaticComponent implements OnInit {
|
|||||||
resolve()
|
resolve()
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
|
console.error('Error while getting current user', err)
|
||||||
reject(err)
|
reject(err)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -190,6 +193,14 @@ export class AutomaticComponent implements OnInit {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getComputeContextName(id: string): string | undefined {
|
||||||
|
return (
|
||||||
|
this.computeContexts.find(
|
||||||
|
(context: ComputeContextItem) => context.id === id
|
||||||
|
)?.name || undefined
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes sas.json file to deploy the backend
|
* Executes sas.json file to deploy the backend
|
||||||
* Method will first try to run the `auto deploy`
|
* Method will first try to run the `auto deploy`
|
||||||
@ -265,13 +276,12 @@ export class AutomaticComponent implements OnInit {
|
|||||||
let selectedComputeContextName = this.sasJsConfig.contextName
|
let selectedComputeContextName = this.sasJsConfig.contextName
|
||||||
|
|
||||||
if (this.selectedComputeContext.length && this.computeContexts.length) {
|
if (this.selectedComputeContext.length && this.computeContexts.length) {
|
||||||
const computeContext = this.computeContexts.find(
|
const computeContextName = this.getComputeContextName(
|
||||||
(context: ComputeContextItem) =>
|
this.selectedComputeContext
|
||||||
context.id === this.selectedComputeContext
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (computeContext) {
|
if (computeContextName) {
|
||||||
selectedComputeContextName = computeContext.name
|
selectedComputeContextName = computeContextName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,14 +297,9 @@ export class AutomaticComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.sasJs
|
this.sasJs
|
||||||
.request(
|
.request(`services/admin/makedata`, data, overrideConfig, () => {
|
||||||
`services/admin/makedata&_contextname=${selectedComputeContextName}`,
|
this.sasService.shouldLogin.next(true)
|
||||||
data,
|
})
|
||||||
overrideConfig,
|
|
||||||
() => {
|
|
||||||
this.sasService.shouldLogin.next(true)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
this.autodeployDone = true
|
this.autodeployDone = true
|
||||||
|
|
||||||
@ -321,6 +326,9 @@ export class AutomaticComponent implements OnInit {
|
|||||||
MAC: macMsg
|
MAC: macMsg
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.helperService.isStreamingViya())
|
||||||
|
this.updateIndexHtmlComputeContext()
|
||||||
})
|
})
|
||||||
.catch((err: any) => {
|
.catch((err: any) => {
|
||||||
this.eventService.showAbortModal('makedata', JSON.stringify(err))
|
this.eventService.showAbortModal('makedata', JSON.stringify(err))
|
||||||
@ -335,6 +343,57 @@ export class AutomaticComponent implements OnInit {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only when on Viya streamed app, this method will update the `contextname` in the `index.html` on the SAS drive
|
||||||
|
* This is needed to ensure that the DC will use the same compute context `makedata` service used to run against.
|
||||||
|
*/
|
||||||
|
public async updateIndexHtmlComputeContext() {
|
||||||
|
const filenamePath = location.search.split('/').pop()
|
||||||
|
const filename = filenamePath?.includes('.') ? filenamePath : undefined
|
||||||
|
|
||||||
|
if (!filename) {
|
||||||
|
this.eventService.showAbortModal(
|
||||||
|
null,
|
||||||
|
'We could not figure out the file name of `index.html` based on the url.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const indexHtmlContent = await this.sasService.getFileContent(
|
||||||
|
`${this.appLoc}/services`,
|
||||||
|
filename
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!indexHtmlContent) {
|
||||||
|
this.loggerService.error(
|
||||||
|
`Failed to get ${filename} at ${this.appLoc}/services`
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const computeContextName = this.getComputeContextName(
|
||||||
|
this.selectedComputeContext
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!computeContextName) {
|
||||||
|
this.loggerService.error(
|
||||||
|
`Compute context name not found for ID: ${this.selectedComputeContext} | List: ${JSON.stringify(this.computeContexts)}`
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedContent = indexHtmlContent.replace(
|
||||||
|
/contextname="[^"]*"/g,
|
||||||
|
`contextname="${computeContextName}"`
|
||||||
|
)
|
||||||
|
|
||||||
|
await this.sasService
|
||||||
|
.updateFileContent(`${this.appLoc}/services`, filename, updatedContent)
|
||||||
|
.catch((err: any) => {
|
||||||
|
this.loggerService.error(`Failed to update DataController.html: ${err}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public downloadFile(
|
public downloadFile(
|
||||||
content: any,
|
content: any,
|
||||||
filename: string,
|
filename: string,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import cloneDeep from 'lodash-es/cloneDeep'
|
import cloneDeep from 'lodash-es/cloneDeep'
|
||||||
import * as CryptoMD5 from 'crypto-js/md5'
|
import * as CryptoMD5 from 'crypto-js/md5'
|
||||||
|
import { SasService } from './sas.service'
|
||||||
|
|
||||||
const librariesToShow = 50
|
const librariesToShow = 50
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ export class HelperService {
|
|||||||
public loadMoreCount: number = librariesToShow
|
public loadMoreCount: number = librariesToShow
|
||||||
public isMicrosoft: boolean = false
|
public isMicrosoft: boolean = false
|
||||||
|
|
||||||
constructor() {
|
constructor(private sasService: SasService) {
|
||||||
this.isMicrosoft = this.isIEorEDGE()
|
this.isMicrosoft = this.isIEorEDGE()
|
||||||
console.log('Is IE or Edge?', this.isMicrosoft)
|
console.log('Is IE or Edge?', this.isMicrosoft)
|
||||||
}
|
}
|
||||||
@ -314,6 +315,20 @@ export class HelperService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isStreamingViya(): boolean {
|
||||||
|
const serverType = this.sasService.getServerType()
|
||||||
|
|
||||||
|
if (serverType !== 'SASVIYA') return false
|
||||||
|
|
||||||
|
if (
|
||||||
|
location.search.toLowerCase().includes('?_file=') &&
|
||||||
|
location.pathname.toLowerCase().includes('/sasjobexecution')
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Required type is NodeJS.Timeout
|
// Required type is NodeJS.Timeout
|
||||||
// But NodeJS is not available in browser so we have to go with any
|
// But NodeJS is not available in browser so we have to go with any
|
||||||
private debounceTimeout: any
|
private debounceTimeout: any
|
||||||
|
@ -657,4 +657,17 @@ export class SasService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Viya specific functions
|
||||||
|
public getFileContent(folderPath: string, fileName: string) {
|
||||||
|
return this.sasjsAdapter.getFileContent(folderPath, fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateFileContent(
|
||||||
|
folderPath: string,
|
||||||
|
fileName: string,
|
||||||
|
content: string
|
||||||
|
) {
|
||||||
|
return this.sasjsAdapter.updateFileContent(folderPath, fileName, content)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dcfrontend",
|
"name": "dcfrontend",
|
||||||
"version": "6.15.1",
|
"version": "6.16.2",
|
||||||
"description": "Data Controller",
|
"description": "Data Controller",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@saithodev/semantic-release-gitea": "^2.1.0",
|
"@saithodev/semantic-release-gitea": "^2.1.0",
|
||||||
|
10
sas/package-lock.json
generated
10
sas/package-lock.json
generated
@ -7,7 +7,7 @@
|
|||||||
"name": "dc-sas",
|
"name": "dc-sas",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/cli": "^4.12.7",
|
"@sasjs/cli": "^4.12.7",
|
||||||
"@sasjs/core": "^4.58.1"
|
"@sasjs/core": "^4.58.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@coolaj86/urequest": {
|
"node_modules/@coolaj86/urequest": {
|
||||||
@ -76,12 +76,18 @@
|
|||||||
"sasjs": "build/index.js"
|
"sasjs": "build/index.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/core": {
|
"node_modules/@sasjs/cli/node_modules/@sasjs/core": {
|
||||||
"version": "4.58.1",
|
"version": "4.58.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.58.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.58.1.tgz",
|
||||||
"integrity": "sha512-Qp6KAtp1VZcmN5HLGSIUE9H41qpFuihWLbjNygOYp+NRs/Y8VagpHrYeyIQbh3cSgchiJEMXudLql8hoU06wpg==",
|
"integrity": "sha512-Qp6KAtp1VZcmN5HLGSIUE9H41qpFuihWLbjNygOYp+NRs/Y8VagpHrYeyIQbh3cSgchiJEMXudLql8hoU06wpg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@sasjs/core": {
|
||||||
|
"version": "4.58.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.58.2.tgz",
|
||||||
|
"integrity": "sha512-P/DMCHfFrZT+50DIT7CiYBSjxOo5m0AHBLNKHGFOMfQnEymOKekQPk2Xzw5wkQyg8gjp2yBKhRwhpni5rvJFgQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@sasjs/lint": {
|
"node_modules/@sasjs/lint": {
|
||||||
"version": "2.4.3",
|
"version": "2.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/lint/-/lint-2.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/lint/-/lint-2.4.3.tgz",
|
||||||
|
@ -29,6 +29,6 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/cli": "^4.12.7",
|
"@sasjs/cli": "^4.12.7",
|
||||||
"@sasjs/core": "^4.58.1"
|
"@sasjs/core": "^4.58.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user