diff options
Diffstat (limited to 'cds-ui/designer-client/src/app/modules/feature-modules/packages/designer')
15 files changed, 1485 insertions, 772 deletions
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.css new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.css diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.html new file mode 100644 index 000000000..051ef1634 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.html @@ -0,0 +1,348 @@ +<div class="scrollWrapper"> + <div class="row m-0"> + <div class="col"> + <div class="form-group"> + <label for="exampleInputEmail1">Action Name</label> + <input type="text" class="form-control" placeholder="Action Name" + value="resource-assignment"> + </div> + </div> + </div> + <!--Add Attribute--> + <div class="row m-b add-attribute"> + <div class="col"> + <h5>Add Attribute</h5> + <div class="row"> + <div class="col pr-0 text-center"> + <button type="button" data-toggle="modal" data-target="#exampleModalScrollable" + class="btn btn-secondary"><i class="icon-custom-attribute" type="button" + aria-hidden="true"></i></button> + <span>Custom Attribute</span> + + + </div> + <div class="col text-center"> + <button type="button" class="btn btn-secondary"><i class="icon-function-attribute" + type="button" aria-hidden="true"></i></button> + <span>Function Attribute</span> + </div> + </div> + </div> + </div> + <!--INPUTS--> + <div class="accordion" id="accordionExample"> + <div class="card"> + <div class="card-header row" id="headingOne"> + <button class="btn btn-link" type="button" data-toggle="collapse" + data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> + Inputs + </button> + </div> + <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" + data-parent="#accordionExample"> + <div class="card-body action-attributes"> + <div class="row"> + <div class="col"> + <div class="form-group" *ngFor="let input of inputs"> + <label for="exampleFormControlTextarea1">{{input.name}} + <i [hidden]="!input.required" class="icon-required-star" + type="button" aria-hidden="true"></i> + <i [hidden]="input.required" type="button" aria-hidden="true"></i> + </label> + <div class="attributeOptions"> + <a data-toggle="modal" data-target="#exampleModalScrollable2" + class="accordion-delete editAttribute" + tooltip="Edit Attribute" placement="bottom"><i + class="icon-edit"></i></a> + <a class="accordion-delete deleteAttribute" + tooltip="Delete Attribute" placement="bottom"><i + class="icon-delete-sm"></i></a> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + <!--OUTPUTS--> + <div class="accordion" id="accordionExample1"> + <div class="card"> + <div class="card-header row" id="headingOne"> + <button class="btn btn-link" type="button" data-toggle="collapse" + data-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo"> + Outputs + </button> + </div> + + <div id="collapseTwo" class="collapse show" aria-labelledby="headingOne" + data-parent="#accordionExample1"> + <div class="card-body"> + <div class="row"> + <div class="col"> + <div class="form-group" *ngFor="let output of outputs"> + <label for="exampleFormControlTextarea1">{{output.name}} + <i [hidden]="output.required" + class="icon-required-star optional-attribute" type="button" + aria-hidden="true"></i> + <i [hidden]="output.required" class="optional-attribute" + type="button" aria-hidden="true"></i> + </label> + </div> + </div> + </div> + </div> + </div> + </div> + </div> +</div> +<!--Action - Add Custom Attribute - Modal--> +<div class="modal fade" id="exampleModalScrollable" tabindex="-1" role="dialog" + aria-labelledby="exampleModalScrollableTitle" aria-hidden="true"> + <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="exampleModalScrollableTitle"> + Add Custom Attributes</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <img src="assets/img/icon-close.svg"/> + </button> + </div> + <div class="modal-body createAttributeTabs"> + <!--Action - Inputs & Outputs Attribute--> + <ul class="nav nav-tabs" id="myTab" role="tablist"> + <li class="nav-item"> + <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" + aria-controls="home" aria-selected="true">Inputs</a> + </li> + <li class="nav-item"> + <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" + aria-controls="profile" aria-selected="false">Outputs</a> + </li> + </ul> + <div class="tab-content" id="myTabContent"> + <!--INPUTS Tab--> + <div class="tab-pane fade show active create-form" id="home" role="tabpanel" + aria-labelledby="home-tab"> + <div class="form-group row"> + <label for="inputEmail3" class="col-sm-3 col-form-label">Name <span>*</span></label> + <div class="col-sm-9"> + <input [(ngModel)]="inputActionAttribute.name" type="email" class="form-control" + id="inputEmail3" placeholder="Attribute name"> + </div> + </div> + <div class="form-group row"> + <label for="inputPassword3" class="col-sm-3 col-form-label">Description</label> + <div class="col-sm-9"> + <input [(ngModel)]="inputActionAttribute.description" type="text" class="form-control" + id="inputPassword3" + placeholder="Add some description"> + </div> + </div> + <div class="form-group row"> + <label class="col-form-label col-sm-3 pt-0">Type <span>*</span></label> + <div class="col-sm-9"> + <div class="list-group list-group-horizontal"> + <button type="button" + class="list-group-item list-group-item-action" + (click)="setInputType('String')"> + String + </button> + <button type="button" + class="list-group-item list-group-item-action" + (click)="setInputType('Integer')">Integer + </button> + <button type="button" + class="list-group-item list-group-item-action" + (click)="setInputType('Boolean')">Boolean + </button> + <button type="button" class="list-group-item list-group-item-action" + (click)="setInputType('List')">List + </button> + <button type="button" class="list-group-item list-group-item-action" + (click)="setInputType('Other')">Other + </button> + + </div> + </div> + </div> + <div class="form-group row"> + <label class="col-form-label col-sm-3 pt-0">Required <span>*</span></label> + <div class="col-sm-9"> + <div class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline1" name="customRadioInline1" + class="custom-control-input" (click)="setInputRequired(true)"> + <label class="custom-control-label" for="customRadioInline1">True</label> + </div> + <div class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline2" name="customRadioInline1" + class="custom-control-input" (click)="setInputRequired(false)"> + <label class="custom-control-label" for="customRadioInline2">False</label> + </div> + </div> + </div> + </div> + <!--OUTPUTS Tab--> + <div class="tab-pane fade create-form" id="profile" role="tabpanel" aria-labelledby="profile-tab"> + <div class="form-group row"> + <label for="inputEmail3" class="col-sm-3 col-form-label">Name <span>*</span></label> + <div class="col-sm-9"> + <input [(ngModel)]="outputActionAttribute.name" type="email" class="form-control" + id="inputEmail3" placeholder="Attribute name"> + </div> + </div> + <div class="form-group row"> + <label for="inputPassword3" class="col-sm-3 col-form-label">Description</label> + <div class="col-sm-9"> + <input [(ngModel)]="outputActionAttribute.description" + type="text" class="form-control" id="inputPassword3" + placeholder="Add some description"> + </div> + </div> + <div class="form-group row"> + <label class="col-form-label col-sm-3 pt-0">Type <span>*</span></label> + <div class="col-sm-9"> + <div class="list-group list-group-horizontal"> + <button type="button" class="list-group-item list-group-item-action">String</button> + <button type="button" + class="list-group-item list-group-item-action" + (click)="setOutputType('Integer')"> + Integer + </button> + <button type="button" + class="list-group-item list-group-item-action" + (click)="setOutputType('Boolean')"> + Boolean + </button> + <button type="button" class="list-group-item list-group-item-action" + (click)="setOutputType('List')"> + List + </button> + <button type="button" + class="list-group-item list-group-item-action" + (click)="setOutputType('Other')"> + Other + </button> + </div> + <input type="text" class="form-control mt-2 mb-2" id="inputPassword3" + placeholder="Add Other type name"> + </div> + </div> + <div class="form-group row"> + <label class="col-form-label col-sm-3 pt-0">Required <span>*</span></label> + <div class="col-sm-9"> + <div class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline1" name="customRadioInline1" + class="custom-control-input" (click)="setOutputRequired(true)"> + <label class="custom-control-label" for="customRadioInline1">True</label> + </div> + <div class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline2" name="customRadioInline1" + class="custom-control-input"> + <label class="custom-control-label" for="customRadioInline2" + (click)="setOutputRequired(false)">False</label> + </div> + </div> + </div> + </div> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> + <button type="button" class="btn btn-primary" (click)="submitAttributes()">Submit Attributes</button> + </div> + </div> + </div> +</div> +<!--Delete Action - Modal--> +<div class="modal fade" id="exampleModalScrollable1" tabindex="-1" role="dialog" + aria-labelledby="exampleModalScrollableTitle1" aria-hidden="true"> + <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="exampleModalScrollableTitle1"> + Delete Action</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <img src="assets/img/icon-close.svg"/> + </button> + </div> + <div class="modal-body"> + Are you sure you want to delete <b>resource-assignment</b> action? + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> + <button type="button" class="btn btn-primary">Delete</button> + </div> + </div> + </div> +</div> +<!--Action - Edit Custom Attribute - Modal--> +<div class="modal fade" id="exampleModalScrollable2" tabindex="-1" role="dialog" + aria-labelledby="exampleModalScrollableTitle2" aria-hidden="true"> + <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="exampleModalScrollableTitle2"> + Edit Custom Attributes</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <img src="assets/img/icon-close.svg"/> + </button> + </div> + <div class="modal-body createAttributeTabs"> + <div class="create-form"> + <div class="form-group row"> + <label for="inputEmail3" class="col-sm-3 col-form-label">Name <span>*</span></label> + <div class="col-sm-9"> + <input type="email" class="form-control" id="inputEmail3" placeholder="Attribute name" + value="resource-assignment-properties"> + </div> + </div> + <div class="form-group row"> + <label for="inputPassword3" class="col-sm-3 col-form-label">Description</label> + <div class="col-sm-9"> + <input type="text" class="form-control" id="inputPassword3" + placeholder="Add some description" + value="Dynamic PropertyDefinition for workflow(resource-assignment)."> + </div> + </div> + <div class="form-group row"> + <label class="col-form-label col-sm-3 pt-0">Type <span>*</span></label> + <div class="col-sm-9"> + <div class="list-group list-group-horizontal"> + <button type="button" + class="list-group-item list-group-item-action">String + </button> + <button type="button" class="list-group-item list-group-item-action">Integer</button> + <button type="button" class="list-group-item list-group-item-action">Boolean</button> + <button type="button" class="list-group-item list-group-item-action">List</button> + <button type="button" class="list-group-item list-group-item-action active">Other + </button> + </div> + <input type="text" class="form-control mt-2 mb-2" id="inputPassword3" + placeholder="Add Other type name" value="dt-resource-assignment-properties"> + </div> + </div> + <div class="form-group row"> + <label class="col-form-label col-sm-3 pt-0">Required <span>*</span></label> + <div class="col-sm-9"> + <div class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline1" name="customRadioInline1" + class="custom-control-input" checked> + <label class="custom-control-label" for="customRadioInline1">True</label> + </div> + <div class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline2" name="customRadioInline1" + class="custom-control-input"> + <label class="custom-control-label" for="customRadioInline2">False</label> + </div> + </div> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> + <button type="button" class="btn btn-primary">Save</button> + </div> + </div> + </div> + </div> +</div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.spec.ts new file mode 100644 index 000000000..12078eb0d --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ActionAttributesComponent } from './action-attributes.component'; + +describe('ActionAttributesComponent', () => { + let component: ActionAttributesComponent; + let fixture: ComponentFixture<ActionAttributesComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ActionAttributesComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ActionAttributesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.ts new file mode 100644 index 000000000..f4f74a9fd --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/action-attributes.component.ts @@ -0,0 +1,58 @@ +import {Component, OnInit} from '@angular/core'; +import {InputActionAttribute, OutputActionAttribute} from './models/InputActionAttribute'; + +@Component({ + selector: 'app-action-attributes', + templateUrl: './action-attributes.component.html', + styleUrls: ['./action-attributes.component.css'] +}) +export class ActionAttributesComponent implements OnInit { + + inputs = []; + outputs = []; + actionAttributesSideBar: boolean; + inputActionAttribute = new InputActionAttribute(); + outputActionAttribute = new OutputActionAttribute(); + + constructor() { + + } + + ngOnInit() { + } + + _toggleSidebar2() { + this.actionAttributesSideBar = !this.actionAttributesSideBar; + } + + addInput(input: InputActionAttribute) { + this.inputs.push(input); + } + + addOutput(output: OutputActionAttribute) { + this.outputs.push(output); + } + + setInputType(type) { + this.inputActionAttribute.type = type; + } + + setInputRequired(isRequired) { + this.inputActionAttribute.required = isRequired; + } + + setOutputRequired(isRequired) { + this.outputActionAttribute.required = isRequired; + } + + setOutputType(type) { + this.outputActionAttribute.type = type; + } + + submitAttributes() { + console.log(this.inputActionAttribute); + console.log(this.outputActionAttribute); + this.inputs.push(this.inputActionAttribute); + this.outputs.push(this.outputActionAttribute); + } +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/models/InputActionAttribute.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/models/InputActionAttribute.ts new file mode 100644 index 000000000..3aa370360 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/action-attributes/models/InputActionAttribute.ts @@ -0,0 +1,17 @@ +export class InputActionAttribute { + name: string; + description: string; + type: string; + required: boolean; + + constructor() { + this.name = ''; + this.description = ''; + this.type = ''; + this.required = false; + } +} + +export class OutputActionAttribute extends InputActionAttribute { + +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css index f7cff5072..43f3818a0 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.css @@ -203,7 +203,9 @@ header{ font-size: 11px; line-height: 20px; } - +.save-blueprint li:hover{ + cursor: pointer; +} @@ -591,39 +593,69 @@ p.compType-4{ .componentContainer p{ font-size: 12px; } -.functionAttributeSidebar{ +.attributeSidebar{ width: 440px; padding: 0px; margin-top: 45px; } -.functionAttributeSidebar .attributesContainer{ +.attributesContainer{ + padding: 0; background: #fff; border: solid 1px #C1CDDD; box-shadow: 0 2px 6px rgba(47, 83, 151, .1); } /*ATTRIBUTES SIDE BAR*/ .attributesSideBar{ - width: 396px; + width: 358px; padding: 0px; - margin-top: 50px; + margin-top: 45px; } .attributesSideBar .attributesContainer{ + height: 85.9vh; + overflow-y: hidden; + padding-bottom: 20px; background: #fff; border: solid 1px #C1CDDD; box-shadow: 0 2px 6px rgba(47, 83, 151, .1); } .closeBar{ float: left; - width: 50%; - height: 42px; - background: url(/assets/img/icon-close.svg) center center #DCE8F4 no-repeat ; + padding: 0 !important; + width: 38px; + height: 35px; + background:#D9E3EE; border: 0; outline: 0; - margin-left: -30px; } .closeBar:focus{ outline: none; } +.attributesContainer .scrollWrapper{ + overflow-y: auto; + height: 79vh; +} +.attributesContainer .nav-link{ + padding-top: 7px !important; + padding-bottom: 7px !important; + color: #1B3E6F !important; + text-transform: capitalize !important; + border: solid 1px #ECEDF2 !important; + border-radius: 0 !important; +} +.attributesContainer .nav-item:first-child a{ + border-top-left-radius: 4px !important; + border-bottom-left-radius: 4px !important; + border-right-width: 0 !important; +} +.attributesContainer .nav-item:last-child a{ + border-top-right-radius: 4px !important; + border-bottom-right-radius: 4px !important; + border-left-width: 0 !important; +} +.nav-pills .nav-link.active{ + background-color: #1B3E6F; + color: #fff !important; +} .attributesContainer h1{ margin-bottom: 10px; padding: 12px 0 12px 15px; @@ -633,24 +665,91 @@ p.compType-4{ text-transform: uppercase; color: #1B3E6F; } +.attributesContainertTitle{ + height: 35px; + margin-bottom: 9px !important; + padding: 0; + background: #DEE8F3; + font-size: 12px; +} +.add-attribute{ + margin: 15px 0; + padding: 15px 9px; + background-color: #F4F9FE; +} +.add-attribute h5{ + padding: 0; + margin-bottom: 12px; + font-size: 12px; + font-weight: bold; + text-transform: uppercase; + color: #1B3E6F; +} +.add-attribute .btn{ + width: 100%; + background-color: #fff; + border: solid 1px #C1CDDD; + color: #1B3E6F; + line-height: 18px; + border-radius: 4px; +} +.add-attribute .btn:hover{ + background-color: #1B3E6F; +} +.add-attribute .btn:hover i::before{ + color: #fff; +} +.icon-function-attribute{ + font-size: 18px; +} +.add-attribute span{ + font-size: 11px; + line-height: 16px; +} +.attributesContainertTitle .btn-group{ + margin-top: 3px; +} +.attributesContainertTitle .btn{ + margin-left: 8px !important; + padding: 1px 9px !important; + border-radius: 4px !important; +} .attributesContainer h6{ - margin-bottom: 10px; - padding: 12px 0 12px 15px; + padding: 0; + margin-bottom: 0; background: #DEE8F3; + line-height: 35px !important; font-size: 12px; font-weight: bold; text-transform: uppercase; color: #1B3E6F; } -.actionName{ - margin-bottom: 21px; +.view-source, +.view-source:hover{ + background: #103D73; + border-color: #D0DFF1; + color: #fff; + font-size: 11px; +} +.trash-item, +.trash-item:hover{ + background: #fff; + border-color: #D0DFF1; + color: #103D73; +} +.trash-item{ + font-size: 14px; } .attributesContainer label{ color: #1B3E6F; - text-transform: uppercase; - font-size: 11px; + /* text-transform: uppercase; */ + font-size: 12px; font-weight: bold; } +.attributesContainer label.custom-control-label{ + text-transform: unset; + font-weight: normal; +} .attributesContainer .form-group{ margin-bottom: 9px; } @@ -668,23 +767,119 @@ p.compType-4{ .attributesContainer .form-control::placeholder{ color: #CFD7E5; } -.scrolll{ - max-height: 88.75vh; - overflow-y: auto; +.attributesContainer .attribute-value{ + text-transform: unset; + display: block; + width: 100%; + padding: 0 .75rem .375rem 0; + font-size: 12px; + font-weight: normal; +} +.attributesContainer textarea{ + height: 60px; +} +.icon-required-star{ + font-size: 10px; +} +.optional-attribute::before{ + color: #CAD3E0; +} +.attributeOptions{ + display: none; + border: 0; +} +.attributeOptions a:not(:first-child){ + margin-left: 18px; +} +.attributeOptions i{ + color: #103D73 !important; + font-size: 16px; +} +.editAttribute i{ + font-size: 14px; +} +.action-attributes .form-group{ + display: inline-block; + width: 100%; + padding-left: 12px; + /* line-height: 30px; */ +} +.action-attributes .form-group:hover{ + cursor: pointer !important; + background-color: #F5FAFF; +} +.action-attributes .form-group:hover label{ + cursor: pointer !important; + /* padding-left: 12px; */ +} +.action-attributes .form-group:hover .attributeOptions{ + display: inline-block; + position: relative; + left: 8%; + top: 3px; +} + +.btn-select-template{ + background-color: #C3CDDB; + border-radius: 2px; + color: #1B3E6F; + font-size: 12px; +} +.btn-select-template i{ + font-size: 16px; + vertical-align: text-bottom; +} +.attribute-wrap{ + padding-bottom: 15px; + margin-bottom: 9px; + border-bottom: solid 1px #F4F9FE; +} +.attribute-wrap .form-group{ + margin-bottom: 0; +} +.template-mapping-list{ + margin-bottom: 15px; + font-size: 13px; +} +.template-mapping-list p{ + width: 56%; +} +.deleteTemplate{ + right: 30px; + top: -8px; +} +.deleteTemplate i{ + color: #103D73 !important; +} +.icon-close::before{ + color: #103D73; + font-size: 10px !important; +} +.accordion{ + margin-top: 12px; } .accordion > .card{ margin-bottom: 0 !important; border: 0; + box-shadow: none; +} +.card-header .btn-link, +.accordion .card-header .btn-link[aria-expanded="true"], +.accordion .card-header .btn-link[aria-expanded="false"]{ + padding-left: 15px !important; + padding-right: 15px !important; } .accordion > .card .card-header{ margin: 0; - padding: 0; + padding: 0 !important; background-color: #F4F9FE; border: 0; border-radius: 0; } + .accordion > .card .card-body{ - padding-bottom: 10px !important; + padding-top: 20px !important; + padding-bottom: 0 !important; } .accordion .btn-link{ padding: 0; @@ -694,6 +889,9 @@ p.compType-4{ text-transform: uppercase; line-height: 15px; } +.btn-link::before{ + font-size: 15px !important; +} .accordion .btn-link:hover{ color: #103D73; text-decoration: unset; @@ -706,12 +904,12 @@ p.compType-4{ font-weight: normal; font-size: 12px; } -.accordion .card-header .btn-link[aria-expanded="true"]:after{ +/* .accordion .card-header .btn-link[aria-expanded="true"]:after{ content: "\f078"; } .accordion .card-header .btn-link[aria-expanded="false"]:after{ content: "\f054"; -} +} */ .btn-addAttribute{ width: 20px; height: 20px; @@ -776,11 +974,7 @@ p.compType-4{ margin-left: 12px; font-weight: bold; } -.function-attribute{ - margin-right: -16px; -} .trash-span{ - margin-left: 150px; font-size:15px } @@ -854,3 +1048,10 @@ ul.editor{ .zoom-percent{ font-size: 12px; } +/*Modal*/ +.modal-backdrop{z-index: -1} +.modal-holder.modal-backdrop{z-index: 100} +.modal-holder + .modal-dialog {z-index: 1000} +.modal-dialog{ + max-width: 680px; +}
\ No newline at end of file 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..537a0a8ca 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 @@ -10,9 +10,9 @@ </li> <i class="fa fa-angle-right ml-2 mr-2"></i> <li class="breadcrumb-item"> - <a href="/package/{{viewedPackage.id}}">{{viewedPackage.artifactName}}</a> + <a routerLink="/packages/package/{{viewedPackage.id}}">{{viewedPackage.artifactName}}</a> <button type="button" class="btn package-info-btn" data-toggle="modal" - data-target="#exampleModalLong"> + data-target="#exampleModalLong"> <i class="icon-info" aria-hidden="true"></i> </button> </li> @@ -22,13 +22,13 @@ </li> </ol> <div class="modal fade" id="exampleModalLong" tabindex="-1" role="dialog" - aria-labelledby="exampleModalLongTitle" aria-hidden="true"> + aria-labelledby="exampleModalLongTitle" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLongTitle">Package Details</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> - <img src="assets/img/icon-close.svg" /> + <img src="assets/img/icon-close.svg"/> </button> </div> <div class="modal-body package-info"> @@ -70,15 +70,15 @@ <li> <div class="btn-group" role="group" aria-label="Basic example"> <a href="#" role="button" aria-pressed="true" class="btn-topology-action float tooltip-bottom" - data-tooltip="Preview"> + data-tooltip="Preview"> <i class="fa fa-eye"></i> </a> <a href="#" role="button" aria-pressed="true" class="btn-topology-action float tooltip-bottom" - data-tooltip="Download"> + data-tooltip="Download"> <i class="fa fa-download"></i> </a> <a href="#" role="button" aria-pressed="true" class="btn-topology-action float tooltip-bottom" - data-tooltip="Share"> + data-tooltip="Share"> <i class="fa fa-share-square"></i> </a> </div> @@ -87,12 +87,12 @@ <div class="dropdown"> <input class="dropdown-toggle" type="text"> <div class="dropdown-text">Save</div> - <ul class="dropdown-content"> + <ul class="dropdown-content save-blueprint"> <li> - <a href="">Save</a> + <a (click)="saveBluePrint()">Save</a> </li> <li> - <a href="">Save & Deploy</a> + <a (click)="publishBluePrint()">Save & Deploy</a> </li> </ul> </div> @@ -103,33 +103,36 @@ </div> </div> </header> - +<!--Editor Bar--> <nav class="editNavbar row source-button {{cl}} navbar navbar-expand-lg"> + <!--Actions/Functions Side Menu Toogole Button--> <button (click)="_toggleSidebar1()" class="toggoleBtn active btn tooltip-bottom" title="" aria-pressed="true" - data-tooltip="Collapse Side bar"> + data-tooltip="Collapse Side bar"> <i class="fa arr-size"></i> </button> + <!--Nav Tabs--> <div class="collapse navbar-collapse "> + <!--Action Tabs--> <ul class="navbar-nav"> <li class="nav-item active"> <nav class="row"> - <!--Nav Tabs--> <div class="col-12"> <div class="nav nav-tabs " id="nav-tab" role="tablist"> <a class="nav-item nav-link active col-6" id=" " data-toggle="tab" href="" role="tab" - aria-controls=" " aria-selected="false" autofocus #nameit>Workflow</a> + aria-controls=" " aria-selected="false" autofocus #nameit>Workflow</a> <a class="nav-item nav-link col-6" id=" " data-toggle="tab" href="" role="tab" - aria-controls=" " aria-selected="false">Template</a> + aria-controls=" " aria-selected="false">Template</a> </div> </div> </nav> </li> </ul> + <!--Requirement/Capability Legend--> <ul class="templateLegend ml-auto mr-auto p-0"> <li class="requirement"><i class="icon-rectangle" aria-hidden="true"></i> Requirement</li> <li class="capability"><i class="icon-rectangle" aria-hidden="true"></i> Capability</li> </ul> - + <!--Undo/Redo Buttons--> <ul class="editor navbar"> <li> <button type="button" class="btn tooltip-bottom" data-tooltip="Undo"> @@ -142,42 +145,43 @@ </button> </li> <li class="vertical_line"></li> - <li><button type="button" class="btn tooltip-bottom" data-tooltip="Zoom Out"> + <li> + <button type="button" class="btn tooltip-bottom" data-tooltip="Zoom Out"> <img src="/assets/img/icon-zoomOut.svg"> - </button></li> + </button> + </li> <li class="zoom-percent">100%</li> <li> <button type="button" class="btn tooltip-bottom" data-tooltip="Zoom In"> - <img src="/assets/img/icon-zoomIn.svg"> </button> + <img src="/assets/img/icon-zoomIn.svg"></button> </li> </ul> - + <!--Designer/Scripting View Tabs--> <ul class="navbar ml-2" style="list-style: none"> <li class="nav-item"> <div class="btn-group viewBtns" role="group"> <button type="button" class="btn btn-secondary topologySource active">Designer</button> <button [routerLink]="['/designer/source', viewedPackage.id]" type="button" - class="btn btn-secondary topologyView">Scripting</button> + class="btn btn-secondary topologyView">Scripting + </button> </div> </li> </ul> - </div> </nav> <ng-sidebar-container class="sidebar-container"> - <!-- Controller SideBar --> + <!--Left Side Menu--> <ng-sidebar [(opened)]="controllerSideBar" [sidebarClass]="'demo-sidebar controllerSidebar container-fluid'" - [mode]="'push'" #sidebarLeft> - + [mode]="'push'" #sidebarLeft> <nav class="row"> <!--Nav Tabs--> <div class="col"> <div class="nav nav-tabs " id="nav-tab" role="tablist"> <a class="nav-item nav-link active col-6" id="nav-action-tab" data-toggle="tab" href="#nav-action" - role="tab" aria-controls="nav-action" aria-selected="false" autofocus #nameit>Actions</a> + role="tab" aria-controls="nav-action" aria-selected="false" autofocus #nameit>Actions</a> <a class="nav-item nav-link col-6" id="nav-function-tab" data-toggle="tab" href="#nav-function" - role="tab" aria-controls="nav-function" aria-selected="false">Functions</a> + role="tab" aria-controls="nav-function" aria-selected="false">Functions</a> </div> </div> </nav> @@ -185,10 +189,17 @@ <div class="col"> <div class="tab-content" id="nav-tabContent"> <div class="tab-pane fade show active" id="nav-action" role="tabpanel" - aria-labelledby="nav-action-tab"> + aria-labelledby="nav-action-tab"> <!--Action Search Box--> <input type="text" class="form-control input-search-controller" placeholder="Search Actions"> - + <button (click)="sidebarRight1.open()" type="button" class="btn btn-primary"> + Action Attributes + </button> + <br/><br/> + <button (click)="sidebarRight2.open()" type="button" class="btn btn-secondary"> + Function Attributes + </button> + <br/> <button (click)="insertCustomActionIntoBoard()" type="button" class="btn new-action"> + New Action </button> @@ -197,23 +208,31 @@ <label><i class="icon-file" aria-hidden="true"></i> {{customActionName}} </label> </div> + <div *ngIf="!showAction" class="custom-control"> + <ul> + <li *ngFor="let customActionName of actions"> + <label> + <i class="icon-file" aria-hidden="true" class="icon-file" + (click)="openFunctionAttributes(customActionName)"></i> + {{customActionName}} </label> + </li> + </ul> + </div> </div> </div> <div class="tab-pane fade" id="nav-function" role="tabpanel" aria-labelledby="nav-function-tab"> <!--Function Search Box--> <input type="text" class="form-control input-search-controller" placeholder="Search Functions"> - <div id="palette-paper" class="componentsList"> </div> + <div id="palette-paper" class="componentsList"></div> </div> - </div> </div> </div> - <div class="helpBox"><i class="icon-info" aria-hidden="true"></i><a - href="https://wiki.onap.org/display/DW/CDS+Designer+Guide" target="_blank">Help - Learn The Basics</a> + <div class="helpBox"><i class="icon-info" aria-hidden="true"></i> + <a href="https://wiki.onap.org/display/DW/CDS+Designer+Guide" target="_blank">Help - Learn The Basics</a> </div> </ng-sidebar> - <!-- Page content --> - + <!--Page content--> <div ng-sidebar-content id="board-paper"> <button class="rotate" (click)="_toggleSidebar1()"> <span> @@ -222,7 +241,9 @@ </span> </button> - <!-- Canvas --> + + <!-- CANVAS --> + <!--Editor Bar--> <div class="editBar text-center"> <div class="btn-group mr-2" role="group" aria-label="First group"> <button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Undo"> @@ -246,396 +267,64 @@ <button type="button" class="btn btn-secondary topologyView">Source</button> </div> </div> - <!-- <div class="card actionContainer"> - <div class="card-header"> - <span>Action 1</span> - </div> - <div class="card-body"> - <a (click)="sidebarRight.open()" class="componentContainer text-center"> - <img src="/assets/img/icon-comType1.svg" title=""> - <h2>config-assign</h2> - <p>component-resource-resolution</p> - </a> - <a (click)="sidebarRight.open()" class="componentContainer text-center"> - <img src="/assets/img/icon-comType2.svg" title=""> - <h2>execute</h2> - <p>component-netconf-executor</p> - </a> - <a (click)="sidebarRight.open()" class="componentContainer text-center"> - <img src="/assets/img/icon-comType3.svg" title=""> - <h2>function 1</h2> - <p>dg-generic</p> - </a> - <a (click)="sidebarRight.open()" class="componentContainer text-center"> - <img src="/assets/img/icon-comType2.svg" title=""> - <h2>execute</h2> - <p>component-netconf-executor</p> - </a> - </div> - </div> --> - <!-- <button (click)="_toggleSidebar2()" style="float:right;">Toggle sidebar right</button> --> + <!--<button (click)="_toggleSidebar2()" style="float:right;">Toggle sidebar right</button> --> </div> - <!-- Action Attribute SideBar --> - <ng-sidebar [(opened)]="attributesSideBar" [sidebarClass]="'demo-sidebar attributesSideBar '" [mode]="'push'" - [position]="'right'" #sidebarRight> + <ng-sidebar [(opened)]="actionAttributesSideBar" [sidebarClass]="'demo-sidebar attributesSideBar '" [mode]="'push'" + [position]="'right'" #sidebarRight1> <div class="container-fluid0"> <div class="row m-0"> - <div class="col-2 pr-0"> - <button (click)="sidebarRight.close()" class="closeBar"></button> - </div> - <div class="col-10 attributesContainer p-0"> - <h1>Action Attributes</h1> - <div class="scrolll"> - <div class="row m-0"> - <div class="col"> - <div class="form-group actionName"> - <label for="exampleInputEmail1">Action Name</label> - <input type="text" class="form-control" placeholder="Action 1"> - </div> - </div> + <div class="col attributesContainer"> + <div class="row m-0 attributesContainertTitle"> + <div class="col-2 pl-0"> + <button (click)="sidebarRight1.close()" class="closeBar" tooltip="Close" placement="bottom"> + <i + class="icon-close" type="button" aria-hidden="true"></i></button> </div> - <div class="accordion" id="accordionExample"> - <div class="card"> - <div class="card-header row" id="headingOne"> - <h2 class="col-10 mb-0"> - <button class="btn btn-link" type="button" data-toggle="collapse" - data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> - Steps - </button> - </h2> - <div class="col-2 p-0 text-center"> - <button class="btn btn-addAttribute" type="button"></button> - </div> - </div> - - <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" - data-parent="#accordionExample"> - <div class="card-body"> - <div class="row"> - <div class="col-9"> - <label for="exampleInputEmail1">Name</label> - <button type="button" class="btn p-0"> - <img src="/assets/img/icon-edit.svg"> - </button> - </div> - <div class="col-3"> - <button type="button" class="btn btn-deleteAttribute">Delete</button> - </div> - </div> - <div class="form-group"> - <label for="exampleInputEmail1">Name</label> - <input type="text" class="form-control" placeholder="Action 1"> - </div> - <div class="form-group"> - <label for="exampleFormControlTextarea1">Description</label> - <textarea class="form-control" id="exampleFormControlTextarea1" - rows="3"></textarea> - </div> - <div class="form-group"> - <label for="exampleInputEmail1">Target</label> - <input type="text" class="form-control" placeholder="Action 1"> - </div> - - </div> - </div> - </div> - <div class="card"> - <div class="card-header row" id="headingTwo"> - <h2 class="col-10 mb-0"> - <button class="btn btn-link" type="button" data-toggle="collapse" - data-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo"> - Inputs - </button> - </h2> - <div class="col-2 p-0 text-center"> - <button class="btn btn-addAttribute" type="button"></button> - </div> - </div> - <div id="collapseTwo" class="collapse show" aria-labelledby="headingTwo" - data-parent="#accordionExample"> - <div class="card-body"> - <div class="row"> - <div class="col-9"> - <label for="exampleInputEmail1">Name</label> - <button type="button" class="btn p-0"> - <img src="/assets/img/icon-edit.svg"> - </button> - </div> - <div class="col-3"> - <button type="button" class="btn btn-deleteAttribute">Delete</button> - </div> - </div> - <div class="form-group"> - <label for="exampleInputEmail1">Name</label> - <input type="text" class="form-control" placeholder="Action 1"> - </div> - <div class="form-group"> - <label for="exampleFormControlTextarea1">Description</label> - <textarea class="form-control" id="exampleFormControlTextarea1" - rows="3"></textarea> - </div> - <div class="form-group"> - <label for="exampleInputEmail1">Target</label> - <input type="text" class="form-control" placeholder="Action 1"> - </div> - - </div> - </div> - </div> - <div class="card"> - <div class="card-header row" id="headingThree"> - <h2 class="col-10 mb-0"> - <button class="btn btn-link" type="button" data-toggle="collapse" - data-target="#collapseThree" aria-expanded="true" - aria-controls="collapseThree"> - Outputs - </button> - </h2> - <div class="col-2 p-0 text-center"> - <button class="btn btn-addAttribute" type="button"></button> - </div> - </div> - <div id="collapseThree" class="collapse show" aria-labelledby="headingThree" - data-parent="#accordionExample"> - <div class="card-body"> - <div class="row"> - <div class="col-9"> - <label for="exampleInputEmail1">Name</label> - <button type="button" class="btn p-0"> - <img src="/assets/img/icon-edit.svg"> - </button> - </div> - <div class="col-3"> - <button type="button" class="btn btn-deleteAttribute">Delete</button> - </div> - </div> - <div class="form-group"> - <label for="exampleInputEmail1">Name</label> - <input type="text" class="form-control" placeholder="Action 1"> - </div> - <div class="form-group"> - <label for="exampleFormControlTextarea1">Description</label> - <textarea class="form-control" id="exampleFormControlTextarea1" - rows="3"></textarea> - </div> - <div class="form-group"> - <label for="exampleInputEmail1">Target</label> - <input type="text" class="form-control" placeholder="Action 1"> - </div> - - </div> - </div> + <h6 class="col pl-0">Action Attributes</h6> + <div class="col-3 pl-0"> + <div class="btn-group" role="group" aria-label="Basic example"> + <button type="button" class="btn view-source" tooltip="View Action Source" + placement="bottom"><i class="icon-source"></i></button> + <button type="button" data-toggle="modal" data-target="#exampleModalScrollable1" + class="btn trash-item" tooltip="Delete Action" placement="bottom"><i + class="icon-delete-sm" aria-hidden="true"></i></button> </div> </div> </div> + <app-action-attributes></app-action-attributes> </div> </div> </div> </ng-sidebar> - - <!-- Function Attribute SideBar --> - <ng-sidebar [(opened)]="functionAttributeSidebar" [sidebarClass]="'demo-sidebar functionAttributeSidebar '" - [mode]="'push'" [position]="'right'" #sidebarRight> + <!--Right Side Menu - Function Attribute--> + <ng-sidebar [(opened)]="functionAttributeSidebar" [sidebarClass]="'demo-sidebar attributesSideBar'" [mode]="'push'" + [position]="'right'" #sidebarRight2> <div class="container-fluid0"> <div class="row m-0"> - <div class="col-2 pr-0"> - <!-- <button (click)="sidebarRight.close()" class="closeBar"></button> --> - </div> - <div class="col-10 attributesContainer p-0"> - <div class="row m-0"> - <div class="col"> - <div class="col-3"> - <button (click)="sidebarRight.close()" class="closeBar"></button> - </div> - - <div class="function-attribute"> - <h6>Function Attributes - <span class="trash-span"> - <i class="fa fa-trash" type="button" aria-hidden="true"></i> - </span> - </h6> - </div> - - - </div> - </div> - - <div> - <div class="row m-0"> - <div class="col"> - <div class="form-group actionName"> - <label for="exampleInputEmail1">Function Name</label> - <input type="text" class="form-control" placeholder="Function Name"> - </div> - </div> - </div> - <div class="row m-0"> - <div class="col"> - <div class=" actionName"> - <label>Function Type</label> - <div class="dropdown w-100"> - <input class="dropdown-toggle" type="text"> - <div class="dropdown-text">component-resource-resolution <i - class="fa fa-caret-down"></i></div> - <ul class="dropdown-content w-100"> - <li> - <div class="form-group "> - <li>other component</li> - </div> - </li> - </ul> - </div> - </div> + <div class="col attributesContainer"> + <div class="row m-0 attributesContainertTitle"> + <div class="col-2 pl-0"> + <button (click)="sidebarRight2.close()" class="closeBar" tooltip="Close" + placement="bottom"><i class="icon-close" type="button" aria-hidden="true"></i> + </button> </div> - </div> - <div class="accordion" id="accordionExample"> - <div class="card"> - <div class="card-header row" id="headingOne"> - <h2 class="col-10 mb-0"> - <button class="btn btn-link" type="button" data-toggle="collapse" - data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> - Interface - </button> - </h2> - <div class="col-2 p-0 text-center"> - <button class="btn btn-addAttribute" type="button"></button> - </div> - </div> - - <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" - data-parent="#accordionExample"> - <div class="card-body"> - <div class="row"> - <div class="col-9"> - <label for="exampleInputEmail1">ResourceResolutionComponent</label> - <button type="button" class="btn p-0"> - <img src="/assets/img/icon-edit.svg"> - </button> - </div> - <div class="col-3"> - <button type="button" class="btn btn-deleteAttribute">Delete</button> - </div> - </div> - <div class="form-group"> - <label for="exampleInputEmail1">Resoluton-key</label> - <input type="text" class="form-control"> - </div> - <div class="form-group"> - <label for="exampleFormControlTextarea1">Store result</label> - </div> - <div class="form-group"> - <label> - <input class="with-gap radio-btn" name="group1" type="radio" /> - <span class="radio-btn">True</span> - </label> - <label class="radio-btn"> - <input class="with-gap radio-btn" name="group1" type="radio" /> - <span class="radio-btn">False</span> - </label> - </div> - <div class="form-group"> - <label for="exampleInputEmail1">Target</label> - <input type="text" class="form-control" placeholder=""> - </div> - <div class="form-group"> - <label for="exampleFormControlTextarea1">Artifact Prefix Name</label> - <input type="text" class="form-control" placeholder=""> - - </div> - - </div> - </div> - </div> - - </div> - - <div class="accordion" id="accordionExample"> - <div class="card"> - <div class="card-header row" id="headingOne"> - <h2 class="col-10 mb-0"> - <button class="btn btn-link" type="button" data-toggle="collapse" - data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> - Artifact - </button> - </h2> - <div class="col-2 p-0 text-center"> - <button class="btn btn-addAttribute" type="button"></button> - </div> - </div> - - <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" - data-parent="#accordionExample"> - <div class="card-body"> - <div class="row"> - <div class="col-9"> - <label for="exampleInputEmail1">base config-template</label> - <button type="button" class="btn p-0"> - <img src="/assets/img/icon-edit.svg"> - </button> - </div> - <div class="col-3"> - <button type="button" class="btn btn-deleteAttribute">Delete</button> - </div> - </div> - <div class="form-group"> - <label for="exampleInputEmail1">Type</label> - <div class="dropdown w-100"> - <input class="dropdown-toggle" type="text"> - <div class="dropdown-text">artifact-template-velocity <i - class="fa fa-caret-down"></i></div> - <ul class="dropdown-content w-100"> - <li> - <div class="form-group "> - <li>ddwd</li> - </div> - </li> - </ul> - </div> - </div> - - <div style="height: 30px; margin-top: 30px;"> - <hr> - </div> - - <div class="row"> - <div class="col-9"> - <label for="exampleInputEmail1">base config-mapping</label> - <button type="button" class="btn p-0"> - <img src="/assets/img/icon-edit.svg"> - </button> - </div> - <div class="col-3"> - <button type="button" class="btn btn-deleteAttribute">Delete</button> - </div> - </div> - <div class="form-group"> - <label for="exampleInputEmail1">Type</label> - <div class="dropdown w-100"> - <input class="dropdown-toggle" type="text"> - <div class="dropdown-text">artifact-mapping resource <i - class="fa fa-caret-down"></i></div> - <ul class="dropdown-content w-100"> - <li> - <div class="form-group "> - <li>ddwd</li> - </div> - </li> - </ul> - </div> - </div> - - <div style="height: 30px; margin-top: 30px;"> - <hr> + <h6 class="col pl-0">Function Attributes</h6> + <div class="col-3 pl-0"> + <div class="btn-group" role="group" aria-label="Basic example"> + <button type="button" class="btn view-source" tooltip="View Function Source" + placement="bottom"><i class="icon-source"></i></button> + <button type="button" class="btn trash-item" tooltip="Delete Function" + placement="bottom"><i class="icon-delete-sm" type="button" + aria-hidden="true"></i></button> </div> </div> </div> + <app-functions-attribute></app-functions-attribute> </div> - </div> </div> - </div> - </div> - </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..1475f1ac3 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,454 @@ 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, Router} 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 {PackageCreationExtractionService} from '../package-creation/package-creation-extraction.service'; +import {CBAPackage} from '../package-creation/mapping-models/CBAPacakge.model'; +import {TopologyTemplate} from './model/designer.topologyTemplate.model'; +import {ToastrService} from 'ngx-toastr'; @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; + actionAttributesSideBar: 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(); + cbaPackage: CBAPackage; + actions: string[] = []; + dataTarget: string; + + constructor( + private designerStore: DesignerStore, + private functionStore: FunctionsStore, + private packageCreationStore: PackageCreationStore, + private packageCreationUtils: PackageCreationUtils, + private graphUtil: GraphUtil, + private graphGenerator: GraphGenerator, + private route: ActivatedRoute, + private router: Router, + private designerService: DesignerService, + private packageCreationService: PackageCreationService, + private packageCreationExtractionService: PackageCreationExtractionService, + private toastService: ToastrService) { + this.controllerSideBar = true; + this.actionAttributesSideBar = false; + this.showAction = false; + this.functionAttributeSidebar = false; + + } + + _toggleSidebar1() { + this.controllerSideBar = !this.controllerSideBar; + if (this.controllerSideBar === false) { + this.cl = 'editBar2'; + } + if (this.controllerSideBar === true) { + this.cl = 'editBar'; + } } - if (this.controllerSideBar === true) { - this.cl = 'editBar'; + + _toggleSidebar2() { + this.actionAttributesSideBar = !this.actionAttributesSideBar; } - } - _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; + + publishBluePrint() { + this.create(); + this.zipFile.generateAsync({type: 'blob'}) + .then(blob => { + const formData = new FormData(); + formData.append('file', blob); + this.designerService.publishBlueprint(formData).subscribe(res => { + console.log('Package Deployed...'); + }, error => { + console.log(error); + }, () => { + // this.deployBluePrint = false; + }); + }); } - 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++); - }); - } - }); - - 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 - }); - } - } - - 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; + + ngOnInit() { + this.customActionName = this.route.snapshot.paramMap.get('actionName'); + if (this.customActionName !== '') { + this.showAction = true; } + 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]; + this.packageCreationService.downloadPackage(this.viewedPackage.artifactName + '/' + + this.viewedPackage.artifactVersion) + .subscribe(response => { + const blob = new Blob([response], {type: 'application/octet-stream'}); + this.packageCreationExtractionService.extractBlobToStore(blob); + }); + } + }); + this.packageCreationStore.state$.subscribe(cba => { + this.cbaPackage = cba; + console.log(cba.templateTopology.content); + this.designerStore.saveSourceContent(cba.templateTopology.content); - 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())) { + /** + * 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: TopologyTemplate = JSON.parse(state.sourceContent); + console.log(topologtTemplate); + delete state.sourceContent; + this.graphGenerator.clear(this.boardGraph); + 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.actions = []; + for (const workflowsKey in topologtTemplate.workflows) { + if (workflowsKey && !this.actions.includes(workflowsKey)) { + this.actions.push(workflowsKey); + } + } + } + }); + + // action triggering + this.functionStore.retrieveFuntions(); - // All the four corners of the child are inside - // the parent area. - return; + } + + 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 + }); } + } - // Revert the child position. - cell.set('position', cell.previous('position')); - }); + 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...'); } - 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); - } + insertCustomActionIntoBoard() { + console.log('saving action to store action workflow....'); + const actionName = this.graphUtil.generateNewActionName(); + this.graphUtil.createCustomActionWithName(actionName, this.boardGraph); + this.designerStore.addDeclarativeWorkFlow(actionName); + } - stencilPaperEventListeners() { - this.palettePaper.on('cell:pointerdown', (draggedCell, pointerDownEvent, x, y) => { + stencilPaperEventListeners() { + this.palettePaper.on('cell:pointerdown', (draggedCell, pointerDownEvent, x, y) => { - $('body').append(` + $('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 + ); + 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(); + }); }); - }); - - $('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(); - } + console.log('done stencilPaperEventListeners()...'); + } + + ngOnDestroy() { + this.ngUnsubscribe.next(); + this.ngUnsubscribe.complete(); + } + + saveBluePrint() { + + FilesContent.clear(); + let packageCreationModes: PackageCreationModes; + this.cbaPackage = PackageCreationModes.mapModeType(this.cbaPackage); + this.cbaPackage.metaData = PackageCreationModes.setEntryPoint(this.cbaPackage.metaData); + packageCreationModes = PackageCreationBuilder.getCreationMode(this.cbaPackage); + this.designerStore.state$.subscribe(state => { + this.cbaPackage.templateTopology.content = this.packageCreationUtils.transformToJson(state.template); + }); + packageCreationModes.execute(this.cbaPackage, this.packageCreationUtils); + this.filesData.push(this.folder.TREE_DATA); + this.saveBluePrintToDataBase(); + + } + + create() { + this.zipFile = new JSZip(); + FilesContent.getMapOfFilesNamesAndContent().forEach((value, key) => { + this.zipFile.folder(key.split('/')[0]); + this.zipFile.file(key, value); + }); + + } + + saveBluePrintToDataBase() { + this.create(); + this.zipFile.generateAsync({type: 'blob'}) + .then(blob => { + this.packageCreationService.savePackage(blob).subscribe( + bluePrintDetailModels => { + this.toastService.info('success updating the package'); + const id = bluePrintDetailModels.toString().split('id')[1].split(':')[1].split('"')[1]; + this.router.navigate(['/packages/designer/' + id]); + console.log('success'); + }, error => { + this.toastService.error('error happened when editing ' + error.message); + console.log('Error -' + error.message); + }); + }); + } + + openFunctionAttributes(customActionName: string) { + console.log('opening here function attributes'); + } } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.service.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.service.ts index 771c44ba8..c0d79cae1 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.service.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.service.ts @@ -21,11 +21,11 @@ limitations under the License. ============LICENSE_END============================================ */ -import {Injectable} from '@angular/core'; -import {Observable} from 'rxjs'; -import {ApiService} from '../../../../common/core/services/api.typed.service'; -import {ResourceDictionaryURLs, BlueprintURLs} from '../../../../common/constants/app-constants'; -import {ModelType} from './model/ModelType.model'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { ApiService } from '../../../../common/core/services/api.typed.service'; +import { ResourceDictionaryURLs, BlueprintURLs } from '../../../../common/constants/app-constants'; +import { ModelType } from './model/ModelType.model'; import { BluePrintDetailModel } from '../model/BluePrint.detail.model'; @@ -34,8 +34,10 @@ import { BluePrintDetailModel } from '../model/BluePrint.detail.model'; }) export class DesignerService { - constructor(private api: ApiService<ModelType>, - private api2: ApiService<BluePrintDetailModel>) { + constructor( + private api: ApiService<ModelType>, + private api2: ApiService<BluePrintDetailModel> + ) { } getFunctions(modelDefinitionType: string): Observable<ModelType[]> { @@ -50,4 +52,9 @@ export class DesignerService { return this.getBluePrintModel(id); } + publishBlueprint(body: any | null, options?: any): Observable<any> { + + return this.api.post(BlueprintURLs.publish, body, { responseType: 'text' }); + } + } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.store.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.store.ts index ba8b2f0f1..e07fbb94d 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.store.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.store.ts @@ -23,8 +23,8 @@ import {Injectable} from '@angular/core'; import {Store} from '../../../../common/core/stores/Store'; import {DesignerService} from './designer.service'; import {DesignerDashboardState} from './model/designer.dashboard.state'; -import { DeclarativeWorkflow } from './model/designer.workflow'; -import { NodeTemplate } from './model/desinger.nodeTemplate.model'; +import {DeclarativeWorkflow} from './model/designer.workflow'; +import {NodeTemplate} from './model/desinger.nodeTemplate.model'; @Injectable({ @@ -54,7 +54,7 @@ export class DesignerStore extends Store<DesignerDashboardState> { }); } - addStepToDeclarativeWorkFlow(workflowName: string, stepName: string, stepType: string) { + addStepToDeclarativeWorkFlow(workflowName: string, stepName: string, stepType: string) { this.setState({ ...this.state, template: { @@ -76,12 +76,15 @@ export class DesignerStore extends Store<DesignerDashboardState> { } saveSourceContent(code: string) { - const topologyTemplate = JSON.parse(code); - this.setState({ - ...this.state, - sourceContent: code, - template: topologyTemplate - }); + console.log(code); + if (code) { + const topologyTemplate = JSON.parse(code); + this.setState({ + ...this.state, + sourceContent: code, + template: topologyTemplate + }); + } } @@ -141,4 +144,9 @@ export class DesignerStore extends Store<DesignerDashboardState> { } }); } + + clear() { + this.setState(new DesignerDashboardState()); + } + } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.css b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.css new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.css diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.html new file mode 100644 index 000000000..c89a96de0 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.html @@ -0,0 +1,178 @@ +<div class="scrollWrapper"> + <div class="row m-0"> + <div class="col"> + <div class="form-group"> + <label for="exampleInputEmail1">Function Instance Name</label> + <input type="text" class="form-control" placeholder="Function Instance Name"> + </div> + <div class="form-group"> + <label>Function Type</label> + <label class="attribute-value">component-resource-resolution</label> + </div> + <div class="form-group"> + <label for="exampleFormControlTextarea1">Description</label> + <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea> + </div> + </div> + </div> + <!--INTERFACES--> + <div class="accordion" id="accordionExample"> + <div class="card"> + <div class="card-header row" id="headingOne"> + <button class="btn btn-link" type="button" data-toggle="collapse" + data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> + Interfaces + </button> + </div> + + <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" + data-parent="#accordionExample"> + <div class="card-body"> + <!--Inputs & Outputs Tabs--> + <ul class="nav nav-pills nav-fill mb-3" id="pills-tab" role="tablist"> + <li class="nav-item" role="presentation"> + <a class="nav-link active" id="pills-home-tab" data-toggle="pill" + href="#pills-home" role="tab" aria-controls="pills-home" + aria-selected="true">Inputs</a> + </li> + <li class="nav-item" role="presentation"> + <a class="nav-link" id="pills-profile-tab" data-toggle="pill" + href="#pills-profile" role="tab" aria-controls="pills-profile" + aria-selected="false">Outputs</a> + </li> + </ul> + <div class="tab-content" id="pills-tabContent"> + <div class="tab-pane fade show active" id="pills-home" role="tabpanel" + aria-labelledby="pills-home-tab"> + <div class="row"> + <div class="col"> + <!--list--> + <div class="attribute-wrap"> + <div class="form-group"> + <label + for="exampleFormControlTextarea1">artifact-prefix-names + <i class="icon-required-star" type="button" + aria-hidden="true"></i></label> + </div> + <div + class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline1" + name="customRadioInline1" + class="custom-control-input"> + <label class="custom-control-label" + for="customRadioInline1">Pre-defined + Template</label> + </div> + <div + class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline2" + name="customRadioInline1" + class="custom-control-input"> + <label class="custom-control-label" + for="customRadioInline2">Input Drivin + Template</label> + </div> + <br /> + <button type="button" class="btn btn-select-template"><i + class="icon-add-circle" type="button" + aria-hidden="true"></i> Select Template</button> + </div> + <!--string--> + <div class="attribute-wrap"> + <div class="form-group"> + <label for="exampleInputEmail1">resoluton-key <i + class="icon-required-star" type="button" + aria-hidden="true"></i></label> + <input type="text" class="form-control"> + </div> + </div> + <!--integer--> + <div class="attribute-wrap"> + <div class="form-group"> + <label for="exampleInputEmail1">request-id <i + class="icon-required-star" type="button" + aria-hidden="true"></i></label> + <input type="number" class="form-control" placeholder="" + value="356"> + </div> + </div> + <!--boolean--> + <div class="attribute-wrap"> + <div class="form-group"> + <label + for="exampleFormControlTextarea1">resolution-summary + <i class="icon-required-star optional-attribute" + type="button" aria-hidden="true"></i></label> + </div> + <div + class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline1" + name="customRadioInline1" + class="custom-control-input"> + <label class="custom-control-label" + for="customRadioInline1">True</label> + </div> + <div + class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline2" + name="customRadioInline1" + class="custom-control-input"> + <label class="custom-control-label" + for="customRadioInline2">False</label> + </div> + </div> + <!-- Add Optional Attributes button --> + </div> + </div> + </div> + <div class="tab-pane fade" id="pills-profile" role="tabpanel" + aria-labelledby="pills-profile-tab">2</div> + </div> + </div> + </div> + </div> + </div> + <!--ARTIFACTS--> + <div class="accordion" id="accordionExample1"> + <div class="card"> + <div class="card-header row" id="headingOne"> + <button class="btn btn-link" type="button" data-toggle="collapse" + data-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo"> + Artifacts + </button> + </div> + + <div id="collapseTwo" class="collapse show" aria-labelledby="headingOne" + data-parent="#accordionExample1"> + <div class="card-body"> + <div class="row"> + <div class="col-12"> + <a class="template-mapping-list"> + <p>baseconfig</p> + <span>Mapping</span> + <span>Template</span> + + <a data-toggle="modal" + data-target="#templateDeletionModal" + class="accordion-delete deleteTemplate" + title="Delete Template"><i class="icon-delete-sm"></i></a> + </a> + + </div> + <div class="col-12"> + <a class="template-mapping-list"> + <p>vpkg</p> + <span>Mapping</span> + <span>Template</span> + <a data-toggle="modal" + data-target="#templateDeletionModal" + class="accordion-delete deleteTemplate" + title="Delete Template"><i class="icon-delete-sm"></i></a> + </a> + </div> + </div> + </div> + </div> + </div> + </div> +</div> diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.spec.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.spec.ts new file mode 100644 index 000000000..2b41c192a --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FunctionsAttributeComponent } from './functions-attribute.component'; + +describe('FunctionsAttributeComponent', () => { + let component: FunctionsAttributeComponent; + let fixture: ComponentFixture<FunctionsAttributeComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FunctionsAttributeComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FunctionsAttributeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.ts new file mode 100644 index 000000000..88bd76eb6 --- /dev/null +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.ts @@ -0,0 +1,46 @@ +import {Component, OnDestroy, OnInit} from '@angular/core'; +import {DesignerStore} from '../designer.store'; +import {PackageCreationStore} from '../../package-creation/package-creation.store'; +import {Subject} from 'rxjs'; +import {distinctUntilChanged, takeUntil} from 'rxjs/operators'; +import {CBAPackage} from '../../package-creation/mapping-models/CBAPacakge.model'; + +@Component({ + selector: 'app-functions-attribute', + templateUrl: './functions-attribute.component.html', + styleUrls: ['./functions-attribute.component.css'] +}) +export class FunctionsAttributeComponent implements OnInit, OnDestroy { + + ngUnsubscribe = new Subject(); + private designerDashboardState: DecodeSuccessCallback; + private cbaPackage: CBAPackage; + + constructor(private designerStore: DesignerStore, + private packageCreationStore: PackageCreationStore) { + } + + ngOnInit() { + this.designerStore.state$ + .pipe( + distinctUntilChanged((a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)), + takeUntil(this.ngUnsubscribe)) + .subscribe(designerDashboardState => { + this.designerDashboardState = designerDashboardState; + }); + + this.packageCreationStore.state$ + .pipe( + distinctUntilChanged((a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)), + takeUntil(this.ngUnsubscribe)) + .subscribe(cbaPackage => { + this.cbaPackage = cbaPackage; + }); + + } + + ngOnDestroy() { + this.ngUnsubscribe.next(); + this.ngUnsubscribe.complete(); + } +} diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/graph.generator.util.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/graph.generator.util.ts index 8e1d88907..226f54399 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/graph.generator.util.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/graph.generator.util.ts @@ -18,10 +18,9 @@ See the License for the specific language governing permissions and limitations under the License. ============LICENSE_END============================================ */ -import { TopologyTemplate } from './model/designer.topologyTemplate.model'; -import { Injectable } from '@angular/core'; -import { GraphUtil } from './graph.util'; -import { NodeTemplate } from './model/desinger.nodeTemplate.model'; +import {TopologyTemplate} from './model/designer.topologyTemplate.model'; +import {Injectable} from '@angular/core'; +import {GraphUtil} from './graph.util'; @Injectable({ providedIn: 'root' @@ -31,6 +30,10 @@ export class GraphGenerator { constructor(private graphUtil: GraphUtil) { } + clear(boardGraph: joint.dia.Graph) { + boardGraph.clear(); + } + /** * loops over workflows * create action element @@ -79,7 +82,7 @@ export class GraphGenerator { // create action element const actionElement = - this.graphUtil.createCustomActionWithName(workFlowName, boardGraph); + this.graphUtil.createCustomActionWithName(workFlowName, boardGraph); // create board function elements const workflow = topologyTempalte.workflows[workFlowName].steps; @@ -91,7 +94,7 @@ export class GraphGenerator { this.graphUtil.dropFunctionOverActionRelativeToParent( actionElement, - stepName , functionType, boardGraph); + stepName, functionType, boardGraph); // TODO handle dg-generic case (multi-step in the same action) if (functionType === 'dg-generic') { |