dc/client/src/app/app.component.ts

280 lines
8.8 KiB
TypeScript

import { ChangeDetectorRef, Component, ElementRef } from '@angular/core'
import { Router } from '@angular/router'
import { VERSION } from '../environments/version'
import { ActivatedRoute } from '@angular/router'
import { Location } from '@angular/common'
import '@clr/icons'
import '@clr/icons/shapes/all-shapes'
import { globals } from './_globals'
import * as moment from 'moment'
import { EventService } from './services/event.service'
import { AppService } from './services/app.service'
import { InfoModal } from './models/InfoModal'
import { DcAdapterSettings } from './models/DcAdapterSettings'
import { AppStoreService } from './services/app-store.service'
import { LicenceService } from './services/licence.service'
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
private dcAdapterSettings: DcAdapterSettings | undefined
public commitVer: string
public version: any
public routeUrl: any
public errTop: boolean | undefined
public licenseExpiringDays: number | null = null
public sasjsAborts: InfoModal[] = []
public editorActive: boolean = false
public approveActive: boolean = false
public freeTierBanner: boolean = this.licenceService.isAppFreeTier.value
public licenceProblem = this.licenceService.licenceProblem
public appOverCapacity: boolean = false
public appActive: boolean | null = null
public requestsModal: boolean = false
public showRegistration: boolean = true
public startupDataLoaded: boolean = false
public demoLimitNotice: { open: boolean; featureName: string } = {
open: false,
featureName: ''
}
public syssite = this.appService.syssite
public licenceState = this.licenceService.licenceState
constructor(
private appService: AppService,
private licenceService: LicenceService,
public router: Router,
private route: ActivatedRoute,
private location: Location,
private eventService: EventService,
private appStoreService: AppStoreService,
private cdr: ChangeDetectorRef,
private elementRef: ElementRef
) {
this.parseDcAdapterSettings()
;(window as any).appinfo = () => {
const licenseKeyData = this.licenceService.getLicenseKeyData()
if (licenseKeyData) {
const expiry_date = moment(
licenseKeyData.valid_until,
'YYYY-MM-DD'
).startOf('day')
const current_date = moment().startOf('day')
const daysToExpiry = expiry_date.diff(current_date, 'days')
licenseKeyData.valid_until += ` (${daysToExpiry} ${
daysToExpiry === 1 ? 'day' : 'days'
} remaining)`
if (isNaN(daysToExpiry)) licenseKeyData.valid_until = 'Unlimited'
}
console.table({
'Adapter version': VERSION.adapterVersion || 'n/a',
'App version': (VERSION.tag || '').replace('v', ''),
'Build timestamp': moment(parseInt(VERSION.timestamp)).format(
'DD-MMM-YYYY HH:MM'
),
'...': '...'
})
}
this.subscribeToLicenseEvents()
this.commitVer = (VERSION.tag || '').replace('v', '') + '.' + VERSION.hash
router.events.subscribe((val) => {
this.routeUrl = this.router.url
if (typeof this.routeUrl !== 'undefined' && this.routeUrl.length > 4) {
let rootParam = this.routeUrl.split('/')[1]
if (rootParam === 'editor') {
this.errTop = true
this.editorActive = true
this.approveActive = false
} else if (rootParam === 'home') {
this.errTop = false
this.editorActive = true
this.approveActive = false
} else {
this.errTop = true
this.editorActive = false
}
globals.rootParam = rootParam
}
if (typeof this.routeUrl !== 'undefined' && this.routeUrl.length > 6) {
if (this.routeUrl.includes('approveDet')) {
this.approveActive = true
} else if (this.routeUrl.includes('toapprove')) {
this.approveActive = true
} else {
this.approveActive = false
}
}
})
this.subscribeToShowAbortModal()
this.subscribeToRequestsModal()
this.subscribeToStartupData()
this.subscribeToAppActive()
this.subscribeToDemoLimitModal()
/* In Viya streaming apps, content is served within an iframe. This code
makes that iframe "full screen" so it looks like a regular window. */
if (window.frameElement) {
window.frameElement.setAttribute(
'style',
'height:100%;width:100%;position:absolute'
)
window.frameElement.setAttribute('allowfullscreen', '')
window.frameElement.setAttribute('frameborder', '0')
window.frameElement.setAttribute('marginheight', '0')
window.frameElement.setAttribute('marginwidth', '0')
window.frameElement.setAttribute('scrolling', 'auto')
window.focus()
}
}
private parseDcAdapterSettings() {
const sasjsElement = document.querySelector('sasjs')
if (!sasjsElement) {
this.licenceService.deactivateApp()
setTimeout(() => {
this.eventService.showAbortModal(
null,
"Please make sure 'SASJS' tag with config attributes is added to index.html",
null,
'SASjs Config not found'
)
})
return
}
const getAppAttribute = (attribute: string) =>
sasjsElement.getAttribute(attribute) || undefined
const dcAdapterSettings = {
serverUrl: getAppAttribute('serverUrl') || '',
appLoc: getAppAttribute('appLoc') || '',
serverType: getAppAttribute('serverType'),
loginMechanism: getAppAttribute('loginMechanism') || '',
adminGroup: getAppAttribute('adminGroup') || '',
dcPath: getAppAttribute('dcPath') || '',
debug: getAppAttribute('debug') === 'true' || false,
useComputeApi: this.parseComputeApi(getAppAttribute('useComputeApi')),
contextName: getAppAttribute('contextName') || '',
hotLicenceKey: getAppAttribute('hotLicenceKey') || ''
}
this.dcAdapterSettings = dcAdapterSettings as any
this.appStoreService.setDcAdapterSettings(dcAdapterSettings as any)
this.appService.sasServiceInit()
}
public licenceProblemDetails(url: string) {
this.router.navigateByUrl(url)
}
/**
* Based on string provided we return true, false or null
* True -> Compute API
* False -> JES API
* Null -> JES WEB
* @param value provided in the html <sasjs> tag
* @returns true, false or null
*/
private parseComputeApi(value: string | undefined): boolean | null {
if (value === undefined) return null
if (value === 'undefined' || value === 'null') return null
return value === 'true' || false
}
public subscribeToDemoLimitModal() {
this.eventService.onDemoLimitModalShow.subscribe((featureName: string) => {
this.demoLimitNotice = {
open: true,
featureName
}
})
}
public subscribeToLicenseEvents() {
this.licenceService.isAppFreeTier.subscribe((isAppFreeTier: boolean) => {
this.freeTierBanner = isAppFreeTier
})
this.licenceService.licenseExpiresInDays.subscribe(
(licenseExpiringDays: number | null) => {
if (licenseExpiringDays && licenseExpiringDays <= 14)
this.licenseExpiringDays = licenseExpiringDays
}
)
this.licenceService.isAppOverCapacity.subscribe(
(isAppOverAppCapacity: boolean) => {
this.appOverCapacity = isAppOverAppCapacity
}
)
}
public subscribeToAppActive() {
this.licenceService.isAppActivated.subscribe((value: any) => {
this.appActive = value
})
}
/**
* Listnes to an event that is fired when showing abort modal
* Then pushes object to array and modal is displayed
* `abortId` is calculated and assigned so that modal can be removed and closed
* it's an incrementing number
*/
public subscribeToShowAbortModal() {
this.eventService.onShowAbortModal.subscribe((sasjsAbort: InfoModal) => {
let abortId = this.sasjsAborts.length + 1
sasjsAbort.id = abortId
this.sasjsAborts.push(sasjsAbort)
this.cdr.detectChanges() //Changes were not triggered while hot is focused
})
}
public subscribeToStartupData() {
this.eventService.onStartupDataLoaded.subscribe(() => {
this.startupDataLoaded = true
})
}
public subscribeToRequestsModal() {
this.eventService.onRequestsModalOpen.subscribe((value: boolean) => {
this.requestsModal = true
})
}
public closeAbortModal(abortId: number) {
let abortIndex = this.sasjsAborts.findIndex((abort) => abort.id === abortId)
this.sasjsAborts.splice(abortIndex, 1)
}
public toggleSidebar() {
this.eventService.toggleSidebar()
}
public isMainRoute(route: string): boolean {
return this.router.url.includes(route)
}
public openLicencingPage() {
this.router.navigateByUrl('/licensing/update')
}
}