diff options
20 files changed, 783 insertions, 392 deletions
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.html index 2b6ba4c63..879b9b94a 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.html @@ -103,7 +103,7 @@ <span>Download</span> </a> - <a data-target="#removePackageModal" data-toggle="modal" class="action-button"> + <a data-target="#removePackageModal" data-toggle="modal" class="action-button delete"> <i class="icon-delete-sm" aria-hidden="true"></i> <span>Delete</span> </a> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.ts index 449312f99..2b0521bb2 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/configuration-dashboard/configuration-dashboard.component.ts @@ -267,6 +267,10 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl goToDesignerMode(id) { // this.designerService.setActionName(this.customActionName); + this.packageCreationStore.state$.subscribe(cba => { + console.log(cba); + sessionStorage.setItem('cba', this.packageCreationUtils.transformToJson(cba)); + }); this.router.navigate(['/packages/designer', id, {actionName: this.customActionName}]); } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html index 6a432fec8..4c0835741 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html @@ -89,7 +89,7 @@ <div class="dropdown-text">Save</div> <ul class="dropdown-content"> <li> - <a href="">Save</a> + <a (click)="saveBluePrint()">Save</a> </li> <li> <a href="">Save & Deploy</a> @@ -638,4 +638,4 @@ </div> </ng-sidebar> -</ng-sidebar-container>
\ No newline at end of file +</ng-sidebar-container> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts index 9462caf68..e4bcdfe7a 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts @@ -5,6 +5,8 @@ Copyright (C) 2019 Orange. All rights reserved. =================================================================== Modification Copyright (c) 2020 IBM =================================================================== +Modification Copyright (c) 2020 Orange +=================================================================== Unless otherwise specified, all software contained herein is licensed under the Apache License, Version 2.0 (the License); @@ -23,348 +25,403 @@ limitations under the License. import dagre from 'dagre'; import graphlib from 'graphlib'; -import { Component, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core'; +import {Component, OnDestroy, OnInit, ViewEncapsulation} from '@angular/core'; import * as joint from 'jointjs'; import './jointjs/elements/palette.function.element'; import './jointjs/elements/action.element'; import './jointjs/elements/board.function.element'; -import { DesignerStore } from './designer.store'; -import { ActionElementTypeName } from 'src/app/common/constants/app-constants'; -import { GraphUtil } from './graph.util'; -import { GraphGenerator } from './graph.generator.util'; -import { FunctionsStore } from './functions.store'; -import { Subject, empty } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; -import { distinctUntilChanged } from 'rxjs/operators'; -import { BluePrintDetailModel } from '../model/BluePrint.detail.model'; -import { ActivatedRoute } from '@angular/router'; -import { DesignerService } from './designer.service'; -import { isDefined } from '@angular/compiler/src/util'; +import {DesignerStore} from './designer.store'; +import {ActionElementTypeName} from 'src/app/common/constants/app-constants'; +import {GraphUtil} from './graph.util'; +import {GraphGenerator} from './graph.generator.util'; +import {FunctionsStore} from './functions.store'; +import {Subject} from 'rxjs'; +import {distinctUntilChanged, takeUntil} from 'rxjs/operators'; +import {BluePrintDetailModel} from '../model/BluePrint.detail.model'; +import {ActivatedRoute} from '@angular/router'; +import {DesignerService} from './designer.service'; +import {FilesContent, FolderNodeElement} from '../package-creation/mapping-models/metadata/MetaDataTab.model'; +import {PackageCreationModes} from '../package-creation/creationModes/PackageCreationModes'; +import {PackageCreationBuilder} from '../package-creation/creationModes/PackageCreationBuilder'; +import {PackageCreationStore} from '../package-creation/package-creation.store'; +import {PackageCreationService} from '../package-creation/package-creation.service'; +import {PackageCreationUtils} from '../package-creation/package-creation.utils'; +import * as JSZip from 'jszip'; +import {CBAPackage} from '../package-creation/mapping-models/CBAPacakge.model'; @Component({ - selector: 'app-designer', - templateUrl: './designer.component.html', - styleUrls: ['./designer.component.css'], - encapsulation: ViewEncapsulation.None + selector: 'app-designer', + templateUrl: './designer.component.html', + styleUrls: ['./designer.component.css'], + encapsulation: ViewEncapsulation.None }) export class DesignerComponent implements OnInit, OnDestroy { - controllerSideBar: boolean; - attributesSideBar: boolean; - functionAttributeSidebar: boolean; - viewedPackage: BluePrintDetailModel = new BluePrintDetailModel(); - customActionName: string; - showAction: boolean; - cl = 'editBar'; - - boardGraph: joint.dia.Graph; - boardPaper: joint.dia.Paper; - - paletteGraph: joint.dia.Graph; - palettePaper: joint.dia.Paper; - ngUnsubscribe = new Subject(); - opt = { tx: 100, ty: 100 }; - - constructor( - private designerStore: DesignerStore, - private functionStore: FunctionsStore, - private graphUtil: GraphUtil, - private graphGenerator: GraphGenerator, - private route: ActivatedRoute, - private designerService: DesignerService) { - this.controllerSideBar = true; - this.attributesSideBar = false; - this.showAction = false; - this.functionAttributeSidebar = false; - - } - _toggleSidebar1() { - this.controllerSideBar = !this.controllerSideBar; - if (this.controllerSideBar === false) { - this.cl = 'editBar2'; + controllerSideBar: boolean; + attributesSideBar: boolean; + functionAttributeSidebar: boolean; + viewedPackage: BluePrintDetailModel = new BluePrintDetailModel(); + customActionName: string; + showAction: boolean; + cl = 'editBar'; + + boardGraph: joint.dia.Graph; + boardPaper: joint.dia.Paper; + + paletteGraph: joint.dia.Graph; + palettePaper: joint.dia.Paper; + ngUnsubscribe = new Subject(); + opt = {tx: 100, ty: 100}; + filesData: any = []; + folder: FolderNodeElement = new FolderNodeElement(); + zipFile: JSZip = new JSZip(); + + constructor( + private designerStore: DesignerStore, + private functionStore: FunctionsStore, + private packageCreationStore: PackageCreationStore, + private packageCreationUtils: PackageCreationUtils, + private graphUtil: GraphUtil, + private graphGenerator: GraphGenerator, + private route: ActivatedRoute, + private designerService: DesignerService, + private packageCreationService: PackageCreationService) { + this.controllerSideBar = true; + this.attributesSideBar = false; + this.showAction = false; + this.functionAttributeSidebar = false; + } - if (this.controllerSideBar === true) { - this.cl = 'editBar'; + + _toggleSidebar1() { + this.controllerSideBar = !this.controllerSideBar; + if (this.controllerSideBar === false) { + this.cl = 'editBar2'; + } + if (this.controllerSideBar === true) { + this.cl = 'editBar'; + } } - } - _toggleSidebar2() { - this.attributesSideBar = !this.attributesSideBar; - } - // private _toggleSidebar3() { - // this.functionAttributeSidebar = !this.functionAttributeSidebar; - // } - - - /** - * - There is a board (main paper) that will the action and function selected from the palette - * itmes in this board will be used to create tosca workflow and node templates - * - There is also palette , whis contains all the possible functions and actions - * that can be dragged into the board - * - There is also a fly paper , which is temporarliy paper created on the fly - * when items is dragged from the palette- and it's deleted when the item is dropped over - * the board. - * for more info about the drag and drop algorithem used please visit the following link: - * https://stackoverflow.com/a/36932973/1340034 - */ - - ngOnInit() { - this.customActionName = this.route.snapshot.paramMap.get('actionName'); - if (this.customActionName !== '') { - this.showAction = true; + + _toggleSidebar2() { + this.attributesSideBar = !this.attributesSideBar; } - this.initializeBoard(); - this.initializePalette(); - this.stencilPaperEventListeners(); - const id = this.route.snapshot.paramMap.get('id'); - this.designerService.getPagedPackages(id).subscribe( - (bluePrintDetailModels) => { - if (bluePrintDetailModels) { - this.viewedPackage = bluePrintDetailModels[0]; - } - }); + + // private _toggleSidebar3() { + // this.functionAttributeSidebar = !this.functionAttributeSidebar; + // } + + /** - * the code to retrieve from server is commented + * - There is a board (main paper) that will the action and function selected from the palette + * itmes in this board will be used to create tosca workflow and node templates + * - There is also palette , whis contains all the possible functions and actions + * that can be dragged into the board + * - There is also a fly paper , which is temporarliy paper created on the fly + * when items is dragged from the palette- and it's deleted when the item is dropped over + * the board. + * for more info about the drag and drop algorithem used please visit the following link: + * https://stackoverflow.com/a/36932973/1340034 */ - this.functionStore.state$ - .pipe( - distinctUntilChanged((a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)), - takeUntil(this.ngUnsubscribe)) - .subscribe(state => { - - if (state.serverFunctions) { - console.log('inside subscriotn on functions store -->', state.serverFunctions); - console.log(state); - // this.viewedFunctions = state.functions; - const list = state.serverFunctions; - - const cells = this.graphUtil.buildPaletteGraphFromList(list); - this.paletteGraph.resetCells(cells); - - let idx = 0; - cells.forEach(cell => { - cell.translate(5, (cell.attributes.size.height + 5) * idx++); - }); + + ngOnInit() { + this.customActionName = this.route.snapshot.paramMap.get('actionName'); + if (this.customActionName !== '') { + this.showAction = true; } - }); - - this.designerStore.state$ - .pipe( - distinctUntilChanged((a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)), - takeUntil(this.ngUnsubscribe)) - .subscribe(state => { - if (state.sourceContent) { - console.log('inside desinger.component---> ', state); - // generate graph from store objects if exist - const topologtTemplate = JSON.parse(state.sourceContent); - console.log(topologtTemplate); - delete state.sourceContent; - this.graphGenerator.populate(topologtTemplate, this.boardGraph); - - console.log('all cells', this.boardGraph.getCells()); - /** - * auto arrange elements in graph - * https://resources.jointjs.com/docs/jointjs/v3.1/joint.html#layout.DirectedGraph - */ - joint.layout.DirectedGraph.layout(this.boardGraph.getCells(), { - dagre, - graphlib, - setLinkVertices: false, - marginX: 10, - marginY: 10, - clusterPadding: { top: 100, left: 30, right: 10, bottom: 100 }, - rankDir: 'TB' - }); + this.initializeBoard(); + this.initializePalette(); + this.stencilPaperEventListeners(); + const id = this.route.snapshot.paramMap.get('id'); + this.designerService.getPagedPackages(id).subscribe( + (bluePrintDetailModels) => { + if (bluePrintDetailModels) { + this.viewedPackage = bluePrintDetailModels[0]; + } + }); + /** + * the code to retrieve from server is commented + */ + this.functionStore.state$ + .pipe( + distinctUntilChanged((a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)), + takeUntil(this.ngUnsubscribe)) + .subscribe(state => { + + if (state.serverFunctions) { + console.log('inside subscriotn on functions store -->', state.serverFunctions); + console.log(state); + // this.viewedFunctions = state.functions; + const list = state.serverFunctions; + + const cells = this.graphUtil.buildPaletteGraphFromList(list); + this.paletteGraph.resetCells(cells); + + let idx = 0; + cells.forEach(cell => { + cell.translate(5, (cell.attributes.size.height + 5) * idx++); + }); + } + }); + + this.designerStore.state$ + .pipe( + distinctUntilChanged((a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)), + takeUntil(this.ngUnsubscribe)) + .subscribe(state => { + if (state.sourceContent) { + console.log('inside desinger.component---> ', state); + // generate graph from store objects if exist + const topologtTemplate = JSON.parse(state.sourceContent); + console.log(topologtTemplate); + delete state.sourceContent; + this.graphGenerator.populate(topologtTemplate, this.boardGraph); + + console.log('all cells', this.boardGraph.getCells()); + /** + * auto arrange elements in graph + * https://resources.jointjs.com/docs/jointjs/v3.1/joint.html#layout.DirectedGraph + */ + joint.layout.DirectedGraph.layout(this.boardGraph.getCells(), { + dagre, + graphlib, + setLinkVertices: false, + marginX: 10, + marginY: 10, + clusterPadding: {top: 100, left: 30, right: 10, bottom: 100}, + rankDir: 'TB' + }); + } + }); + + // action triggering + this.functionStore.retrieveFuntions(); + + } + + initializePalette() { + if (!this.paletteGraph) { + this.paletteGraph = new joint.dia.Graph(); + this.palettePaper = new joint.dia.Paper({ + el: $('#palette-paper'), + model: this.paletteGraph, + width: 318, + height: $('#palette-paper').height(), + // background: { + // color: 'rgba(0, 255, 0, 0.3)' + // }, + interactive: false + // elements in paletter need to be fixed, please refer to flying paper concept + }); } - }); - - // action triggering - this.functionStore.retrieveFuntions(); - - } - - initializePalette() { - if (!this.paletteGraph) { - this.paletteGraph = new joint.dia.Graph(); - this.palettePaper = new joint.dia.Paper({ - el: $('#palette-paper'), - model: this.paletteGraph, - width: 318, - height: $('#palette-paper').height(), - // background: { - // color: 'rgba(0, 255, 0, 0.3)' - // }, - interactive: false - // elements in paletter need to be fixed, please refer to flying paper concept - }); } - } - - initializeBoard() { - if (!this.boardGraph) { - console.log('initializeBoard...'); - this.boardGraph = new joint.dia.Graph(); - this.boardPaper = new joint.dia.Paper({ - el: $('#board-paper'), - model: this.boardGraph, - // height: 720, - // width: 1100, - gridSize: 10, - drawGrid: true, - // background: { - // color: 'rgba(0, 255, 0, 0.3)' - // }, - cellViewNamespace: joint.shapes - }); - - this.boardPaper.on('all', element => { - // console.log(element); - }); - - this.boardPaper.on('link:pointerdown', link => { - console.log(link); - }); - - this.boardPaper.on('element:pointerdown', element => { - // this.modelSelected.emit(element.model.get('model')); - }); - - this.boardPaper.on('blank:pointerclick', () => { - // this.selectedModel = undefined; - }); - - this.boardGraph.on('change:position', (cell) => { - - const parentId = cell.get('parent'); - if (!parentId) { - // this is action - return; + + initializeBoard() { + if (!this.boardGraph) { + console.log('initializeBoard...'); + this.boardGraph = new joint.dia.Graph(); + this.boardPaper = new joint.dia.Paper({ + el: $('#board-paper'), + model: this.boardGraph, + // height: 720, + // width: 1100, + gridSize: 10, + drawGrid: true, + // background: { + // color: 'rgba(0, 255, 0, 0.3)' + // }, + cellViewNamespace: joint.shapes + }); + + this.boardPaper.on('all', element => { + // console.log(element); + }); + + this.boardPaper.on('link:pointerdown', link => { + console.log(link); + }); + + this.boardPaper.on('element:pointerdown', element => { + // this.modelSelected.emit(element.model.get('model')); + }); + + this.boardPaper.on('blank:pointerclick', () => { + // this.selectedModel = undefined; + }); + + this.boardGraph.on('change:position', (cell) => { + + const parentId = cell.get('parent'); + if (!parentId) { + // this is action + return; + } + + const parent = this.boardGraph.getCell(parentId); + + const parentBbox = parent.getBBox(); + const cellBbox = cell.getBBox(); + if (parentBbox.containsPoint(cellBbox.origin()) && + parentBbox.containsPoint(cellBbox.topRight()) && + parentBbox.containsPoint(cellBbox.corner()) && + parentBbox.containsPoint(cellBbox.bottomLeft())) { + + // All the four corners of the child are inside + // the parent area. + return; + } + + // Revert the child position. + cell.set('position', cell.previous('position')); + }); } + console.log('done initializing Board...'); + } - const parent = this.boardGraph.getCell(parentId); + insertCustomActionIntoBoard() { + console.log('saving action to store action workflow....'); + const actionName = this.graphUtil.generateNewActionName(); + this.graphUtil.createCustomActionWithName(actionName, this.boardGraph); + this.designerStore.addDeclarativeWorkFlow(actionName); + } - const parentBbox = parent.getBBox(); - const cellBbox = cell.getBBox(); - if (parentBbox.containsPoint(cellBbox.origin()) && - parentBbox.containsPoint(cellBbox.topRight()) && - parentBbox.containsPoint(cellBbox.corner()) && - parentBbox.containsPoint(cellBbox.bottomLeft())) { + stencilPaperEventListeners() { + this.palettePaper.on('cell:pointerdown', (draggedCell, pointerDownEvent, x, y) => { - // All the four corners of the child are inside - // the parent area. - return; - } + $('body').append(` + <div id="flyPaper" + style="position:fixed;z-index:100;opacity:.7;pointer-event:none;background-color: transparent !important;"></div>` + ); + const flyGraph = new joint.dia.Graph(); + const flyPaper = new joint.dia.Paper({ + el: $('#flyPaper'), + model: flyGraph, + interactive: true + }); + const flyShape = draggedCell.model.clone(); + const pos = draggedCell.model.position(); + const offset = { + x: x - pos.x, + y: y - pos.y + }; + + flyShape.position(0, 0); + flyGraph.addCell(flyShape); + $('#flyPaper').offset({ + left: pointerDownEvent.pageX - offset.x, + top: pointerDownEvent.pageY - offset.y + }); + $('body').on('mousemove.fly', mouseMoveEvent => { + $('#flyPaper').offset({ + left: mouseMoveEvent.pageX - offset.x, + top: mouseMoveEvent.pageY - offset.y + }); + }); + + $('body').on('mouseup.fly', mouseupEvent => { + const mouseupX = mouseupEvent.pageX; + const mouseupY = mouseupEvent.pageY; + const target = this.boardPaper.$el.offset(); + // Dropped over paper ? + if (mouseupX > target.left && + mouseupX < target.left + this.boardPaper.$el.width() && + mouseupY > target.top && y < target.top + this.boardPaper.$el.height()) { + const functionType = this.graphUtil.getFunctionTypeFromPaletteFunction(flyShape); + // step name is CDS realted terminology, please refer to tosca types + const stepName = functionType; + const functionElementForBoard = this.graphUtil.dropFunctionOverActionWithPosition( + stepName, functionType, + mouseupX, mouseupY, + target, offset, + this.boardGraph); + + const parentCell = this.graphUtil.getParent(functionElementForBoard, this.boardPaper); + + if (parentCell && + parentCell.model.attributes.type === ActionElementTypeName && + this.graphUtil.canEmpedMoreChildern(parentCell.model, this.boardGraph)) { + + if (this.graphUtil.isEmptyParent(parentCell.model)) { + // first function in action + const actionName = parentCell.model.attributes.attrs['#label'].text; + this.designerStore.addStepToDeclarativeWorkFlow(actionName, stepName, functionType); + if (functionType === 'dg-generic') { + this.designerStore.addDgGenericNodeTemplate(stepName); + } else { + this.designerStore.addNodeTemplate(stepName, functionType); + } + } else { + // second action means there was a dg-generic node before + this.designerStore.addNodeTemplate(stepName, functionType); + // this will fail if multiple dg-generic were added + // TODO prevent multi functions of the same type inside the same action + const dgGenericNode = this.graphUtil.getDgGenericChild(parentCell.model, this.boardGraph)[0]; + const dgGenericNodeName = this.graphUtil.getFunctionNameFromBoardFunction(dgGenericNode); + this.designerStore.addDgGenericDependency(dgGenericNodeName, stepName); + } + + + // Prevent recursive embedding. + if (parentCell && + parentCell.model.get('parent') !== functionElementForBoard.id) { + parentCell.model.embed(functionElementForBoard); + } + } else { + console.log('function dropped outside action or not allowed, rolling back...'); + alert('function dropped outside action or not allowed, rolling back...'); + functionElementForBoard.remove(); + } + } + $('body').off('mousemove.fly').off('mouseup.fly'); + // flyShape.remove(); + $('#flyPaper').remove(); + }); + }); + console.log('done stencilPaperEventListeners()...'); + } - // Revert the child position. - cell.set('position', cell.previous('position')); - }); + ngOnDestroy() { + this.ngUnsubscribe.next(); + this.ngUnsubscribe.complete(); } - console.log('done initializing Board...'); - } - insertCustomActionIntoBoard() { - console.log('saving action to store action workflow....'); - const actionName = this.graphUtil.generateNewActionName(); - this.graphUtil.createCustomActionWithName(actionName, this.boardGraph); - this.designerStore.addDeclarativeWorkFlow(actionName); - } + saveBluePrint() { + let cbaPackage: CBAPackage = JSON.parse(sessionStorage.getItem('cba')); + console.log(cbaPackage); + FilesContent.clear(); + let packageCreationModes: PackageCreationModes; + cbaPackage = PackageCreationModes.mapModeType(cbaPackage); + cbaPackage.metaData = PackageCreationModes.setEntryPoint(cbaPackage.metaData); + packageCreationModes = PackageCreationBuilder.getCreationMode(cbaPackage); + this.designerStore.state$.subscribe(state => { + cbaPackage.templateTopology.content = this.packageCreationUtils.transformToJson(state.template); + }); + packageCreationModes.execute(cbaPackage, this.packageCreationUtils); + this.filesData.push(this.folder.TREE_DATA); + this.saveBluePrintToDataBase(); - stencilPaperEventListeners() { - this.palettePaper.on('cell:pointerdown', (draggedCell, pointerDownEvent, x, y) => { + } - $('body').append(` - <div id="flyPaper" - style="position:fixed;z-index:100;opacity:.7;pointer-event:none;background-color: transparent !important;"></div>` - ); - const flyGraph = new joint.dia.Graph(); - const flyPaper = new joint.dia.Paper({ - el: $('#flyPaper'), - model: flyGraph, - interactive: true - }); - const flyShape = draggedCell.model.clone(); - const pos = draggedCell.model.position(); - const offset = { - x: x - pos.x, - y: y - pos.y - }; - - flyShape.position(0, 0); - flyGraph.addCell(flyShape); - $('#flyPaper').offset({ - left: pointerDownEvent.pageX - offset.x, - top: pointerDownEvent.pageY - offset.y - }); - $('body').on('mousemove.fly', mouseMoveEvent => { - $('#flyPaper').offset({ - left: mouseMoveEvent.pageX - offset.x, - top: mouseMoveEvent.pageY - offset.y + create() { + this.zipFile = new JSZip(); + FilesContent.getMapOfFilesNamesAndContent().forEach((value, key) => { + this.zipFile.folder(key.split('/')[0]); + this.zipFile.file(key, value); }); - }); - - $('body').on('mouseup.fly', mouseupEvent => { - const mouseupX = mouseupEvent.pageX; - const mouseupY = mouseupEvent.pageY; - const target = this.boardPaper.$el.offset(); - // Dropped over paper ? - if (mouseupX > target.left && - mouseupX < target.left + this.boardPaper.$el.width() && - mouseupY > target.top && y < target.top + this.boardPaper.$el.height()) { - const functionType = this.graphUtil.getFunctionTypeFromPaletteFunction(flyShape); - // step name is CDS realted terminology, please refer to tosca types - const stepName = functionType; - const functionElementForBoard = this.graphUtil.dropFunctionOverActionWithPosition( - stepName, functionType, - mouseupX, mouseupY, - target, offset, - this.boardGraph); - - const parentCell = this.graphUtil.getParent(functionElementForBoard, this.boardPaper); - - if (parentCell && - parentCell.model.attributes.type === ActionElementTypeName && - this.graphUtil.canEmpedMoreChildern(parentCell.model, this.boardGraph)) { - - if (this.graphUtil.isEmptyParent(parentCell.model)) { - // first function in action - const actionName = parentCell.model.attributes.attrs['#label'].text; - this.designerStore.addStepToDeclarativeWorkFlow(actionName, stepName, functionType); - if (functionType === 'dg-generic') { - this.designerStore.addDgGenericNodeTemplate(stepName); - } else { - this.designerStore.addNodeTemplate(stepName, functionType); - } - } else { - // second action means there was a dg-generic node before - this.designerStore.addNodeTemplate(stepName, functionType); - // this will fail if multiple dg-generic were added - // TODO prevent multi functions of the same type inside the same action - const dgGenericNode = this.graphUtil.getDgGenericChild(parentCell.model, this.boardGraph)[0]; - const dgGenericNodeName = this.graphUtil.getFunctionNameFromBoardFunction(dgGenericNode); - this.designerStore.addDgGenericDependency(dgGenericNodeName, stepName); - } - - - // Prevent recursive embedding. - if (parentCell && - parentCell.model.get('parent') !== functionElementForBoard.id) { - parentCell.model.embed(functionElementForBoard); - } - } else { - console.log('function dropped outside action or not allowed, rolling back...'); - alert('function dropped outside action or not allowed, rolling back...'); - functionElementForBoard.remove(); - } - } - $('body').off('mousemove.fly').off('mouseup.fly'); - // flyShape.remove(); - $('#flyPaper').remove(); - }); - }); - console.log('done stencilPaperEventListeners()...'); - } - - ngOnDestroy() { - this.ngUnsubscribe.next(); - this.ngUnsubscribe.complete(); - } + + } + + saveBluePrintToDataBase() { + this.create(); + this.zipFile.generateAsync({type: 'blob'}) + .then(blob => { + this.packageCreationService.savePackage(blob).subscribe( + bluePrintDetailModels => { + console.log('success'); + }, error => { + // this.toastService.error('error happened when editing ' + error.message); + console.log('Error -' + error.message); + }); + }); + } } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/DesignerCreationMode.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/DesignerCreationMode.ts index f739ceb2e..b8938043c 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/DesignerCreationMode.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/DesignerCreationMode.ts @@ -37,9 +37,11 @@ export class DesignerCreationMode extends PackageCreationModes { } private createDefinitionsFolder(cbaPackage: CBAPackage, packageCreationUtils: PackageCreationUtils) { - cbaPackage.definitions.imports.forEach((valueOfFile, key) => { - FilesContent.putData(key, valueOfFile); - }); + if (cbaPackage.definitions.imports && cbaPackage.definitions.imports.size > 0) { + cbaPackage.definitions.imports.forEach((valueOfFile, key) => { + FilesContent.putData(key, valueOfFile); + }); + } const filenameEntry = 'Definitions/' + cbaPackage.metaData.name + '.json'; const vlbDefinition: VlbDefinition = new VlbDefinition(); @@ -51,28 +53,34 @@ export class DesignerCreationMode extends PackageCreationModes { metadata['author-email'] = 'shaaban.eltanany.ext@orange.com'; metadata['user-groups'] = 'test'; metadata.template_description = cbaPackage.metaData.description; - cbaPackage.metaData.mapOfCustomKey.forEach((customKeyValue, key) => { - metadata[key] = customKeyValue; - }); + if (cbaPackage.metaData.mapOfCustomKey && cbaPackage.metaData.mapOfCustomKey.size > 0) { + cbaPackage.metaData.mapOfCustomKey.forEach((customKeyValue, key) => { + metadata[key] = customKeyValue; + }); + } // create Tags let fullTags = ''; let setCount = 0; - cbaPackage.metaData.templateTags.forEach(val => { - setCount++; - if (setCount === cbaPackage.metaData.templateTags.size) { - fullTags += val; - } else { - fullTags += val + ', '; - } - }); + if (cbaPackage.metaData.templateTags && cbaPackage.metaData.templateTags.size > 0) { + cbaPackage.metaData.templateTags.forEach(val => { + setCount++; + if (setCount === cbaPackage.metaData.templateTags.size) { + fullTags += val; + } else { + fullTags += val + ', '; + } + }); + } metadata.template_tags = fullTags; vlbDefinition.metadata = metadata; const files: Import[] = []; - cbaPackage.definitions.imports.forEach((valueOfFile, key) => { - if (!key.includes(cbaPackage.metaData.name)) { - files.push({file: key}); - } - }); + if (cbaPackage.definitions.imports && cbaPackage.definitions.imports.size > 0) { + cbaPackage.definitions.imports.forEach((valueOfFile, key) => { + if (!key.includes(cbaPackage.metaData.name)) { + files.push({file: key}); + } + }); + } console.log(vlbDefinition); vlbDefinition.imports = files; console.log(cbaPackage.definitions.dslDefinition.content); @@ -83,6 +91,7 @@ export class DesignerCreationMode extends PackageCreationModes { vlbDefinition.topology_template = JSON.parse(cbaPackage.templateTopology.content); } console.log(vlbDefinition); + const value = packageCreationUtils.transformToJson(vlbDefinition); FilesContent.putData(filenameEntry, value); console.log('hello there'); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/PackageCreationModes.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/PackageCreationModes.ts index 6b80358fd..8b82cc0eb 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/PackageCreationModes.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/creationModes/PackageCreationModes.ts @@ -1,7 +1,7 @@ -import { CBAPackage } from '../mapping-models/CBAPacakge.model'; -import { ModeType } from '../mapping-models/ModeType'; -import { FilesContent, MetaDataTabModel } from '../mapping-models/metadata/MetaDataTab.model'; -import { PackageCreationUtils } from '../package-creation.utils'; +import {CBAPackage} from '../mapping-models/CBAPacakge.model'; +import {ModeType} from '../mapping-models/ModeType'; +import {FilesContent, MetaDataTabModel} from '../mapping-models/metadata/MetaDataTab.model'; +import {PackageCreationUtils} from '../package-creation.utils'; export abstract class PackageCreationModes { @@ -21,25 +21,28 @@ export abstract class PackageCreationModes { public static mapModeType(cbaPackage: CBAPackage) { console.log(cbaPackage.metaData.mode); - if (cbaPackage.metaData.mode.includes('Scripting')) { - cbaPackage.metaData.mode = ModeType.Scripting; - } else if (cbaPackage.metaData.mode.includes('Designer') || cbaPackage.metaData.mode.includes('DEFAULT') ) { - cbaPackage.metaData.mode = ModeType.Designer; - } else { - cbaPackage.metaData.mode = ModeType.Generic; - } + /* if (cbaPackage.metaData.mode.includes('Scripting')) { + cbaPackage.metaData.mode = ModeType.Scripting; + } else if (cbaPackage.metaData.mode.includes('Designer') || cbaPackage.metaData.mode.includes('DEFAULT') ) { + cbaPackage.metaData.mode = ModeType.Designer; + } else { + cbaPackage.metaData.mode = ModeType.Generic; + }*/ + cbaPackage.metaData.mode = ModeType.Designer; return cbaPackage; } getValueOfMetaData(metaDataTab: MetaDataTabModel): string { let tags = ''; let count = 0; - for (const tag of metaDataTab.templateTags) { - count++; - if (count === metaDataTab.templateTags.size) { - tags += tag; - } else { - tags += tag + ', '; + if (metaDataTab.templateTags && metaDataTab.templateTags.size > 0) { + for (const tag of metaDataTab.templateTags) { + count++; + if (count === metaDataTab.templateTags.size) { + tags += tag; + } else { + tags += tag + ', '; + } } } return 'TOSCA-Meta-File-Version: 1.0.0\n' + diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.ts index 0e809674a..20cee7340 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/metadata-tab/metadata-tab.component.ts @@ -48,7 +48,6 @@ export class MetadataTabComponent implements OnInit { this.tags = element.metaData.templateTags; this.tags.delete(''); this.metaDataTab.templateTags = this.tags; - console.log(element); if (element.metaData.mode && element.metaData.mode.includes('DEFAULT')) { this.metaDataTab.mode = 'Designer Mode'; this.modeType = this.metaDataTab.mode; @@ -56,8 +55,12 @@ export class MetadataTabComponent implements OnInit { this.customKeysMap = element.metaData.mapOfCustomKey; this.metaDataTab.mapOfCustomKey = this.customKeysMap; + if (this.isNameEditable) { + this.validatePackageNameAndVersion(); + } // this.tags = element.metaData.templateTags; + } }); } @@ -99,6 +102,8 @@ export class MetadataTabComponent implements OnInit { } validatePackageNameAndVersion() { + console.log('in validate'); + console.log('in this.metaDataTab.name' + this.metaDataTab.name); if (this.metaDataTab.name && this.metaDataTab.version) { this.packageCreationService.checkBluePrintNameAndVersion(this.metaDataTab.name, this.metaDataTab.version).then(element => { if (element) { diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation-extraction.service.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation-extraction.service.ts new file mode 100644 index 000000000..31a5c3c35 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation-extraction.service.ts @@ -0,0 +1,130 @@ +import {Injectable, ViewChild} from '@angular/core'; +import {MetaDataTabModel} from './mapping-models/metadata/MetaDataTab.model'; +import {VlbDefinition} from './mapping-models/definitions/VlbDefinition'; +import {DslDefinition} from './mapping-models/CBAPacakge.model'; +import {PackageCreationStore} from './package-creation.store'; +import * as JSZip from 'jszip'; +import {PackageCreationUtils} from './package-creation.utils'; +import {MetadataTabComponent} from './metadata-tab/metadata-tab.component'; +import {DesignerStore} from '../designer/designer.store'; + +@Injectable({ + providedIn: 'root' +}) +export class PackageCreationExtractionService { + + zipFile: JSZip = new JSZip(); + entryDefinitionKeys: string[] = ['template_tags', 'user-groups', + 'author-email', 'template_version', 'template_name', 'template_author', 'template_description']; + @ViewChild(MetadataTabComponent, {static: false}) + metadataTabComponent: MetadataTabComponent; + + constructor(private packageCreationStore: PackageCreationStore, + private packageCreationUtils: PackageCreationUtils, + private designerStore: DesignerStore) { + } + + public extractBlobToStore(blob) { + let packageName = null; + this.zipFile.loadAsync(blob).then((zip) => { + Object.keys(zip.files).filter(fileName => fileName.includes('TOSCA-Metadata/')) + .forEach((filename) => { + zip.files[filename].async('string').then((fileData) => { + if (fileData) { + if (filename.includes('TOSCA-Metadata/')) { + const metaDataTabInfo: MetaDataTabModel = this.getMetaDataTabInfo(fileData); + packageName = metaDataTabInfo.name; + this.setMetaData(metaDataTabInfo); + console.log('found file ' + packageName); + } + } + }); + }); + }); + + this.zipFile.loadAsync(blob).then((zip) => { + Object.keys(zip.files).forEach((filename) => { + zip.files[filename].async('string').then((fileData) => { + console.log(filename); + if (fileData) { + if (filename.includes('Scripts/')) { + this.setScripts(filename, fileData); + } else if (filename.includes('Templates/')) { + if (filename.includes('-mapping.')) { + this.setMapping(filename, fileData); + } else if (filename.includes('-template.')) { + this.setTemplates(filename, fileData); + } + + } else if (filename.includes('Definitions/')) { + this.setImports(filename, fileData, packageName); + } + } + }); + }); + }); + } + + setScripts(filename: string, fileData: any) { + this.packageCreationStore.addScripts(filename, fileData); + } + + setImports(filename: string, fileData: any, packageName: string) { + console.log(filename); + if (filename.includes(packageName)) { + let definition = new VlbDefinition(); + definition = fileData as VlbDefinition; + definition = JSON.parse(fileData); + const dslDefinition = new DslDefinition(); + dslDefinition.content = this.packageCreationUtils.transformToJson(definition.dsl_definitions); + const mapOfCustomKeys = new Map<string, string>(); + for (const metadataKey in definition.metadata) { + if (!this.entryDefinitionKeys.includes(metadataKey + '')) { + mapOfCustomKeys.set(metadataKey + '', definition.metadata[metadataKey + '']); + } + } + this.packageCreationStore.changeDslDefinition(dslDefinition); + this.packageCreationStore.setCustomKeys(mapOfCustomKeys); + this.setPackageDescription(definition.metadata.template_description); + if (definition.topology_template && definition.topology_template.content) { + this.designerStore.saveSourceContent(definition.topology_template.content); + } + + } + this.packageCreationStore.addDefinition(filename, fileData); + + } + + setTemplates(filename: string, fileData: any) { + this.packageCreationStore.addTemplate(filename, fileData); + } + + setMapping(fileName: string, fileData: string) { + this.packageCreationStore.addMapping(fileName, fileData); + } + + setMetaData(metaDataObject: MetaDataTabModel) { + this.packageCreationStore.changeMetaData(metaDataObject); + } + + getMetaDataTabInfo(fileData: string) { + const metaDataTabModel = new MetaDataTabModel(); + const arrayOfLines = fileData.split('\n'); + metaDataTabModel.entryFileName = arrayOfLines[3].split(':')[1]; + metaDataTabModel.name = arrayOfLines[4].split(':')[1]; + metaDataTabModel.version = arrayOfLines[5].split(':')[1]; + metaDataTabModel.mode = arrayOfLines[6].split(':')[1]; + console.log(arrayOfLines[7]); + if (arrayOfLines[7].split(':')) { + metaDataTabModel.templateTags = new Set<string>(arrayOfLines[7].split(':')[1].split(',')); + } + return metaDataTabModel; + } + + private setPackageDescription(templateDescription: string) { + const metaData = this.packageCreationStore.getMetaData(); + metaData.description = templateDescription; + this.setMetaData(metaData); + + } +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.html index a09951cd2..03bbc72f4 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.html @@ -83,8 +83,9 @@ <div class="nav nav-tabs " id="nav-tab" role="tablist"> <a (click)="openTourGuide('metadataTab')" tourAnchor="metadataTab" class="nav-item nav-link active" id="nav-metadata-tab" data-toggle="tab" href="#nav-metadata" role="tab" aria-controls="nav-metadata" - aria-selected="false" autofocus #nameit (focusout)="saveMetaData()" - [classList]="metadataClasses">METADATA</a> + aria-selected="false" autofocus #nameit (focusout)="saveMetaData()" [classList]="metadataClasses">METADATA</a> + + <a (click)="openTourGuide('tm-templateTab')" tourAnchor="tm-templateTab" class="nav-item nav-link" id="nav-template-tab" data-toggle="tab" href="#nav-template" role="tab" aria-controls="nav-template" aria-selected="false">TEMPLATE & @@ -134,4 +135,4 @@ </div> </div> </div> -</div>
\ No newline at end of file +</div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.ts index 6b29ec4fd..f74015956 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.component.ts @@ -34,6 +34,7 @@ import {ToastrService} from 'ngx-toastr'; import {TourService} from 'ngx-tour-md-menu'; import {PackageCreationService} from './package-creation.service'; import {ComponentCanDeactivate} from '../../../../common/core/canDactivate/ComponentCanDeactivate'; +import {DesignerStore} from '../designer/designer.store'; @Component({ @@ -53,7 +54,8 @@ export class PackageCreationComponent extends ComponentCanDeactivate implements private packageCreationUtils: PackageCreationUtils, private router: Router, private tourService: TourService, - private toastService: ToastrService) { + private toastService: ToastrService, + private designerStore: DesignerStore) { super(); } @@ -110,6 +112,7 @@ export class PackageCreationComponent extends ComponentCanDeactivate implements cbaPackage = PackageCreationModes.mapModeType(cbaPackage); cbaPackage.metaData = PackageCreationModes.setEntryPoint(cbaPackage.metaData); packageCreationModes = PackageCreationBuilder.getCreationMode(cbaPackage); + cbaPackage.templateTopology.content = this.designerStore.state.sourceContent; packageCreationModes.execute(cbaPackage, this.packageCreationUtils); this.filesData.push(this.folder.TREE_DATA); this.saveBluePrintToDataBase(); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.service.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.service.ts index bd8360a14..bd0944146 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.service.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.service.ts @@ -84,4 +84,6 @@ export class PackageCreationService { } + + } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.store.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.store.ts index 7b1c6bfb1..bca6903f6 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.store.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/package-creation.store.ts @@ -24,11 +24,7 @@ import {Injectable} from '@angular/core'; import {Store} from '../../../../common/core/stores/Store'; import {CBAPackage, DslDefinition} from './mapping-models/CBAPacakge.model'; -import {PackageCreationService} from './package-creation.service'; import {MetaDataTabModel} from './mapping-models/metadata/MetaDataTab.model'; -import {Observable} from 'rxjs'; -import {ResourceDictionary} from './mapping-models/ResourceDictionary.model'; -import {BluePrintDetailModel} from '../model/BluePrint.detail.model'; import {TemplateTopology} from './mapping-models/definitions/VlbDefinition'; @@ -127,4 +123,8 @@ export class PackageCreationStore extends Store<CBAPackage> { templateTopology }); } + + getMetaData() { + return this.state.metaData; + } } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/guideSteps.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/guideSteps.ts index 5026980de..6601e2f17 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/guideSteps.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/guideSteps.ts @@ -23,28 +23,28 @@ export const steps = [ }, { anchorId: 'metadataTab', - content: 'Set your package basic information', + content: 'It captures the model entities that compose the cba package name, version, description and searchable tags.', title: 'Metadata Tab', route: 'packages/createPackage' }, { anchorId: 'mt-packageName', - content: 'Set your package name (required)', + content: 'Set your package name (required).', title: 'Package name', }, { anchorId: 'mt-packageVersion', - content: 'Set your package version like 1.0.0 (required)', + content: 'Set your package version like 1.0.0 (required).', title: 'Package version', }, { anchorId: 'mt-packageDescription', - content: 'Set your package description (required)', + content: 'Set your package description (required).', title: 'Package description', }, { anchorId: 'mt-packageTags', - content: 'Set your package Tags (Optional)', + content: 'Set your package Tags (Optional).', title: 'Package tag', }, // { @@ -55,66 +55,66 @@ export const steps = [ // Temaplate & Mapping { anchorId: 'tm-templateTab', - content: 'Create Your \'Template & Mapping \' files', + content: 'A template is an artifact, and uses Modeling Concepts#artifact-mapping-resource and artifact-template-velocity. ', title: 'Temaplate & Mapping', stepId: 'tm-templateTab' }, { anchorId: 'tm-templateName', - content: 'Set your Template & Mapping Name', + content: 'Set your Template & Mapping Name.', title: 'Temaplte & Mapping name', stepId: 'tm-templateName' }, { anchorId: 'tm-templateType', - content: 'Set your Template Type', + content: 'Set your Template Type.', title: 'Temaplte Type', }, { anchorId: 'tm-templateContent', - content: 'Click \'Import File\' to get content from a file, or write template content manually', + content: 'Click \'Import File\' to get content from a file, or write template content manually.', title: 'Template Content', }, { anchorId: 'tm-mappingContent', - content: 'Set your mapping content from the current template, or from an external file (XML, CSV)', + content: 'Set your mapping content from the current template, or from an external file (XML, CSV).', title: 'Mapping Content', }, { anchorId: 'tm-templateFinish', - content: 'Click your \' Finish \' button when you finish ', + content: 'Click your \'Finish\' button to save your template.', title: 'Finish', stepId: 'tm-templateFinish' }, - { - anchorId: 'tm-templateEdit', - content: 'Create another new Template or Click on the previous one to edit', - title: 'Create & Edit', - stepId: 'tm-templateEdit' - }, + // { + // anchorId: 'tm-templateEdit', + // content: 'Create another new Template or Click on the previous one to edit.', + // title: 'Create & Edit', + // stepId: 'tm-templateEdit' + // }, // Script { anchorId: 'st-scriptsTab', - content: 'Move To Scripts Tab to set your Kotlin and Python scripts', + content: 'It is Kotlin/Python scripts that allows the execution of a sequence of instructions as part of CDS workflow execution.', title: 'Scripts', stepId: 'st-scriptsTab' }, { anchorId: 'st-scriptsImport', - content: 'Click \' Import File\'button kotlin and python files', + content: 'Click to import kotlin or python files.', title: 'Import File' }, // DSL { anchorId: 'dslTab', - content: 'Write your Authentication Properties in Javascript', - title: 'ESAP', + content: 'Interaction with external systems is made dynamic, removing development cycle to support new endpoint.', + title: 'External Systems support', stepId: 'dslTab' }, // save package { anchorId: 'packageSave', - content: 'Click \' Save \' button to create your package', + content: 'Click to save your package.', title: 'Save' } ]; diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.css new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.css diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.html new file mode 100644 index 000000000..274435cd4 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.html @@ -0,0 +1,54 @@ +<div class="modal fade" id="importPackageModal" tabindex="-1" role="dialog" aria-labelledby="importPackageModal" + aria-hidden="true"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="importModalLabel">Import File</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <!-- <span aria-hidden="true">×</span> --> + <img src="assets/img/icon-close.svg"/> + </button> + </div> + <div class="modal-body"> + <ngx-file-drop accept=".zip" dropZoneLabel="Drop files here" (onFileDrop)="dropped($event)" + (onFileOver)="fileOver($event)" (onFileLeave)="fileLeave($event)"> + <ng-template ngx-file-drop-content-tmp let-openFileSelector="openFileSelector"> + <div class="folder-upload"> + <img src="assets/img/folder-upload.svg"/> + </div> + <div class="folder-upload-text"> + Drag & Drop file + </div> + <div class="folder-upload-text">or + <button type="button" class="btn btn-sm btn-primary" (click)="openFileSelector()">Browse + Files + </button> + </div> + <div class="folder-upload-type">Allowed file type: zip</div> + </ng-template> + </ngx-file-drop> + <div class="upload-table"> + <table class="table"> + <thead> + <tr *ngFor="let item of uploadedFiles; let i=index"> + <th width="40"><img src="assets/img/icon-file-code.svg"/></th> + <th>{{ item.name }}</th> + <th (click)="removeInitFile(i)" width="40" class="text-right"><img + src="assets/img/icon-remove-file.svg"/></th> + </tr> + </thead> + </table> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal" + (click)="resetTheUploadedFiles()">Cancel + </button> + <button type="button" class="btn btn-sm btn-primary" [disabled]="uploadedFiles?.length<=0" + data-dismiss="modal" (click)="openFilesInCreationPackage();saveFileToStore()"> + Import + </button> + </div> + </div> + </div> +</div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.spec.ts new file mode 100644 index 000000000..c594b34aa --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ImportPackageComponent } from './import-package.component'; + +describe('ImportPackageComponent', () => { + let component: ImportPackageComponent; + let fixture: ComponentFixture<ImportPackageComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ImportPackageComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ImportPackageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.ts new file mode 100644 index 000000000..0f582d7f6 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/import-package/import-package.component.ts @@ -0,0 +1,90 @@ +import {Component, OnInit} from '@angular/core'; +import {FileSystemFileEntry, NgxFileDropEntry} from 'ngx-file-drop'; +import {PackageCreationExtractionService} from '../../package-creation/package-creation-extraction.service'; +import {Router} from '@angular/router'; + +@Component({ + selector: 'app-import-package', + templateUrl: './import-package.component.html', + styleUrls: ['./import-package.component.css'] +}) +export class ImportPackageComponent implements OnInit { + + public uploadedFiles: FileSystemFileEntry[] = []; + private fileNames: Set<string> = new Set(); + fileToDelete: any = {}; + public files: NgxFileDropEntry[] = []; + + constructor(private packageCreationExtractionService: PackageCreationExtractionService, + private router: Router) { + } + + ngOnInit() { + } + + removeInitFile(index) { + this.uploadedFiles.splice(index, 1); + } + + public dropped(files: NgxFileDropEntry[]) { + this.files = files; + for (const droppedFile of files) { + // Is it a file? & Not added before + if (droppedFile.fileEntry.isFile) { + const fileEntry = droppedFile.fileEntry as FileSystemFileEntry; + this.uploadedFiles.push(fileEntry); + console.log(fileEntry.name); + this.fileNames.add(fileEntry.name); + + } + } + } + + initDelete(file) { + console.log(file); + this.fileToDelete = file; + } + + removeFile() { + const filename = this.fileToDelete.key; + for (let i = 0; i < this.uploadedFiles.length; i++) { + console.log(this.uploadedFiles[i]); + if (this.uploadedFiles[i].name === filename) { + this.uploadedFiles.splice(i, 1); + break; + } + } + } + + resetTheUploadedFiles() { + this.uploadedFiles = []; + } + + + public fileOver(event) { + console.log(event); + } + + public fileLeave(event) { + console.log(event); + } + + saveFileToStore() { + for (const droppedFile of this.uploadedFiles) { + const file = this.getFile(droppedFile); + this.packageCreationExtractionService.extractBlobToStore(file); + } + } + + openFilesInCreationPackage() { + this.router.navigate(['/packages/createPackage/']); + } + + async getFile(fileEntry) { + try { + return await new Promise((resolve, reject) => fileEntry.file(resolve, reject)); + } catch (err) { + console.log(err); + } + } +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html index 1390a7b78..0bb4f1f41 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.html @@ -12,7 +12,8 @@ Package </a> <br /> - <a href="#" id="clone-btn" role="button" aria-pressed="true" class="btn-import-package float"><i + <a data-target="#importPackageModal" data-toggle="modal" id="clone-btn" role="button" + aria-pressed="true" class="btn-import-package float"><i class="icon-import-blue" aria-hidden="true"></i>Import Package </a> <ngx-ui-loader></ngx-ui-loader> @@ -121,3 +122,6 @@ </div> </div> </div> + + +<app-import-package></app-import-package> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.module.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.module.ts index c0ec679f7..4cfbb897c 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.module.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages.module.ts @@ -32,6 +32,7 @@ import {DesignerSourceViewComponent} from './designer/source-view/source-view.co import {NgxUiLoaderModule} from 'ngx-ui-loader'; import {TourMatMenuModule} from 'ngx-tour-md-menu'; import {ComponentCanDeactivateGuard} from '../../../common/core/canDactivate/ComponentCanDeactivateGuard'; +import { ImportPackageComponent } from './packages-dashboard/import-package/import-package.component'; @NgModule({ declarations: [PackagesDashboardComponent, @@ -54,6 +55,7 @@ import {ComponentCanDeactivateGuard} from '../../../common/core/canDactivate/Com MetadataTabComponent, DslDefinitionsTabComponent, DesignerSourceViewComponent, + ImportPackageComponent, ], imports: [ diff --git a/cds-ui/designer-client/src/styles.css b/cds-ui/designer-client/src/styles.css index 62ce5aa70..fb200dead 100644 --- a/cds-ui/designer-client/src/styles.css +++ b/cds-ui/designer-client/src/styles.css @@ -2510,9 +2510,11 @@ animation: glowing 1500ms infinite; } -.action-button.delete i{ +/* .action-button.delete i{ color: #BABBC3; -} +} */ +.action-button.delete, +.action-button.delete i, .action-button.delete:hover, .action-button.delete:hover .icon-delete-sm{ color: #FF6469 !important; @@ -3421,7 +3423,7 @@ for simplicity .mat-menu-panel{ box-shadow: 0 2px 13px 6px rgba(47, 83, 151, .17) !important; border-radius: 3px !important; - border-bottom: solid 3px #1273EB; + border-top: solid 3px #1273EB; } .mat-menu-panel::after { content: ''; @@ -3431,7 +3433,7 @@ for simplicity position: absolute; border-left: 8px solid transparent; border-right: 8px solid transparent; - border-bottom: 8px solid #1B3E6F; + border-bottom: 8px solid #1273EB; left: 9px; top: -8px; } |