28 Commits

Author SHA1 Message Date
9264ce2a60 Merge pull request 'Adapter bump, including getFileContent and updateFileContent' (#167) from adapter-bump into main
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 4m4s
Release / Build-and-test-development (push) Successful in 9m9s
Release / release (push) Successful in 8m19s
Reviewed-on: #167
2025-06-05 13:17:06 +00:00
cbd69df708 fix: bump core to ensure ff works on viya streaming deploy
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m3s
Build / Build-and-test-development (pull_request) Successful in 8m39s
closes #156 (along with previous releases)
2025-06-05 14:16:44 +01:00
ca7caa25b6 fix: adapter bump
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m9s
Build / Build-and-test-development (pull_request) Successful in 8m45s
2025-06-05 14:49:21 +02:00
c10330627f Merge pull request 'Viya smooth deploy' (#166) from deploy-context into main
Some checks failed
Release / Build-production-and-ng-test (push) Has been cancelled
Release / Build-and-test-development (push) Has been cancelled
Release / release (push) Has been cancelled
Reviewed-on: #166
2025-06-05 12:30:29 +00:00
d80c59afce Merge branch 'main' into deploy-context
Some checks failed
Build / Build-and-ng-test (pull_request) Has been cancelled
Build / Build-and-test-development (pull_request) Has been cancelled
2025-06-05 12:30:19 +00:00
abdbb67471 fix: viya deploy load data timing
Some checks failed
Build / Build-and-ng-test (pull_request) Failing after 4m0s
Build / Build-and-test-development (pull_request) Failing after 2h56m12s
2025-06-05 12:07:26 +02:00
037a97b6ff fix: automatic viya deploy timing issue 2025-06-04 17:37:44 +02:00
a0a529ad38 style: lint 2025-06-04 17:36:13 +02:00
72239558af feat: viya deploy, update the index.html contextname 2025-06-04 17:35:15 +02:00
d2097ad6dd chore(release): 6.15.2 [skip ci]
## [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](624a7a8f37))
2025-06-04 14:26:44 +00:00
1bd542cddb Merge pull request 'fix: pipeline updates for DC.html' (#165) from issue156b into main
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 4m29s
Release / Build-and-test-development (push) Successful in 8m37s
Release / release (push) Successful in 8m17s
Reviewed-on: #165
2025-06-04 13:53:24 +00:00
fb1c1ee874 Merge branch 'main' into issue156b
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m1s
Build / Build-and-test-development (pull_request) Successful in 8m34s
2025-06-04 13:48:58 +00:00
624a7a8f37 fix: pipeline updates for DC.html
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m5s
Build / Build-and-test-development (pull_request) Successful in 8m42s
2025-06-04 14:41:36 +01:00
381378f532 chore(release): 6.15.1 [skip ci]
## [6.15.1](https://git.datacontroller.io/dc/dc/compare/v6.15.0...v6.15.1) (2025-06-04)

### Bug Fixes

* updating pipeline to default to streaming on viya ([4b55894](4b558948d9))
2025-06-04 12:57:08 +00:00
af05486c0e Merge pull request 'fix: updating pipeline to default to streaming on viya' (#164) from issue156b into main
Some checks failed
Release / Build-production-and-ng-test (push) Successful in 3m57s
Release / Build-and-test-development (push) Successful in 8m41s
Release / release (push) Failing after 7m35s
Reviewed-on: #164
2025-06-04 12:28:12 +00:00
4b558948d9 fix: updating pipeline to default to streaming on viya
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m4s
Build / Build-and-test-development (pull_request) Successful in 8m33s
Also added error captures on makedata
2025-06-04 13:27:28 +01:00
d9cff42f5c chore(release): 6.15.0 [skip ci]
# [6.15.0](https://git.datacontroller.io/dc/dc/compare/v6.14.10...v6.15.0) (2025-06-04)

### Bug Fixes

* makedata with context name ([da4d0b2](da4d0b28c7))

### Features

* viya deploy context ([6c96ef7](6c96ef7fb0))
2025-06-04 09:26:02 +00:00
2a3d2b8d0d Merge pull request 'feat: viya deploy context' (#163) from deploy-context into main
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 4m3s
Release / Build-and-test-development (push) Successful in 8m39s
Release / release (push) Successful in 8m30s
Reviewed-on: #163
2025-06-04 09:09:28 +00:00
d0f453d291 chore: typo
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 3m59s
Build / Build-and-test-development (pull_request) Successful in 8m31s
2025-06-04 09:41:06 +02:00
8e65dd0eae style: lint
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 3m59s
Build / Build-and-test-development (pull_request) Successful in 8m25s
2025-06-03 21:06:48 +02:00
da4d0b28c7 fix: makedata with context name
Some checks failed
Build / Build-and-ng-test (pull_request) Failing after 49s
Build / Build-and-test-development (pull_request) Successful in 8m32s
2025-06-03 21:00:54 +02:00
6c96ef7fb0 feat: viya deploy context
Some checks failed
Build / Build-and-ng-test (pull_request) Failing after 47s
Build / Build-and-test-development (pull_request) Successful in 8m35s
2025-06-03 20:22:39 +02:00
997f09adde chore(release): 6.14.10 [skip ci]
## [6.14.10](https://git.datacontroller.io/dc/dc/compare/v6.14.9...v6.14.10) (2025-06-02)

### Bug Fixes

* bump core ([0e8503e](0e8503ed2b))
* default to home directory for SAS Drive in Viya ([9682b54](9682b548e6))
2025-06-02 17:51:20 +00:00
0e8503ed2b fix: bump core
All checks were successful
Release / Build-production-and-ng-test (push) Successful in 4m31s
Release / Build-and-test-development (push) Successful in 8m40s
Release / release (push) Successful in 8m20s
2025-06-02 18:32:33 +01:00
97dfcd79b1 Merge pull request 'issue156' (#161) from issue156 into main
Some checks failed
Release / Build-and-test-development (push) Has been cancelled
Release / release (push) Has been cancelled
Release / Build-production-and-ng-test (push) Has been cancelled
Reviewed-on: #161
2025-06-02 17:29:18 +00:00
9a12a2e41f Merge branch 'main' into issue156
Some checks failed
Build / Build-and-ng-test (pull_request) Successful in 4m9s
Build / Build-and-test-development (pull_request) Has been cancelled
2025-06-02 17:27:14 +00:00
9682b548e6 fix: default to home directory for SAS Drive in Viya
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 4m10s
Build / Build-and-test-development (pull_request) Successful in 8m35s
2025-05-29 15:05:18 +01:00
2e0c60cc0d chore: fix package-lock 2025-05-28 18:57:43 +02:00
18 changed files with 515 additions and 103 deletions

View File

@ -237,20 +237,20 @@ jobs:
cd sas
sasjs c -t viya
rm -rf sasjsbuild/tests
sed -i -e 's/servertype="SASJS"/servertype="SASVIYA"/g' sasjsbuild/services/clickme.html
sasjs b -t viya
cp sasjsbuild/viya.sas ./demostream_viya.sas
# compile Viya Full deploy (without web)
rm -rf sasjsbuild/services/web
rm sasjsbuild/services/clickme.html
sed -i -e 's/servertype="SASJS"/servertype="SASVIYA"/g' sasjsbuild/services/DC.html
sasjs b -t viya
cp sasjsbuild/viya.sas ./viya.sas
cp sasjsbuild/viya.json ./viya.json
# compile Viya Full deploy (without web)
rm -rf sasjsbuild/services/web
rm sasjsbuild/services/DC.html
sasjs b -t viya
cp sasjsbuild/viya.sas ./viya_noweb.sas
cp sasjsbuild/viya.json ./viya_noweb.json
- name: Zip Frontend (including viya.json for full viya deploy)
run: |
cd sas
cp sasjsbuild/viya.json ../client/dist
cp sasjsbuild/viya.json ../client/dist/viya.json
cd ..
zip -r frontend.zip ./client/dist
@ -277,8 +277,8 @@ jobs:
URL="https://git.datacontroller.io/api/v1/repos/dc/dc/releases/$RELEASE_ID/assets?access_token=${{ secrets.RELEASE_TOKEN }}"
curl -k $URL -F attachment=@frontend.zip
curl -k $URL -F attachment=@sas/demostream_sas9.sas
curl -k $URL -F attachment=@sas/demostream_viya.sas
curl -k $URL -F attachment=@sas/viya.sas
curl -k $URL -F attachment=@sas/sasjs_server.json.zip
curl -k $URL -F attachment=@sas/sas9.sas
curl -k $URL -F attachment=@sas/viya.sas
curl -k $URL -F attachment=@sas/viya.json
curl -k $URL -F attachment=@sas/viya_noweb.sas
curl -k $URL -F attachment=@sas/viya_noweb.json

View File

@ -1,3 +1,37 @@
## [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)
### Bug Fixes
* updating pipeline to default to streaming on viya ([4b55894](https://git.datacontroller.io/dc/dc/commit/4b558948d997f456ff25a12a58827fe0d2075493))
# [6.15.0](https://git.datacontroller.io/dc/dc/compare/v6.14.10...v6.15.0) (2025-06-04)
### Bug Fixes
* makedata with context name ([da4d0b2](https://git.datacontroller.io/dc/dc/commit/da4d0b28c7109afd6f96455e1e0e80a40d25a942))
### Features
* viya deploy context ([6c96ef7](https://git.datacontroller.io/dc/dc/commit/6c96ef7fb0a55754a84ff0a8bbab838b78c1acaf))
## [6.14.10](https://git.datacontroller.io/dc/dc/compare/v6.14.9...v6.14.10) (2025-06-02)
### Bug Fixes
* bump core ([0e8503e](https://git.datacontroller.io/dc/dc/commit/0e8503ed2bb22a0fc3924ac929e7f19626772e0a))
* default to home directory for SAS Drive in Viya ([9682b54](https://git.datacontroller.io/dc/dc/commit/9682b548e6106d99d97dcc023a35d93addfd5170))
## [6.14.9](https://git.datacontroller.io/dc/dc/compare/v6.14.8...v6.14.9) (2025-06-02)

View File

@ -21,7 +21,7 @@
"@clr/icons": "^13.0.2",
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
"@handsontable/angular": "^15.3.0",
"@sasjs/adapter": "^4.11.0",
"@sasjs/adapter": "^4.12.0",
"@sasjs/utils": "^3.4.0",
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
"@types/d3-graphviz": "^2.6.7",
@ -5912,9 +5912,9 @@
]
},
"node_modules/@sasjs/adapter": {
"version": "4.11.3",
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.11.3.tgz",
"integrity": "sha512-KF6G4vzs4l4efjpCD02og3kB44uFfJ1u2UWu749VdHtLKNN9l+PO26/moR+YAmRmmz2I9sC3X09fZE1nlN6zgw==",
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.12.0.tgz",
"integrity": "sha512-1W78CzWyovSNSgjJ36fyckAGrzYqaRyDpjyO+sTchv3JjY0G7ZKw2gaX+NVASDGhKvt4L9PEkJ/Gk7ZG2BSkJA==",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {

View File

@ -49,7 +49,7 @@
"@clr/icons": "^13.0.2",
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz",
"@handsontable/angular": "^15.3.0",
"@sasjs/adapter": "^4.11.0",
"@sasjs/adapter": "^4.12.0",
"@sasjs/utils": "^3.4.0",
"@sheet/crypto": "file:libraries/sheet-crypto.tgz",
"@types/d3-graphviz": "^2.6.7",

View File

@ -98,14 +98,14 @@
<label for="dcloc" class="mt-20 clr-control-label">DC Loc</label>
<div class="mb-10 clr-control-container dc-loc-input-wrapper">
<div class="clr-input-wrapper">
<div class="clr-input-wrapper small-mt">
<input clrInput name="dcloc" [(ngModel)]="dcPath" />
</div>
</div>
<label for="dcloc" class="mt-20 clr-control-label">SAS Admin group</label>
<div class="mb-10 clr-control-container">
<div class="clr-input-wrapper">
<div class="clr-input-wrapper small-mt">
<select
*ngIf="!adminGroupsLoading"
clrSelect
@ -124,6 +124,42 @@
</div>
</div>
<label for="computeContext" class="mt-20 clr-control-label"
>Compute Context</label
>
<div class="mb-10 clr-control-container">
<div class="clr-input-wrapper small-mt">
<select
*ngIf="!computeContextsLoading"
clrSelect
name="options"
(ngModelChange)="onComputeContextChange($event)"
[(ngModel)]="selectedComputeContext"
>
<option
*ngFor="let computeContext of computeContexts"
[value]="computeContext.id"
>
{{ computeContext.name }}
</option>
</select>
<clr-spinner
clrInline
class="spinner-sm"
*ngIf="computeContextsLoading"
></clr-spinner>
</div>
</div>
<ng-container *ngIf="runningAsUser">
<label for="dcloc" class="mt-20 clr-control-label">Running as user:</label>
<div class="mb-10 clr-control-container">
<div class="clr-input-wrapper">
<p class="mt-0">{{ runningAsUser }}</p>
</div>
</div>
</ng-container>
<!-- Keeping this for a reference in case future VIYA changes and starts allowing separate backend and frontend) -->
<!-- <clr-checkbox-wrapper>

View File

@ -18,6 +18,11 @@ import {
Item,
ViyaApiIdentities
} from 'src/app/viya-api-explorer/models/viya-api-identities.model'
import { ComputeContextDetails } from 'src/app/viya-api-explorer/models/viya-compute-context-details.model'
import {
ViyaComputeContexts,
Item as ComputeContextItem
} from 'src/app/viya-api-explorer/models/viya-compute-contexts.model'
@Component({
selector: 'app-automatic-deploy',
@ -35,6 +40,7 @@ export class AutomaticComponent implements OnInit {
@Output() onNavigateToHome: EventEmitter<any> = new EventEmitter<any>()
public selectedComputeContext: string = ''
public makeDataResponse: string = ''
public jsonFile: any = null
public autodeploying: boolean = false
@ -50,8 +56,11 @@ export class AutomaticComponent implements OnInit {
public createDatabaseLoading: boolean = false
public adminGroupsLoading: boolean = false
public currentUserInfoLoading: boolean = false
public computeContextsLoading: boolean = false
public adminGroups: { id: string; name: string }[] = []
public runningAsUser: string | undefined
public currentUserInfo: ViyaApiCurrentUser | null = null
public computeContexts: ComputeContextItem[] = []
/** autoDeployStatus
* This object presents the status for two steps that we have for deploy.
@ -77,42 +86,117 @@ export class AutomaticComponent implements OnInit {
) {}
ngOnInit(): void {
this.getAdminGroups()
this.getCurrentUser()
this.loadData()
}
public async loadData() {
await this.getAdminGroups()
await this.getComputeContexts()
await this.getCurrentUser()
setTimeout(() => {
if (this.selectedComputeContext) {
this.onComputeContextChange(this.selectedComputeContext)
}
}, 500)
}
public async getComputeContexts() {
return new Promise<void>((resolve, reject) => {
this.computeContextsLoading = true
this.sasViyaService.getComputeContexts().subscribe(
(res: ViyaComputeContexts) => {
this.computeContextsLoading = false
const defaultContext = res.items.find(
(item: ComputeContextItem) =>
item.name === 'SAS Job Execution compute context'
)
if (defaultContext) {
this.selectedComputeContext = defaultContext.id
}
this.computeContexts = res.items
resolve()
},
(err) => {
reject(err)
}
)
})
}
public async getCurrentUser() {
this.currentUserInfoLoading = true
return new Promise<void>((resolve, reject) => {
this.currentUserInfoLoading = true
this.sasViyaService
.getCurrentUser()
.subscribe((res: ViyaApiCurrentUser) => {
this.currentUserInfoLoading = false
this.sasViyaService.getCurrentUser().subscribe(
(res: ViyaApiCurrentUser) => {
this.currentUserInfoLoading = false
this.currentUserInfo = res
this.currentUserInfo = res
this.dcPath = `/export/viya/homes/${res.id}`
})
this.dcPath = `/export/viya/homes/${res.id}`
resolve()
},
(err) => {
console.error('Error while getting current user', err)
reject(err)
}
)
})
}
public async getAdminGroups() {
this.adminGroupsLoading = true
return new Promise<void>((resolve, reject) => {
this.adminGroupsLoading = true
this.sasViyaService.getAdminGroups().subscribe((res: ViyaApiIdentities) => {
this.adminGroupsLoading = false
// Map admin groups with only needed fields
this.adminGroups = res.items.map((item: Item) => {
return {
id: item.id,
name: item.name
this.sasViyaService
.getAdminGroups()
.subscribe((res: ViyaApiIdentities) => {
this.adminGroupsLoading = false
// Map admin groups with only needed fields
this.adminGroups = res.items.map((item: Item) => {
return {
id: item.id,
name: item.name
}
})
resolve()
}),
(err: any) => {
this.adminGroupsLoading = false
this.loggerService.error('Error while getting admin groups', err)
this.eventService.showAbortModal('admin groups', err)
reject(err)
}
})
}
public async onComputeContextChange(computeContextId: string) {
this.sasViyaService
.getComputeContextById(computeContextId)
.subscribe((res: ComputeContextDetails) => {
if (res.attributes && res.attributes.runServerAs) {
this.runningAsUser = res.attributes.runServerAs
} else {
this.runningAsUser = this.currentUserInfo?.id || 'unknown'
}
})
}),
(err: any) => {
this.adminGroupsLoading = false
this.loggerService.error('Error while getting admin groups', err)
this.eventService.showAbortModal('admin groups', err)
}
}
public getComputeContextName(id: string): string | undefined {
return (
this.computeContexts.find(
(context: ComputeContextItem) => context.id === id
)?.name || undefined
)
}
/**
@ -186,6 +270,19 @@ export class AutomaticComponent implements OnInit {
]
}
// Get and run service using the selected context name
let selectedComputeContextName = this.sasJsConfig.contextName
if (this.selectedComputeContext.length && this.computeContexts.length) {
const computeContextName = this.getComputeContextName(
this.selectedComputeContext
)
if (computeContextName) {
selectedComputeContextName = computeContextName
}
}
/**
* We are overriding default `sasjsConfig` object fields with this object fields.
* Here we want to run this request using original WEB method.
@ -193,7 +290,7 @@ export class AutomaticComponent implements OnInit {
*/
let overrideConfig = {
useComputeApi: null,
contextName: this.sasJsConfig.contextName,
contextName: selectedComputeContextName,
debug: true
}
@ -227,6 +324,8 @@ export class AutomaticComponent implements OnInit {
MAC: macMsg
})
}
this.updateIndexHtmlComputeContext()
})
.catch((err: any) => {
this.eventService.showAbortModal('makedata', JSON.stringify(err))
@ -241,6 +340,50 @@ export class AutomaticComponent implements OnInit {
})
}
/**
* Only when on Viya, this method will update the `contextname` in the `DataController.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 indexHtmlContent = await this.sasService.getFileContent(
`${this.appLoc}/services`,
'DataController.html'
)
if (!indexHtmlContent) {
this.loggerService.error(
`Failed to get DataController.html 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`,
'DataController.html',
updatedContent
)
.catch((err: any) => {
this.loggerService.error(`Failed to update DataController.html: ${err}`)
})
}
public downloadFile(
content: any,
filename: string,

View File

@ -1,6 +1,12 @@
import { HttpClient } from '@angular/common/http'
import {
HttpClient,
HttpContext,
HttpErrorResponse,
HttpHeaders,
HttpParams
} from '@angular/common/http'
import { Injectable } from '@angular/core'
import { Observable } from 'rxjs'
import { catchError, Observable, throwError } from 'rxjs'
import { Collection } from '../viya-api-explorer/models/collection.model'
import { AppStoreService } from './app-store.service'
import { ViyaApis } from '../viya-api-explorer/models/viya-apis.models'
@ -8,6 +14,8 @@ import { ViyaApiFolderMembers } from '../viya-api-explorer/models/viya-api-folde
import { ViyaApiFolder } from '../viya-api-explorer/models/viya-api-folder.model'
import { ViyaApiIdentities } from '../viya-api-explorer/models/viya-api-identities.model'
import { ViyaApiCurrentUser } from '../viya-api-explorer/models/viya-api-current-user.model'
import { ViyaComputeContexts } from '../viya-api-explorer/models/viya-compute-contexts.model'
import { ComputeContextDetails } from '../viya-api-explorer/models/viya-compute-context-details.model'
@Injectable({
providedIn: 'root'
@ -75,7 +83,7 @@ export class SasViyaService {
this.serverUrl = adapterConfig?.serverUrl || ''
//example collection request
// example collection request
// this.getByCollection('jobs').subscribe((res) => {
// console.log('res', res)
// })
@ -95,7 +103,7 @@ export class SasViyaService {
* @returns
*/
getByUrl(url: string): Observable<Collection> {
return this.http.get<Collection>(`${this.serverUrl}${url}`, {
return this.get<Collection>(`${this.serverUrl}${url}`, {
withCredentials: true
})
}
@ -106,23 +114,32 @@ export class SasViyaService {
* @returns
*/
getByCollection(apiCollection: string): Observable<Collection> {
return this.http.get<Collection>(`${this.serverUrl}${apiCollection}`, {
return this.get<Collection>(`${this.serverUrl}${apiCollection}`, {
withCredentials: true
})
}
getComputeContexts(): Observable<any> {
return this.http.get<any>(`${this.serverUrl}/compute/contexts`, {
getComputeContexts(): Observable<ViyaComputeContexts> {
return this.get<ViyaComputeContexts>(`${this.serverUrl}/compute/contexts`, {
withCredentials: true
})
}
getComputeContextById(id: string): Observable<ComputeContextDetails> {
return this.get<ComputeContextDetails>(
`${this.serverUrl}/compute/contexts/${id}`,
{
withCredentials: true
}
)
}
/**
* @param path Path to the folder
* @returns The folder info object
*/
getFolderByPath(path: string): Observable<ViyaApiFolder> {
return this.http.get<ViyaApiFolder>(
return this.get<ViyaApiFolder>(
`${this.serverUrl}/folders/folders/@item?path=${path}`,
{
withCredentials: true
@ -131,7 +148,7 @@ export class SasViyaService {
}
getFolderMembers(folderId: string): Observable<ViyaApiFolderMembers> {
return this.http.get<ViyaApiFolderMembers>(
return this.get<ViyaApiFolderMembers>(
`${this.serverUrl}/folders/folders/${folderId}/members`,
{
withCredentials: true
@ -140,7 +157,7 @@ export class SasViyaService {
}
getAdminGroups(limit: number = 5000): Observable<ViyaApiIdentities> {
return this.http.get<ViyaApiIdentities>(
return this.get<ViyaApiIdentities>(
`${this.serverUrl}/identities/groups?sortBy=name&limit=${limit}`,
{
withCredentials: true
@ -149,11 +166,54 @@ export class SasViyaService {
}
getCurrentUser(): Observable<ViyaApiCurrentUser> {
return this.http.get<ViyaApiCurrentUser>(
return this.get<ViyaApiCurrentUser>(
`${this.serverUrl}/identities/users/@currentUser`,
{
withCredentials: true
}
)
}
get<T>(
url: string,
options?: {
headers?:
| HttpHeaders
| {
[header: string]: string | string[]
}
context?: HttpContext
observe?: 'body'
params?:
| HttpParams
| {
[param: string]:
| string
| number
| boolean
| ReadonlyArray<string | number | boolean>
}
reportProgress?: boolean
responseType?: 'json'
withCredentials?: boolean
transferCache?:
| {
includeHeaders?: string[]
}
| boolean
}
): Observable<T> {
return this.http.get<T>(url, options).pipe(
catchError((err: HttpErrorResponse) => {
console.log('url', url)
console.log('err.status', err.status)
if (err.status === 449 || err.status === 401) {
// Retry once if we got a 449
return this.http.get<T>(url, options)
}
// Otherwise propagate the error
return throwError(() => err)
})
)
}
}

View File

@ -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)
}
}

View File

@ -0,0 +1,34 @@
export interface ComputeContextDetails {
attributes?: Attributes
createdBy: string
creationTimeStamp: string
description: string
id: string
launchContext: LaunchContext
launchType: string
links: Link[]
modifiedBy: string
modifiedTimeStamp: string
name: string
version: number
}
export interface Link {
method: string
rel: string
href: string
uri: string
type?: string
responseType?: string
itemType?: string
}
export interface LaunchContext {
contextId: string
}
export interface Attributes {
reuseServerProcesses: string
runServerAs: string
serverMinAvailable: string
}

View File

@ -0,0 +1,36 @@
export interface ViyaComputeContexts {
accept: string
count: number
items: Item[]
limit: number
links: Link2[]
name: string
start: number
version: number
}
export interface Link2 {
method: string
rel: string
href: string
uri: string
type: string
itemType: string
}
export interface Item {
createdBy: string
id: string
links: Link[]
name: string
version: number
}
export interface Link {
method: string
rel: string
href: string
uri: string
type?: string
responseType?: string
}

View File

@ -3884,6 +3884,12 @@ app-header-actions {
// END OF CSP WORKAROUND
.clr-input-wrapper.small-mt {
.clr-form-control {
margin-top: 5px !important;
}
}
body[cds-theme="dark"] {
scrollbar-width: thin;
scrollbar-color: $trackColor $thumbColor;

View File

@ -1,6 +1,6 @@
{
"name": "dcfrontend",
"version": "6.14.9",
"version": "6.15.2",
"description": "Data Controller",
"devDependencies": {
"@saithodev/semantic-release-gitea": "^2.1.0",

24
sas/package-lock.json generated
View File

@ -6,8 +6,8 @@
"": {
"name": "dc-sas",
"dependencies": {
"@sasjs/cli": "^4.12.5",
"@sasjs/core": "^4.57.0"
"@sasjs/cli": "^4.12.7",
"@sasjs/core": "^4.58.2"
}
},
"node_modules/@coolaj86/urequest": {
@ -45,14 +45,14 @@
}
},
"node_modules/@sasjs/cli": {
"version": "4.12.5",
"resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-4.12.5.tgz",
"integrity": "sha512-y6JFATKlTyTl0gRPpDBPL1rwZsyeuyp5uEz7HMA7raSzQuNa6QZ1oO1Er91I7+cLUg0Ndh5aSNGKYOdBRStQ2g==",
"version": "4.12.7",
"resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-4.12.7.tgz",
"integrity": "sha512-KcXSR+3dRgINOLiN+7oJbzWsNQu7qm1YQ7eaVqiHTZI429BSgZez9+7p1bq09R4otHN8IzMAgLP9se/r9p9yJA==",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
"@sasjs/adapter": "4.11.3",
"@sasjs/core": "4.57.0",
"@sasjs/core": "4.58.1",
"@sasjs/lint": "2.4.3",
"@sasjs/utils": "3.5.2",
"adm-zip": "0.5.10",
@ -76,10 +76,16 @@
"sasjs": "build/index.js"
}
},
"node_modules/@sasjs/cli/node_modules/@sasjs/core": {
"version": "4.58.1",
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.58.1.tgz",
"integrity": "sha512-Qp6KAtp1VZcmN5HLGSIUE9H41qpFuihWLbjNygOYp+NRs/Y8VagpHrYeyIQbh3cSgchiJEMXudLql8hoU06wpg==",
"license": "MIT"
},
"node_modules/@sasjs/core": {
"version": "4.57.0",
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-4.57.0.tgz",
"integrity": "sha512-iJiLnW4oY15InGerXXWtrjc1YpJ9UDz72+r7Odfr/yYR7RxIhtXGjYQIqyQu6US+cS/0b2pi12LZB6VnfMS/pA==",
"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": {

View File

@ -28,7 +28,7 @@
},
"private": true,
"dependencies": {
"@sasjs/cli": "^4.12.5",
"@sasjs/core": "^4.57.0"
"@sasjs/cli": "^4.12.7",
"@sasjs/core": "^4.58.2"
}
}

View File

@ -99,7 +99,7 @@
"httpsAgentOptions": {
"allowInsecureRequests": false
},
"appLoc": "/Public/app/dc",
"appLoc": "/Public/app/dcplaceholder",
"macroFolders": [
"sasjs/targets/viya/macros_viya"
],
@ -109,7 +109,6 @@
"binaryFolders": [],
"buildConfig": {
"initProgram": "sasjs/utils/buildinitviya.sas",
"termProgram": "sasjs/utils/buildtermviya.sas",
"buildResultsFolder": "sasjsresults",
"buildOutputFolder": "sasjsbuild",
"buildOutputFileName": "viya.sas"
@ -128,7 +127,15 @@
"sasjs/utils/viyadeploy.sh"
]
},
"contextName": "Datacontroller compute context"
"streamConfig": {
"streamWeb": true,
"streamWebFolder": "web",
"webSourcePath": "../client/dist",
"streamServiceName": "DC",
"streamLogo": "favicon.ico",
"assetPaths": []
},
"contextName": "SAS Job Execution compute context"
},
{
"name": "viyacloud",
@ -312,38 +319,6 @@
"assetPaths": []
}
},
{
"name": "server-vlad",
"serverUrl": "https://sas.4gl.io:5000",
"serverType": "SASJS",
"httpsAgentOptions": {
"allowInsecureRequests": false
},
"appLoc": "/30.SASApps/app/dc",
"macroFolders": [
"sasjs/targets/server/macros_server"
],
"programFolders": [
"sasjs/db/datactrl"
],
"serviceConfig": {
"serviceFolders": [
"sasjs/targets/server/services_server/admin",
"sasjs/targets/server/services_server/usernav"
],
"initProgram": "sasjs/utils/serviceinitserver.sas",
"termProgram": "",
"macroVars": {}
},
"streamConfig": {
"streamWeb": true,
"streamWebFolder": "webv",
"streamServiceName": "DataController",
"webSourcePath": "../client/dist",
"streamLogo": "favicon.ico",
"assetPaths": []
}
},
{
"name": "mihajlo",
"serverUrl": "https://sas.4gl.io",

View File

@ -0,0 +1,27 @@
/**
@file
@brief Fetches directories to facilitate configuration
@details The service can also be invoked using the following URL param:
@li &parent= (parent path)
<h4> SAS Macros </h4>
@li mp_dirlist.sas
@version 9.2
@author 4GL Apps Ltd
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
and may not be re-distributed or re-sold without the express permission of
4GL Apps Ltd.
**/
%global parent;
/* if no flavour is specified, default to root */
%let parent=%sysfunc(coalescec(&parent,/));
%mp_dirlist(path=&parent,outds=dirlist, maxdepth=2)
%webout(OPEN)
%webout(OBJ,dirlist)
%webout(CLOSE)

View File

@ -7,6 +7,7 @@
@li mf_getapploc.sas
@li mf_mkdir.sas
@li mf_trimstr.sas
@li mp_abort.sas
@li mpe_getvars.sas
@li mpe_makedata.sas
@li mpe_makedatamodel.sas
@ -50,9 +51,33 @@ options noquotelenmax;
%put &=admin;
%mf_mkdir(&dcpath)
%mp_abort(iftrue= (&syscc ne 0)
,mac=&_program
,msg=%str(Unable to create &dcpath using &sysuserid)
)
%mf_mkdir(&dcpath/secret)
%mf_mkdir(&dcpath/dc_staging)
/* check we have physical permissions to the DCLIB folder */
data _null_;
putlog "dcpath=&dcpath/permTest.txt";
putlog "sysuserid=&sysuserid";
data _null_;
file "&dcpath/permTest.txt";
run;
%mp_abort(iftrue= (&syscc ne 0)
,mac=&_program
,msg=%str(User &sysuserid does not have WRITE permissions to: &dcpath )
)
filename delfile "&dcpath/permTest.txt";
data _null_;
rc=fdelete('delfile');
run;
%mp_abort(iftrue= (&syscc ne 0)
,mac=&_program..sas
,msg=%str(User &sysuserid could create (but not delete) &dcpath/permTest.txt )
)
libname &dclib "&dcpath";
%global admin;
@ -60,11 +85,23 @@ libname &dclib "&dcpath";
%mpe_makedatamodel(lib=&dclib)
%mpe_makedata(lib=&dclib,mpeadmins=&admin,path=%str(&dcpath))
%mp_abort(iftrue=(&syscc ne 0)
,mac=&sysmacroname
,msg=%str(Err during &dclib build)
)
/* sample data library */
%mf_mkdir(&dcpath/dc_demo)
libname dcdemo "&dcpath/dc_demo";
%mpe_makesampledata(outlib=DCDEMO)
%mp_abort(iftrue=(&syscc ne 0)
,mac=&sysmacroname
,msg=%str(Err during demo data build)
)
/* the DC precode is stored in the root of the project */
%let root=%mf_getapploc(&_program)/services;
%put &=root;
@ -167,7 +204,7 @@ run;
*/
%mp_abort(iftrue=(&syscc ne 0)
,mac=&sysmacroname
,msg=%str(Err during DB build)
,msg=%str(Err during settings job creation)
)

View File

@ -4,4 +4,9 @@
**/
options nonotes nomprint;
options nonotes nomprint;
/* update apploc to default to user home area if not set */
%let apploc=%sysfunc(ifc("&apploc"="/Public/app/dcplaceholder"
,/Users/&sysuserid/My Folder/Data Controller
,&apploc));