From fec01f44f6a349850dbdbcec352faa2106101932 Mon Sep 17 00:00:00 2001 From: Daniel Scalzi Date: Fri, 10 Apr 2020 21:30:59 -0400 Subject: [PATCH] Right click on XB to download SMG file. We do not have access to the web viewer. Open the SMG on composer. Transformer options are default set to make the selected node the default smg view. --- src/app/app.module.ts | 2 + src/app/main/tree/tree.component.html | 10 +++- src/app/main/tree/tree.component.ts | 73 +++++++++++++++++++----- src/app/model/TransformerOptions.ts | 3 + src/app/services/api/api.service.ts | 4 +- src/app/services/api/resource.service.ts | 15 ++++- 6 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 src/app/model/TransformerOptions.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 8919f61..e9735c4 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -7,6 +7,7 @@ import { AppComponent } from './app.component'; import { HttpClientModule } from '@angular/common/http'; import { TreeModule } from 'primeng/tree'; import { DropdownModule } from 'primeng/dropdown'; +import { ContextMenuModule } from 'primeng/contextmenu'; import { MainComponent } from './main/main.component'; import { MainCenterComponent } from './main/main-center/main-center.component'; import { TreeComponent } from './main/tree/tree.component'; @@ -22,6 +23,7 @@ import { FormsModule } from '@angular/forms'; BrowserAnimationsModule, TreeModule, DropdownModule, + ContextMenuModule, HttpClientModule ], providers: [], diff --git a/src/app/main/tree/tree.component.html b/src/app/main/tree/tree.component.html index 22f712b..068209c 100644 --- a/src/app/main/tree/tree.component.html +++ b/src/app/main/tree/tree.component.html @@ -1,4 +1,12 @@ - + + +
{{ node.label }}
diff --git a/src/app/main/tree/tree.component.ts b/src/app/main/tree/tree.component.ts index 52897f3..af504f9 100644 --- a/src/app/main/tree/tree.component.ts +++ b/src/app/main/tree/tree.component.ts @@ -1,10 +1,10 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { TreeNode } from 'primeng/api'; +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { TreeNode, MenuItem } from 'primeng/api'; import { Subscription } from 'rxjs'; -import { NodeService } from 'src/app/services/node.service'; import { TreeService } from 'src/app/services/tree.service'; import { EndItemService } from 'src/app/services/enditem.service'; import { GeiaService } from 'src/app/services/api/geia.service'; +import { ResourceService } from 'src/app/services/api/resource.service'; @Component({ selector: 'app-tree', @@ -15,14 +15,17 @@ export class TreeComponent implements OnInit, OnDestroy { private dropdownSubscription: Subscription; + contextMenu: MenuItem[]; + selectedMenuItem: TreeNode; + selectedEndItem: string; filesTree: TreeNode[]; constructor( private treeService: TreeService, - private nodeService: NodeService, private endItemService: EndItemService, - private geiaService: GeiaService + private geiaService: GeiaService, + private resourceService: ResourceService ) { } ngOnInit() { @@ -31,7 +34,6 @@ export class TreeComponent implements OnInit, OnDestroy { const xbs = await this.geiaService.getTopLevelXBs(xa).toPromise(); this.filesTree = this.mapXBsToTree(xbs); }); - // this.nodeService.getFiles().then(files => (this.filesTree = files)); } nodeSelect(event: { node: TreeNode }) { @@ -52,20 +54,52 @@ export class TreeComponent implements OnInit, OnDestroy { event.node.children = ret; } + nodeContextMenuSelect(event: { originalEvent: MouseEvent, node: TreeNode }) { + this.selectedMenuItem = event.node; + + const renderModelItem: MenuItem = { + label: 'View 3D Model', + icon: 'pi pi-info-circle', + command: async () => { + const smgName = this.getSmgName(this.endItemService.getFullEndItem(), this.selectedMenuItem.data.geia.lcn); + const res = await this.resourceService.getResourceSmg(smgName, { + setFocusedView: this.selectedMenuItem.data.viewName + }).toPromise(); + const element = document.createElement('a'); + element.href = URL.createObjectURL(new Blob([res])); + element.download = smgName; + element.click(); + } + }; + + if (event.node.data.type !== 'XB') { + renderModelItem.disabled = true; + } + + this.contextMenu = [ + renderModelItem + ]; + } + ngOnDestroy() { this.dropdownSubscription.unsubscribe(); } mapXBsToTree(xbs: any[]): TreeNode[] { const lcnStructure = this.endItemService.getFullEndItem().lcnStructure; - return xbs.map(xb => ({ - label: `${this.lcnToString(xb.lcn, lcnStructure)} ${xb.lcnNomenclature}`, - leaf: this.isXBLeaf(xb), - data: { - geia: xb, - pdfName: 'radar.pdf' - } - })); + return xbs.map(xb => { + const viewName = `${this.lcnToString(xb.lcn, lcnStructure)} ${xb.lcnNomenclature}`; + return { + label: viewName, + leaf: this.isXBLeaf(xb), + data: { + type: 'XB', + geia: xb, + pdfName: 'radar.pdf', + viewName + } + }; + }); } mapCAsToTree(cas: any[]): TreeNode[] { @@ -73,6 +107,7 @@ export class TreeComponent implements OnInit, OnDestroy { label: `${ca.taskCode} ${ca.taskIdentification}`, leaf: true, data: { + type: 'CA', geia: ca, pdfName: 'radar2.pdf' } @@ -89,7 +124,7 @@ export class TreeComponent implements OnInit, OnDestroy { for (let i = 0; i < lcnStructure.length; i++) { const len = Number(lcnStructure.charAt(i)); if (processed < lcn.length) { - acc.push(lcn.substr(processed, processed + len)); + acc.push(lcn.substr(processed, len)); processed += len; } else { break; @@ -98,4 +133,12 @@ export class TreeComponent implements OnInit, OnDestroy { return acc.join('-'); } + getSmgName(endItem: any, lcn: string) { + return `${endItem.endItemAcronymCode}_${this.getTopLevelLcn(lcn, endItem.lcnStructure)}.smg`; + } + + getTopLevelLcn(lcn: string, lcnStructure: string) { + return lcn.substr(0, Number(lcnStructure.charAt(0))); + } + } diff --git a/src/app/model/TransformerOptions.ts b/src/app/model/TransformerOptions.ts new file mode 100644 index 0000000..1426809 --- /dev/null +++ b/src/app/model/TransformerOptions.ts @@ -0,0 +1,3 @@ +export interface TransformerOptions { + setFocusedView?: string; +} diff --git a/src/app/services/api/api.service.ts b/src/app/services/api/api.service.ts index 74e73e3..cfc5005 100644 --- a/src/app/services/api/api.service.ts +++ b/src/app/services/api/api.service.ts @@ -13,8 +13,8 @@ export class APIService { return this.http.get(`${this.baseURL}/${endpoint}`, options); } - _post(endpoint: string, body: any) { - return this.http.post(`${this.baseURL}/${endpoint}`, body); + _post(endpoint: string, body: any, options?: any) { + return this.http.post(`${this.baseURL}/${endpoint}`, body, options); } _put(endpoint: string, body: any) { diff --git a/src/app/services/api/resource.service.ts b/src/app/services/api/resource.service.ts index e6cef09..276f140 100644 --- a/src/app/services/api/resource.service.ts +++ b/src/app/services/api/resource.service.ts @@ -1,6 +1,7 @@ import { APIService } from './api.service'; import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; +import { TransformerOptions } from 'src/app/model/TransformerOptions'; @Injectable({ providedIn: 'root' @@ -8,6 +9,8 @@ import { HttpClient } from '@angular/common/http'; export class ResourceService extends APIService { baseEndpoint = 'resources'; + pdfEndpoint = 'pdf'; + smgEndpoint = 'smg'; constructor( http: HttpClient @@ -19,8 +22,8 @@ export class ResourceService extends APIService { return super._get(`${this.baseEndpoint}/${endpoint}`, options); } - post(endpoint: string, body: any) { - return super._post(`${this.baseEndpoint}/${endpoint}`, body); + post(endpoint: string, body: any, options?: any) { + return super._post(`${this.baseEndpoint}/${endpoint}`, body, options); } put(endpoint: string, body: any) { @@ -35,7 +38,13 @@ export class ResourceService extends APIService { if (key == null) { throw new TypeError('Key must not be null!'); } - return this.get(`pdf/${key}`, { + return this.get(`${this.pdfEndpoint}/${key}`, { + responseType: 'arraybuffer' + }); + } + + getResourceSmg(key: string, transformerOptions?: TransformerOptions) { + return this.post(`${this.smgEndpoint}/${key}`, transformerOptions, { responseType: 'arraybuffer' }); }