diff options
Diffstat (limited to 'cds-ui/designer-client/src/app/modules/feature-modules/packages')
17 files changed, 1339 insertions, 178 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 a281aafae..4ce93057a 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 @@ -82,7 +82,7 @@ <div class="container-fluid body-container"> - + <ngx-ui-loader></ngx-ui-loader> <div class="container"> <div class="creat-action-container"> 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 7ca429dff..766c50a98 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 @@ -1,25 +1,26 @@ -import {Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core'; -import {ActivatedRoute, Router} from '@angular/router'; -import {BluePrintDetailModel} from '../model/BluePrint.detail.model'; -import {PackageCreationStore} from '../package-creation/package-creation.store'; -import {FilesContent, FolderNodeElement} from '../package-creation/mapping-models/metadata/MetaDataTab.model'; -import {MetadataTabComponent} from '../package-creation/metadata-tab/metadata-tab.component'; +import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { BluePrintDetailModel } from '../model/BluePrint.detail.model'; +import { PackageCreationStore } from '../package-creation/package-creation.store'; +import { FilesContent, FolderNodeElement } from '../package-creation/mapping-models/metadata/MetaDataTab.model'; +import { MetadataTabComponent } from '../package-creation/metadata-tab/metadata-tab.component'; import * as JSZip from 'jszip'; -import {ConfigurationDashboardService} from './configuration-dashboard.service'; -import {TemplateTopology, CBADefinition} from '../package-creation/mapping-models/definitions/CBADefinition'; -import {CBAPackage} from '../package-creation/mapping-models/CBAPacakge.model'; -import {PackageCreationUtils} from '../package-creation/package-creation.utils'; -import {PackageCreationModes} from '../package-creation/creationModes/PackageCreationModes'; -import {PackageCreationBuilder} from '../package-creation/creationModes/PackageCreationBuilder'; -import {saveAs} from 'file-saver'; -import {DesignerStore} from '../designer/designer.store'; -import {ToastrService} from 'ngx-toastr'; -import {NgxFileDropEntry} from 'ngx-file-drop'; -import {PackageCreationService} from '../package-creation/package-creation.service'; -import {ComponentCanDeactivate} from '../../../../common/core/canDactivate/ComponentCanDeactivate'; -import {PackageCreationExtractionService} from '../package-creation/package-creation-extraction.service'; -import {distinctUntilChanged, takeUntil} from 'rxjs/operators'; -import {Subject, throwError} from 'rxjs'; +import { ConfigurationDashboardService } from './configuration-dashboard.service'; +import { TemplateTopology, CBADefinition } from '../package-creation/mapping-models/definitions/CBADefinition'; +import { CBAPackage } from '../package-creation/mapping-models/CBAPacakge.model'; +import { PackageCreationUtils } from '../package-creation/package-creation.utils'; +import { PackageCreationModes } from '../package-creation/creationModes/PackageCreationModes'; +import { PackageCreationBuilder } from '../package-creation/creationModes/PackageCreationBuilder'; +import { saveAs } from 'file-saver'; +import { DesignerStore } from '../designer/designer.store'; +import { ToastrService } from 'ngx-toastr'; +import { NgxFileDropEntry } from 'ngx-file-drop'; +import { PackageCreationService } from '../package-creation/package-creation.service'; +import { ComponentCanDeactivate } from '../../../../common/core/canDactivate/ComponentCanDeactivate'; +import { PackageCreationExtractionService } from '../package-creation/package-creation-extraction.service'; +import { distinctUntilChanged, takeUntil } from 'rxjs/operators'; +import { Subject, throwError } from 'rxjs'; +import { NgxUiLoaderService } from 'ngx-ui-loader'; @Component({ selector: 'app-configuration-dashboard', @@ -28,13 +29,13 @@ import {Subject, throwError} from 'rxjs'; }) export class ConfigurationDashboardComponent extends ComponentCanDeactivate implements OnInit, OnDestroy { viewedPackage: BluePrintDetailModel = new BluePrintDetailModel(); - @ViewChild(MetadataTabComponent, {static: false}) + @ViewChild(MetadataTabComponent, { static: false }) metadataTabComponent: MetadataTabComponent; public customActionName = ''; entryDefinitionKeys: string[] = ['template_tags', 'user-groups', 'author-email', 'template_version', 'template_name', 'template_author', 'template_description']; - @ViewChild('nameit', {static: true}) + @ViewChild('nameit', { static: true }) elementRef: ElementRef; uploadedFiles = []; zipFile: JSZip = new JSZip(); @@ -61,6 +62,7 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl private router: Router, private designerStore: DesignerStore, private toastService: ToastrService, + private ngxService: NgxUiLoaderService, private packageCreationExtractionService: PackageCreationExtractionService ) { super(); @@ -69,6 +71,7 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl } ngOnInit() { + this.ngxService.start(); this.vlbDefinition.topology_template = new TemplateTopology(); this.packageCreationStore.state$ .pipe(distinctUntilChanged((a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)), @@ -112,19 +115,26 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl this.downloadCBAPackage(bluePrintDetailModels); this.packageCreationStore.clear(); } + }, err => { }, + () => { + // this.ngxService.stop(); }); } private downloadCBAPackage(bluePrintDetailModels: BluePrintDetailModel) { this.configurationDashboardService.downloadResource( this.viewedPackage.artifactName + '/' + this.viewedPackage.artifactVersion).subscribe(response => { - const blob = new Blob([response], {type: 'application/octet-stream'}); - this.currentBlob = blob; - this.packageCreationExtractionService.extractBlobToStore(blob); - }); + const blob = new Blob([response], { type: 'application/octet-stream' }); + this.currentBlob = blob; + this.packageCreationExtractionService.extractBlobToStore(blob); + }, err => { }, + () => { + this.ngxService.stop(); + }); } editBluePrint() { + this.ngxService.start(); this.configurationDashboardService.deletePackage(this.viewedPackage.id).subscribe(res => { this.formTreeData(); this.saveBluePrintToDataBase(); @@ -148,7 +158,7 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl saveBluePrintToDataBase() { this.create(); - this.zipFile.generateAsync({type: 'blob'}) + this.zipFile.generateAsync({ type: 'blob' }) .then(blob => { this.packageCreationService.savePackage(blob).subscribe( bluePrintDetailModels => { @@ -162,6 +172,8 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl }, error => { this.toastService.error('error happened when editing ' + error.message); console.log('Error -' + error.message); + }, () => { + this.ngxService.stop(); }); }); } @@ -191,20 +203,25 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl } downloadPackage(artifactName: string, artifactVersion: string) { + this.ngxService.start(); this.configurationDashboardService.downloadResource(artifactName + '/' + artifactVersion).subscribe(response => { - const blob = new Blob([response], {type: 'application/octet-stream'}); + const blob = new Blob([response], { type: 'application/octet-stream' }); saveAs(blob, artifactName + '-' + artifactVersion + '-CBA.zip'); + + }, err => { }, () => { + this.ngxService.stop(); }); } deployCurrentPackage() { + this.ngxService.start(); this.formTreeData(); this.deployPackage(); } goToDesignerMode(id) { - this.router.navigate(['/packages/designer', id, {actionName: this.customActionName}]); + this.router.navigate(['/packages/designer', id, { actionName: this.customActionName }]); } public dropped(files: NgxFileDropEntry[]) { @@ -226,6 +243,7 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl } enrichBluePrint() { + this.ngxService.start(); this.packageCreationStore.addTopologyTemplate(this.cbaPackage.templateTopology); this.formTreeData(); this.enrichPackage(); @@ -236,11 +254,11 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl private enrichPackage() { this.create(); - this.zipFile.generateAsync({type: 'blob'}) + this.zipFile.generateAsync({ type: 'blob' }) .then(blob => { this.packageCreationService.enrichPackage(blob).subscribe(response => { console.log('success'); - const blobInfo = new Blob([response], {type: 'application/octet-stream'}); + const blobInfo = new Blob([response], { type: 'application/octet-stream' }); this.currentBlob = blobInfo; this.packageCreationStore.clear(); this.packageCreationExtractionService.extractBlobToStore(this.currentBlob); @@ -250,12 +268,14 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl }, error => { this.toastService.error('error happened when enrich ' + error.message); console.error('Error -' + error.message); + }, () => { + this.ngxService.stop(); }); } private deployPackage() { this.create(); - this.zipFile.generateAsync({type: 'blob'}) + this.zipFile.generateAsync({ type: 'blob' }) .then(blob => { this.packageCreationService.deploy(blob).subscribe(response => { this.toastService.info('deployed successfully '); @@ -265,6 +285,8 @@ export class ConfigurationDashboardComponent extends ComponentCanDeactivate impl }); }, error => { this.handleError(error); + }, () => { + this.ngxService.stop(); }); } 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 index d23628bc7..5a0c9aaad 100644 --- 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 @@ -16,12 +16,13 @@ <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> + <span>Create Custom</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> + <button (click)="printSomethings()" [disabled]="!isFunctionAttributeActive" type="button" + data-toggle="modal" data-target="#exampleModalScrollable3" class="btn btn-secondary"><i + class="icon-function-attribute" type="button" aria-hidden="true"></i></button> + <span>Import From Function</span> </div> </div> </div> @@ -45,7 +46,8 @@ <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> + <i [hidden]="input.required" class="icon-required-star optional-attribute" + type="button" aria-hidden="true"></i> </label> <div class="attributeOptions"> <a data-toggle="modal" data-target="#exampleModalScrollable2" @@ -81,8 +83,8 @@ <label for="exampleFormControlTextarea1">{{output.name}} <i [hidden]="!output.required" class="icon-required-star" type="button" aria-hidden="true"></i> - <i [hidden]="output.required" class="optional-attribute" type="button" - aria-hidden="true"></i> + <i [hidden]="output.required" class="icon-required-star optional-attribute" + type="button" aria-hidden="true"></i> </label> </div> @@ -196,6 +198,22 @@ </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="customRadioInline3" name="customRadioInline3" + class="custom-control-input" (click)="setOutputRequired(true)"> + <label class="custom-control-label" for="customRadioInline3">True</label> + </div> + <div class="custom-control custom-radio custom-control-inline"> + <input type="radio" id="customRadioInline4" name="customRadioInline3" + class="custom-control-input"> + <label class="custom-control-label" for="customRadioInline4" + (click)="setOutputRequired(false)">False</label> + </div> + </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"> @@ -225,22 +243,169 @@ (change)="setOutputType(outputOtherType)"> </div> </div> + <!--Get Attribute Value--> + <div class="form-group row mb-0"> + <label class="col-form-label col pt-0"> + Value <span class="notation">(get_attribute)</span> + </label> + </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="customRadioInline3" name="customRadioInline3" - class="custom-control-input" (click)="setOutputRequired(true)"> - <label class="custom-control-label" for="customRadioInline3">True</label> - </div> - <div class="custom-control custom-radio custom-control-inline"> - <input type="radio" id="customRadioInline4" name="customRadioInline3" - class="custom-control-input"> - <label class="custom-control-label" for="customRadioInline4" - (click)="setOutputRequired(false)">False</label> + <div class="col"> + <input type="email" class="form-control" id="inputEmail3" placeholder="Attributes"> + <div class="container"> + <!-- <div *ngFor="let tempInput of steps">{{tempInput}}</div>--> </div> </div> </div> + + + <section class="carousel" aria-label="Gallery"> + + <ol class="carousel__viewport"> + <!--Function--> + <li id="carousel__slide1" tabindex="0" class="carousel__slide"> + <b class="listBoxTitle">1. Choose Function Name</b> + <div class="list-group addedFunctionsList" id="list-tab" role="tablist"> + <input type="text" class="form-control input-search-controller" + placeholder="Functions"> + <div class="scrollWrapper" *ngFor="let step of steps"> + <a class="list-group-item list-group-item-action active" id="list-home-list" + data-toggle="list" href="#list-home" role="tab" aria-controls="home"> + <i class="icon-resource_resolution mr-1" aria-hidden="true"></i> + {{step}} <i class="icon-next_arrow" aria-hidden="true" (click)="getAttributesAndOutputs( + this.designerState.template.workflows[actionName]['steps'][step]['target'] + )"></i></a> + </div> + </div> + <div class="carousel__snapper" [hidden]="!isNotComponentResourceResolution"> + <a href="#carousel__slide4" [hidden]="isParametersHidden" + class="carousel__prev">Parameters</a> + <a href="#carousel__slide2" class="carousel__next">Attributes</a> + </div> + </li> + <!--Attribute--> + <li id="carousel__slide2" tabindex="1" class="carousel__slide"> + <b class="listBoxTitle">2. Choose Attribute Name</b> + <div class="tab-content nestedAttributes mt-0 p-0" id="nav-tabContent"> + <input type="text" class="form-control input-search-controller" + placeholder="Attributes"> + <div class="tab-pane fade show active" id="list-home" role="tabpanel" + aria-labelledby="list-home-list"> + <div class="scrollWrapper"> + <div *ngIf="suggestedAttributes.length>0" + class="btn-group btn-group-toggle" data-toggle="buttons"> + <label class="btn btn-secondary active" + *ngFor="let suggestedAttribute of suggestedAttributes" + [id]="suggestedAttribute" + (click)="addTempOutputAttr(suggestedAttribute)"> + <input type="radio" name="options" + [id]="suggestedAttribute+'.,.'" + autocomplete="off"> + {{suggestedAttribute}} + </label> + + </div> + <div *ngIf="suggestedAttributes.length == 0"> + <p class="noAttributes">No Attributes Available</p> + </div> + </div> + </div> + </div> + <div class="carousel__snapper"></div> + <a href="#carousel__slide1" class="carousel__prev">Functions</a> + <a href="#carousel__slide3" [hidden]="!isNotComponentResourceResolution" + class="carousel__next">Artifacts</a> + + </li> + <!--Artifact--> + <li id="carousel__slide3" [hidden]="isNotComponentResourceResolution" tabindex="2" + class="carousel__slide"> + <b class="listBoxTitle">3. Choose Artifact Name</b> + <div class="tab-content nestedAttributes mt-0 p-0" id="nav-tabContent"> + <input type="text" class="form-control input-search-controller" + placeholder="Attributes"> + <div class="tab-pane fade show active" id="list-home" role="tabpanel" + aria-labelledby="list-home-list"> + <div class="scrollWrapper"> + <div *ngIf="currentArtifacts.length>0" + class="btn-group btn-group-toggle" data-toggle="buttons"> + <label class="btn btn-secondary active" + *ngFor="let suggestedArtifact of currentArtifacts" + (click)="addArtifactFile(suggestedArtifact)"> + <input type="radio" name="options" [id]="suggestedArtifact" + autocomplete="off" + (click)="addTempOutputAttr(suggestedArtifact)"> + {{suggestedArtifact}} + </label> + + </div> + <div *ngIf="currentArtifacts.length == 0"> + <p class="noAttributes">No Artifacts Available</p> + </div> + </div> + </div> + </div> + <div class="carousel__snapper" [hidden]="!isNotComponentResourceResolution"> + <a href="#carousel__slide2" class="carousel__prev">Attributes</a> + <a href="#carousel__slide4" [hidden]="isParametersHidden" + class="carousel__next">Parmeters</a> + </div> + </li> + <!--Parameter--> + <li id="carousel__slide4" + [hidden]="isParametersHidden" tabindex="3" + class="carousel__slide"> + <b class="listBoxTitle">4. Choose Parameter Name</b> + <div class="tab-content nestedAttributes mt-0 p-0" id="nav-tabContent"> + <input type="text" class="form-control input-search-controller" + placeholder="Attributes"> + <div class="tab-pane fade show active" id="list-home" role="tabpanel" + aria-labelledby="list-home-list"> + <div class="scrollWrapper"> + <div *ngIf="suggestedAttributes.length>0" + class="btn-group btn-group-toggle" data-toggle="buttons"> + <label class="btn btn-secondary active" + *ngFor="let suggestedAttribute of suggestedAttributes" + (click)="addTempOutputAttr(suggestedAttribute)"> + <input type="radio" name="options" [id]="suggestedAttribute" + autocomplete="off" + (click)="addTempOutputAttr(suggestedAttribute)"> + {{suggestedAttribute}} + </label> + + </div> + <div *ngIf="suggestedAttributes.length == 0"> + <p class="noAttributes">No Attributes Available</p> + </div> + </div> + </div> + </div> + <div class="carousel__snapper"></div> + <a href="#carousel__slide3" [hidden]="isNotComponentResourceResolution" + class="carousel__prev">Artifacts</a> + <a href="#carousel__slide1" class="carousel__next">Functions</a> + + </li> + </ol> + <aside class="carousel__navigation"> + <ol class="carousel__navigation-list"> + <li class="carousel__navigation-item"> + <a href="#carousel__slide1" class="carousel__navigation-button">Functions</a> + </li> + <li class="carousel__navigation-item"> + <a href="#carousel__slide2" class="carousel__navigation-button">Attributes</a> + </li> + <li class="carousel__navigation-item" [hidden]="isNotComponentResourceResolution"> + <a href="#carousel__slide3" class="carousel__navigation-button">Artifacts</a> + </li> + <li class="carousel__navigation-item" + [hidden]="isParametersHidden"> + <a href="#carousel__slide4" + class="carousel__navigation-button">Parameters</a> + </li> + </ol> + </aside> + </section> </div> </div> </div> @@ -251,6 +416,154 @@ </div> </div> </div> + +<!--Action - Add Attribute From Function - Modal--> +<div class="modal fade" id="exampleModalScrollable3" tabindex="-1" role="dialog" + aria-labelledby="exampleModalScrollableTitle3" aria-hidden="true"> + <div class="modal-dialog modal-dialog-scrollable" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="exampleModalScrollableTitle3"> + Add Attributes from Function</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="#input" 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="#output" role="tab" + aria-controls="profile" aria-selected="false">Outputs</a> + </li> + </ul> + <div class="tab-content border-0 mt-2" id="myTabContent"> + <!--INPUTS Tab--> + <div class="tab-pane fade show active create-form" id="input" role="tabpanel" + aria-labelledby="input-tab"> + <div class="form-group row"> + <div class="col"> + <input type="email" class="form-control" id="inputEmail3" placeholder="Attributes"> + <div class="container"> + <div *ngFor="let tempInput of tempInputs">{{tempInput}}</div> + </div> + </div> + </div> + + <div class="row"> + <div class="col-6"> + <b class="listBoxTitle">1. Choose Function Name</b> + <div class="list-group addedFunctionsList" id="list-tab" role="tablist"> + <input type="text" class="form-control input-search-controller" + placeholder="Functions"> + <div class="scrollWrapper" *ngFor="let step of steps"> + <a class="list-group-item list-group-item-action active" id="list-home-list" + data-toggle="list" href="#list-home" role="tab" aria-controls="home"><i + class="icon-resource_resolution mr-1" aria-hidden="true"></i> + {{step}} <i class="icon-next_arrow" aria-hidden="true" (click)="setInputAndOutputs( + this.designerState.template.workflows[actionName]['steps'][step]['target'] + )"></i></a> + </div> + </div> + </div> + <div class="col-6"> + <b class="listBoxTitle">2. Choose Input Attribute Name</b> + <div class="tab-content nestedAttributes mt-0 p-0" id="nav-tabContent"> + <input type="text" class="form-control input-search-controller" + placeholder="Attributes"> + <div class="tab-pane fade show active" id="list-home" role="tabpanel" + aria-labelledby="list-home-list"> + <div class="scrollWrapper"> + <div *ngIf="suggestedInputs.length>0" class="btn-group btn-group-toggle" + data-toggle="buttons"> + <label class="btn btn-secondary active" + *ngFor="let suggestedInput of suggestedInputs" + (click)="addTempInput(suggestedInput)"> + <input type="radio" name="options" [id]="suggestedInput" + autocomplete="off" (click)="addTempInput(suggestedInput)"> + {{suggestedInput}} + </label> + </div> + <div *ngIf="suggestedInputs.length == 0"> + <p class="noAttributes">No Attributes Available</p> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + <!--OUTPUTS Tab--> + <div class="tab-pane fade create-form" id="output" role="tabpanel" aria-labelledby="output-tab"> + <div class="form-group row"> + <div class="col"> + <input type="email" class="form-control" id="inputEmail3" placeholder="Attributes"> + <div class="container"> + <div *ngFor="let tempOutput of tempOutputs">{{tempOutput}}</div> + </div> + </div> + </div> + + <div class="row"> + <div class="col-6"> + <b class="listBoxTitle">1. Choose Function Name</b> + <div class="list-group addedFunctionsList" id="list-tab" role="tablist"> + <input type="text" class="form-control input-search-controller" + placeholder="Functions"> + <div class="scrollWrapper" *ngFor="let step of steps"> + <a class="list-group-item list-group-item-action active" id="list-home-list" + data-toggle="list" href="#list-home" role="tab" aria-controls="home"><i + class="icon-resource_resolution mr-1" aria-hidden="true"></i> + {{step}} <i class="icon-next_arrow" aria-hidden="true" (click)="setInputAndOutputs( + this.designerState.template.workflows[actionName]['steps'][step]['target'] + )"></i></a> + </div> + </div> + </div> + <div class="col-6"> + <b class="listBoxTitle">2. Choose output Attribute Name</b> + <div class="tab-content nestedAttributes mt-0 p-0" id="nav-tabContent"> + <input type="text" class="form-control input-search-controller" + placeholder="Attributes"> + <div class="tab-pane fade show active" id="list-home" role="tabpanel" + aria-labelledby="list-home-list"> + <div class="scrollWrapper"> + <div *ngIf="suggestedOutputs.length > 0" class="btn-group btn-group-toggle" + data-toggle="buttons"> + <label class="btn btn-secondary active" + *ngFor="let suggestedOutput of suggestedOutputs"> + <input type="radio" name="options" [id]="suggestedOutput" + autocomplete="off" + (dblclick)="addTempOutput(suggestedOutput)"> + {{suggestedOutput}} + </label> + + </div> + <div *ngIf="suggestedOutputs.length == 0"> + <p class="noAttributes">No Attributes Available</p> + </div> + </div> + </div> + </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)="submitTempAttributes()">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"> 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 index 752f0502d..babfec772 100644 --- 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 @@ -3,6 +3,8 @@ import {InputActionAttribute, OutputActionAttribute} from './models/InputActionA import {DesignerStore} from '../designer.store'; import {DesignerDashboardState} from '../model/designer.dashboard.state'; import {Action} from './models/Action'; +import {FunctionsStore} from '../functions.store'; +import {FunctionsState} from '../model/functions.state'; @Component({ selector: 'app-action-attributes', @@ -13,6 +15,8 @@ export class ActionAttributesComponent implements OnInit { inputs = []; outputs = []; + newInputs = []; + newOutputs = []; actionAttributesSideBar: boolean; inputActionAttribute = new InputActionAttribute(); outputActionAttribute = new OutputActionAttribute(); @@ -22,17 +26,46 @@ export class ActionAttributesComponent implements OnInit { inputOtherType = ''; actionName = ''; designerState: DesignerDashboardState; + isFunctionAttributeActive = false; + functions: FunctionsState; + steps: string[]; + suggestedInputs: string[] = []; + suggestedOutputs: string[] = []; - constructor(private designerStore: DesignerStore) { + tempInputs: string[] = []; + tempOutputs: string[] = []; + currentInterfaceName: string; + functionAndAttributesInput: Map<string, string[]> = new Map<string, string[]>(); + private currentTargetFunctionName: any; + private functionAndAttributesOutput: Map<string, string[]> = new Map<string, string[]>(); + suggestedAttributes: string[] = []; + selectedFunctionName = ''; + selectedAttributeName = ''; + isNotComponentResourceResolution = true; + currentArtifacts: string[] = []; + isParametersHidden = true; + + constructor(private designerStore: DesignerStore, private functionsStore: FunctionsStore) { } ngOnInit() { + console.log('is paramters hidden' + this.isParametersHidden); + console.log('is artifacts hidden' + this.isNotComponentResourceResolution); this.designerStore.state$.subscribe(designerState => { this.designerState = designerState; if (this.designerState && this.designerState.actionName) { this.actionName = this.designerState.actionName; + console.log(this.actionName); const action = this.designerState.template.workflows[this.actionName] as Action; + if (action.steps) { + const steps = Object.keys(action.steps); + this.isFunctionAttributeActive = steps && steps.length > 0; + this.steps = steps; + this.suggestedOutputs = []; + this.suggestedInputs = []; + } + this.inputs = []; if (action.inputs) { const namesOfInput = Object.keys(action.inputs); @@ -45,6 +78,10 @@ export class ActionAttributesComponent implements OnInit { } } }); + + this.functionsStore.state$.subscribe(functions => { + this.functions = functions; + }); } @@ -65,14 +102,15 @@ export class ActionAttributesComponent implements OnInit { addInput(input: InputActionAttribute) { if (input && input.type && input.name) { const insertedInputActionAttribute = Object.assign({}, input); - this.inputs.push(insertedInputActionAttribute); + this.newInputs.push(insertedInputActionAttribute); } } addOutput(output: OutputActionAttribute) { + console.log(output); if (output && output.type && output.name) { const insertedOutputActionAttribute = Object.assign({}, output); - this.outputs.push(insertedOutputActionAttribute); + this.newOutputs.push(insertedOutputActionAttribute); } } @@ -100,10 +138,21 @@ export class ActionAttributesComponent implements OnInit { submitAttributes() { this.addInput(this.inputActionAttribute); + if (this.selectedFunctionName && this.selectedAttributeName) { + this.outputActionAttribute.value = + '["' + this.selectedFunctionName + '","' + this.selectedAttributeName + '"]'; + } this.addOutput(this.outputActionAttribute); this.clearFormInputs(); - this.designerStore.setInputsAndOutputsToSpecificWorkflow(this.storeInputs(this.inputs) - , this.storeOutputs(this.outputs), this.actionName); + this.storeOutputs(this.newOutputs); + this.storeInputs((this.newInputs)); + this.newInputs.forEach(input => { + this.inputs.push(input); + }); + + this.newOutputs.forEach(output => { + this.outputs.push(output); + }); } private clearFormInputs() { @@ -120,28 +169,233 @@ export class ActionAttributesComponent implements OnInit { inputs += this.appendAttributes(input); }); - if (inputs.endsWith(',')) { - inputs = inputs.substr(0, inputs.length - 1); - } - return JSON.parse('{' + inputs + '}'); + this.writeAttribute(inputs, 'inputs'); } private storeOutputs(OutputActionAttributes: OutputActionAttribute[]) { let outputs = ''; OutputActionAttributes.forEach(output => { - outputs += this.appendAttributes(output); + outputs += this.appendOutputAttributes(output); + }); + this.writeAttribute(outputs, 'outputs'); + } + + private appendAttributes(inputActionAttribute: InputActionAttribute) { + return '"' + inputActionAttribute.name + '" : {\n' + + ' "required" : ' + inputActionAttribute.required + ',\n' + + ' "type" : "' + inputActionAttribute.type + '",\n' + + ' "description" : "' + inputActionAttribute.description + '"\n' + + ' },'; + } + + setInputAndOutputs(targetName) { + console.log(targetName); + const nodeTemplate = this.designerState.template.node_templates[targetName]; + console.log(this.designerState.template.node_templates); + console.log(nodeTemplate); + /* tslint:disable:no-string-literal */ + console.log(nodeTemplate['type']); + this.functions.serverFunctions + /* tslint:disable:no-string-literal */ + .filter(currentFunction => currentFunction.modelName.includes(nodeTemplate['type'])) + .forEach(currentFunction => { + console.log(currentFunction); + /* tslint:disable:no-string-literal */ + if (currentFunction['definition'] && currentFunction['definition']['interfaces']) { + const interfaces = Object.keys(currentFunction['definition']['interfaces']); + if (interfaces && interfaces.length > 0) { + const interfaceName = interfaces[0]; + console.log(interfaceName); + this.currentInterfaceName = interfaceName; + + if (!this.functionAndAttributesInput.has(targetName)) { + this.currentTargetFunctionName = targetName; + this.functionAndAttributesInput.set(targetName, []); + } + + if (!this.functionAndAttributesOutput.has(targetName)) { + this.currentTargetFunctionName = targetName; + this.functionAndAttributesOutput.set(targetName, []); + } + + if (nodeTemplate['interfaces'] && + nodeTemplate['interfaces'][interfaceName]['operations'] && + nodeTemplate['interfaces'][interfaceName]['operations']['process'] + ) { + console.log('here'); + if (nodeTemplate['interfaces'][interfaceName]['operations']['process']['inputs']) { + /* tslint:disable:no-string-literal */ + this.suggestedInputs = Object.keys(nodeTemplate['interfaces'] + [interfaceName]['operations']['process']['inputs']); + } + if (nodeTemplate['interfaces'][interfaceName]['operations']['process']['outputs']) { + /* tslint:disable:no-string-literal */ + this.suggestedOutputs = Object.keys(nodeTemplate['interfaces'] + [interfaceName]['operations']['process']['outputs']); + console.log(this.suggestedInputs); + } + + } + } + } + }); + console.log(nodeTemplate); + } + + printSomethings() { + console.log('something'); + } + + addTempInput(suggestedInput: string) { + this.addAttribute(this.tempInputs, suggestedInput); + this.deleteAttribute(this.suggestedInputs, suggestedInput); + this.addAttribute(this.functionAndAttributesInput.get(this.currentTargetFunctionName), suggestedInput); + } + + addTempOutput(suggestedOutput: string) { + this.addAttribute(this.tempOutputs, suggestedOutput); + this.deleteAttribute(this.suggestedOutputs, suggestedOutput); + this.addAttribute(this.functionAndAttributesOutput.get(this.currentTargetFunctionName), suggestedOutput); + } + + deleteAttribute(container: string[], suggestedAttribute: string) { + if (container && suggestedAttribute && container.includes(suggestedAttribute)) { + const index: number = container.indexOf(suggestedAttribute); + if (index !== -1) { + container.splice(index, 1); + } + } + } + + addAttribute(container: string[], suggestedAttribute: string) { + if (container && suggestedAttribute && !container.includes(suggestedAttribute)) { + container.push(suggestedAttribute); + } + } + + + submitTempAttributes() { + this.writeSelectedAttribute(this.functionAndAttributesInput, 'inputs'); + this.writeSelectedAttribute(this.functionAndAttributesOutput, 'outputs'); + } + + private writeSelectedAttribute(map: Map<string, string[]>, attributeType: string) { + map.forEach((value, key) => { + const nodeTemplate = this.getNodeTemplate(key); + this.functions.serverFunctions + /* tslint:disable:no-string-literal */ + .filter(currentFunction => currentFunction.modelName.includes(nodeTemplate['type'])) + .forEach(currentFunction => { + + if (currentFunction['definition'] && currentFunction['definition']['interfaces'] + [Object.keys(currentFunction['definition'] && currentFunction['definition']['interfaces'])] + ['operations']['process'][attributeType]) { + let newAttributes = ''; + const attributes = currentFunction['definition'] && currentFunction['definition']['interfaces'] + [Object.keys(currentFunction['definition'] && currentFunction['definition']['interfaces'])] + ['operations']['process'][attributeType]; + value.forEach(attribute => { + newAttributes += '"' + attribute + '": ' + this.convertToString(attributes[attribute]) + ','; + }); + if (value.length > 0) { + this.writeAttribute(newAttributes, attributeType); + } + } + }); }); - if (outputs.endsWith(',')) { - outputs = outputs.substr(0, outputs.length - 1); + } + + private writeAttribute(newAttributes: string, attributeType: string) { + newAttributes = this.removeTheLastComma(newAttributes); + const originalAttributes = this.convertToString(this.designerState.template.workflows[this.actionName] + [attributeType]); + console.log(originalAttributes.substr(0, originalAttributes.length - 1) + ',' + newAttributes + '}'); + this.designerState.template.workflows[this.actionName][attributeType] = + this.convertToObject(originalAttributes.substr(0, originalAttributes.length - 1) + + ',' + newAttributes + '}'); + } + + private removeTheLastComma = (newInputs: string) => { + if (newInputs.endsWith(',')) { + newInputs = newInputs.substr(0, newInputs.length - 1); + } + return newInputs; + } + + private convertToString = object => JSON.stringify(object); + + private convertToObject = stringValue => JSON.parse(stringValue); + + private getNodeTemplate = (value: string) => this.designerState.template.node_templates[value]; + + + getAttributesAndOutputs(functionName: string) { + this.suggestedAttributes = []; + console.log(functionName); + if (functionName.includes('component-resource-resolution')) { + this.isNotComponentResourceResolution = false; + this.isParametersHidden = true; + } else { + this.isNotComponentResourceResolution = true; + this.isParametersHidden = true; + } + const nodeTemplate = this.designerState.template.node_templates[functionName]; + console.log(this.designerState.template.node_templates); + console.log(nodeTemplate); + /* tslint:disable:no-string-literal */ + console.log(nodeTemplate['type']); + this.functions.serverFunctions + /* tslint:disable:no-string-literal */ + .filter(currentFunction => currentFunction.modelName.includes(nodeTemplate['type'])) + .forEach(currentFunction => { + if (currentFunction.definition['attributes']) { + Object.keys(currentFunction.definition['attributes']).forEach(attribute => { + this.suggestedAttributes.push(attribute); + this.suggestedAttributes.push('assignment-map'); + }); + } + console.log(this.suggestedAttributes); + + this.selectedFunctionName = functionName; + + + }); + } + + addTempOutputAttr(suggestedOutputAndAttribute: string) { + console.log('ssss'); + this.selectedAttributeName = suggestedOutputAndAttribute; + this.currentArtifacts = []; + const nodeTemplate = this.designerState.template.node_templates[this.selectedFunctionName]; + if (nodeTemplate['artifacts'] + ) { + Object.keys(nodeTemplate['artifacts']).forEach(key => { + const mappingName = key.split('-')[0]; + if (!this.currentArtifacts.includes(mappingName)) { + this.currentArtifacts.push(mappingName); + } + }); } - return JSON.parse('{' + outputs + '}'); + console.log('happend'); + } - private appendAttributes(output: OutputActionAttribute) { + + private appendOutputAttributes(output: OutputActionAttribute) { return '"' + output.name + '" : {\n' + ' "required" : ' + output.required + ',\n' + ' "type" : "' + output.type + '",\n' + - ' "description" : "' + output.description + '"\n' + + ' "description" : "' + output.description + '",\n' + + ' "value\" :' + '{\n' + + ' "get_attribute" : ' + output.value + '\n' + + ' }\n' + ' },'; + + } + + addArtifactFile(suggestedArtifact: string) { + console.log(suggestedArtifact); + this.isParametersHidden = !this.selectedAttributeName.includes('assignment-map'); + console.log('assignement map ' + this.isParametersHidden); } } 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 index b4cce3484..82bdb6076 100644 --- 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 @@ -4,14 +4,16 @@ export class InputActionAttribute { type: string; required: boolean; + constructor() { this.name = ''; this.description = ''; this.type = ''; this.required = true; + } } export class OutputActionAttribute extends InputActionAttribute { - + value = ''; } 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 f15d735f6..b076af378 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 @@ -272,6 +272,10 @@ button.rotate{ left: 0; height: 95%; } */ +/* .ng-sidebar__content.ng-sidebar__content--animate{ + padding-top: 70px !important; +} */ + .functionsList tspan{ /* width:30px !important; */ font: normal 13px sans-serif; @@ -337,6 +341,45 @@ p.compType-4{ margin: 0 auto; background: red; } +.actionSubList{ + margin:0 0 0 4px; /* indentation */ + padding:0; + list-style:none; + position:relative; +} +.actionSubList:before { + content: ""; + display: block; + width: 0; + position: absolute; + top: 0; + bottom: 0; + left: 0; + border-left: 1px solid #C1CDDD; +} +.actionSubList li{ + margin: 0; + padding: 0 1.5em; /* indentation + .5em */ + line-height: 32px; + position: relative; +} +.actionSubList li::before{ + content: ""; + display: block; + width: 10px; /* same with indentation */ + height: 0; + border-top: 1px solid #C1CDDD; + margin-top: -1px; /* border top width */ + position: absolute; + top: 16px; /* (line-height/2) */ + left: 0; +} +.actionSubList li:last-child:before { + background: #F4F9FE; /* same with body background */ + height: auto; + top: 16px; /* (line-height/2) */ + bottom: 0; +} .controllerSidebar{ width: 320px; @@ -400,7 +443,10 @@ p.compType-4{ font-weight: bold; /* outline: 0 !important; */ float: left; - +} +.actionsList li:hover, +.actionsList li label:hover{ + cursor: pointer; } .new-action, .new-action:hover{ @@ -674,6 +720,9 @@ p.compType-4{ background-color: #1B3E6F; color: #fff !important; } +.add-attribute .btn i{ + font-weight: bold; +} .attributesContainer h1{ margin-bottom: 10px; padding: 12px 0 12px 15px; @@ -802,6 +851,7 @@ p.compType-4{ height: 60px; } .icon-required-star{ + margin-left: 2px; font-size: 10px; } .optional-attribute::before{ @@ -1096,6 +1146,9 @@ ul.editor{ .modal{ top: 60px; } +.modal-dialog-scrollable{ + max-height: calc(100% - 20%) !important; +} .modal-backdrop{ z-index: 0 !important; opacity: 0 !important; @@ -1106,11 +1159,16 @@ ul.editor{ max-width: 50%; } .modal-body{ + padding: 18px 24px !important; font-size: 14px; } + .createAttributeTabs .nav-link{ padding-top: 0 !important; } +.createAttributeTabs .nav-item a{ + color: #C3CDDB !important; +} .createAttributeTabs .nav-item a, .createAttributeTabs .nav-item a.active{ border-radius: 0 !important; @@ -1132,6 +1190,98 @@ ul.editor{ padding: 20px 50px; border: solid 1px #F4F9FE; } +.createAttributeTabs .listBoxTitle{ + font-size: 11px; + line-height: 29px; +} +.createAttributeTabs .notation{ + margin-left: 3px; + color: #C3CDDB !important; + font-weight: normal; +} +.addedFunctionsList, +.nestedAttributes{ + background: #F4F9FE; + border: solid 1px #D0DFF1 !important; +} +.addedFunctionsList .scrollWrapper, +.nestedAttributes .scrollWrapper{ + height: 230px; + max-height: 300px; + overflow-y: auto; +} +.addedFunctionsList .input-search-controller, +.nestedAttributes .input-search-controller{ + height: 32px; + padding-left: 28px !important; + background-position: 9px; +} +.addedFunctionsList .input-search-controller::placeholder, +.nestedAttributes .input-search-controller::placeholder{ + font-weight: bold; +} +.create-form .addedFunctionsList .input-search-controller:focus, +.create-form .nestedAttributes .input-search-controller:focus{ + background-color: #fff !important; +} +.nestedAttributes .noAttributes{ + margin: 12px; + font-weight: bold; + font-size: 12px; +} +.addedFunctionsList .list-group-item{ + margin-bottom: 0; + padding-left: 10px; + padding-right: 12px; + text-align: left; + font-size: 12px; + border: 0 !important; + border-radius: 0 !important; + background-color: transparent !important; +} +.addedFunctionsList .list-group-item:hover{ + background-color: #fff !important; + color: #1B3E6F; +} +.addedFunctionsList .list-group-item.active{ + background-color: #E0E8F2 !important; +} +.addedFunctionsList .list-group-item i{ + font-size: 18px; + vertical-align: middle; +} +.addedFunctionsList .list-group-item i:last-child{ + float: right; + font-size: 10px; + line-height: 20px; +} +.nestedAttributes .btn-group{ + display: grid; +} +.nestedAttributes .btn-group .btn{ + padding-left: 10px !important; + padding-right: 10px !important; + height: 36px; + border-radius: 0; + background-color: transparent; + border: 0; + color: #1B3E6F !important; + text-align: left; + font-weight: normal; + line-height: 24px; +} +.nestedAttributes .btn-group .btn:hover{ + background-color: #fff !important; +} +.nestedAttributes .btn-group .btn.active, +.nestedAttributes .btn-group .btn.active:hover{ + background-color: #E0E8F2 !important; + outline: 0; +} +.nestedAttributes .btn-group .btn.active:focus{ + box-shadow: none; + border: 0; +} /*FORM*/ .create-form .col-form-label{ color: #1B3E6F; @@ -1252,4 +1402,250 @@ ul.editor{ margin: 12px; padding: 8px 12px !important; line-height: 14px; -}
\ No newline at end of file +} +.testttt .test0{ + width: 48%; + margin: 0 1%; +} + + + + + + + +@keyframes tonext { + 75% { + left: 0; + } + 95% { + left: 100%; + } + 98% { + left: 100%; + } + 99% { + left: 0; + } +} + +@keyframes tostart { + 75% { + left: 0; + } + 95% { + left: -300%; + } + 98% { + left: -300%; + } + 99% { + left: 0; + } +} + +@keyframes snap { + 96% { + scroll-snap-align: center; + } + 97% { + scroll-snap-align: none; + } + 99% { + scroll-snap-align: none; + } + 100% { + scroll-snap-align: center; + } +} + + + +* { + box-sizing: border-box; + scrollbar-color: transparent transparent; /* thumb and track color */ + scrollbar-width: 0px; +} + +*::-webkit-scrollbar { + width: 0; +} + +*::-webkit-scrollbar-track { + background: transparent; +} + +*::-webkit-scrollbar-thumb { + background: transparent; + border: none; +} + +* { + -ms-overflow-style: none; +} + + +.carousel { + position: relative; + height: 360px; + /* padding-top: 75%; */ + /* filter: drop-shadow(0 0 10px #0003); */ + /* perspective: 100px; */ +} + +.carousel__viewport { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; + margin-top: 40px; + margin-bottom: 0; + padding: 0 12px 0 0; + overflow-x: scroll; + counter-reset: item; + scroll-behavior: smooth; + scroll-snap-type: x mandatory; +} + +.carousel__slide { + position: relative; + flex: 0 0 50%; + width: 100%; + margin-right: 12px; + counter-increment: item; + list-style: none; +} + +/* +.carousel__slide:before { + position: absolute; + top: 50%; + left: 50%; + transform: translate3d(-50%,-40%,70px); + color: #fff; + font-size: 2em; +} */ + +.carousel__snapper { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + scroll-snap-align: center; +} + +@media (hover: hover) { + .carousel__snapper { + animation-name: tonext, snap; + animation-timing-function: ease; + animation-duration: 4s; + animation-iteration-count: infinite; + } + + .carousel__slide:last-child .carousel__snapper { + animation-name: tostart, snap; + } +} + +@media (prefers-reduced-motion: reduce) { + .carousel__snapper { + animation-name: none; + } +} + +.carousel:hover .carousel__snapper, +.carousel:focus-within .carousel__snapper { + animation-name: none; +} + +.carousel__navigation { + position: absolute; + right: 0; + top: 0; + left: 0; + text-align: center; + +} + +.carousel__navigation-list, +.carousel__navigation-item{ + display: inline-block; + margin-bottom: 0; +} +.carousel__navigation-item{ + width: 100px; + padding: 6px 12px; + background-color: #DEE8F3; + border-right: solid 1px #C8D6E6; + font-size: 11px; + font-weight: bold; +} +.carousel__navigation-item:first-child{ + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.carousel__navigation-item:last-child{ + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + border-right: 0; +} +.carousel__navigation-button, +.carousel__navigation-button:hover{ + display: inline-block; + width: auto; + /* background-clip: content-box; */ + transition: transform 0.1s; + color: #1B3E6F; +} +.carousel__navigation-button:hover{ + text-decoration: none; +} +.carousel::before, +.carousel::after, +.carousel__prev, +.carousel__next{ + position: absolute; + top: 0; + margin-top: 0; + width: 4rem; + transform: translateY(0); + border-radius: 3px; + font-size: 0; + outline: 0; +} + +/* .carousel::before, +.carousel__prev { + left: -1rem; +} + +.carousel::after, +.carousel__next { + right: -1rem; +} */ + +/* .carousel::before, +.carousel::after { + content: ''; + z-index: 1; + background-color: #333; + background-size: 1.5rem 1.5rem; + background-repeat: no-repeat; + background-position: center center; + color: #fff; + font-size: 2.5rem; + line-height: 4rem; + text-align: center; + pointer-events: none; +} + +.carousel::before { + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolygon points='0,50 80,100 80,0' fill='%23fff'/%3E%3C/svg%3E"); +} + +.carousel::after { + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolygon points='100,50 20,100 20,0' fill='%23fff'/%3E%3C/svg%3E"); +} */ 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 a552c28f6..3ca377df7 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 @@ -12,7 +12,7 @@ <li class="breadcrumb-item"> <a routerLink="/packages/package/{{viewedPackage.id}}">{{viewedPackage.artifactName}}</a> <button type="button" class="btn package-info-btn tooltip-bottom" data-toggle="modal" - data-target="#exampleModalLong" data-tooltip="Package Details"> + data-target="#exampleModalLong" data-tooltip="Package Details"> <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> @@ -107,7 +107,7 @@ <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--> @@ -119,9 +119,9 @@ <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> @@ -162,7 +162,7 @@ <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 + class="btn btn-secondary topologyView">Scripting </button> </div> </li> @@ -173,15 +173,15 @@ <ng-sidebar-container class="sidebar-container"> <!--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> @@ -190,7 +190,7 @@ <div class="tab-content" id="nav-tabContent"> <!--Action List--> <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"> @@ -200,11 +200,11 @@ Action Attributes </button> --> </div> - <div class="col text-center"> + <!-- <div class="col text-center"> <button (click)="sidebarRight2.open()" type="button" class="btn btn-secondary"> Function Attributes </button> - </div> + </div> --> </div> <button (click)="insertCustomActionIntoBoard()" type="button" class="btn new-action"> + New Action @@ -217,11 +217,20 @@ <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> + <label (click)="openActionAttributes(customActionName)" + [attr.for]="customActionName"> + <i class="icon-file" aria-hidden="true" class="icon-file"></i> {{customActionName}} </label> + + <ul *ngIf="customActionName.includes(this.currentActionName)" + class="actionSubList"> + <li (click)="openFunctionAttributes(currentFunction)" + [attr.for]="customActionName" *ngFor="let currentFunction of steps"> + <span>{{getTarget(currentFunction)}}</span> + </li> + </ul> </li> + </ul> </div> </div> @@ -279,7 +288,7 @@ <!--<button (click)="_toggleSidebar2()" style="float:right;">Toggle sidebar right</button> --> </div> <ng-sidebar [(opened)]="actionAttributesSideBar" [sidebarClass]="'demo-sidebar attributesSideBar '" [mode]="'push'" - [position]="'right'" #sidebarRight1> + [position]="'right'" #sidebarRight1> <div class="container-fluid0"> <div class="row m-0"> <div class="col attributesContainer"> @@ -292,9 +301,9 @@ <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> + 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="btn trash-item" tooltip="Delete Action" placement="bottom"><i class="icon-delete-sm" aria-hidden="true"></i></button> </div> </div> @@ -306,24 +315,24 @@ </ng-sidebar> <!--Right Side Menu - Function Attribute--> <ng-sidebar [(opened)]="functionAttributeSidebar" [sidebarClass]="'demo-sidebar attributesSideBar'" [mode]="'push'" - [position]="'right'" #sidebarRight2> + [position]="'right'" #sidebarRight2> <div class="container-fluid0"> <div class="row m-0"> <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> + placement="bottom"><i class="icon-close" type="button" aria-hidden="true"></i> </button> </div> <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> + 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> + placement="bottom"><i class="icon-delete-sm" type="button" + aria-hidden="true"></i></button> </div> </div> </div> @@ -334,4 +343,4 @@ </ng-sidebar> -</ng-sidebar-container> +</ng-sidebar-container>
\ No newline at end of file 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 77e0ceed6..88f28b780 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 @@ -25,32 +25,33 @@ limitations under the License. import dagre from 'dagre'; import graphlib from 'graphlib'; -import {Component, OnDestroy, OnInit, ViewEncapsulation} 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} 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 { 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'; +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'; +import { DesignerDashboardState } from './model/designer.dashboard.state'; @Component({ selector: 'app-designer', @@ -74,13 +75,16 @@ export class DesignerComponent implements OnInit, OnDestroy { paletteGraph: joint.dia.Graph; palettePaper: joint.dia.Paper; ngUnsubscribe = new Subject(); - opt = {tx: 100, ty: 100}; + opt = { tx: 100, ty: 100 }; filesData: any = []; folder: FolderNodeElement = new FolderNodeElement(); zipFile: JSZip = new JSZip(); cbaPackage: CBAPackage; actions: string[] = []; dataTarget: string; + steps: string[]; + designerState: DesignerDashboardState; + currentActionName: string; constructor( private designerStore: DesignerStore, @@ -118,7 +122,7 @@ export class DesignerComponent implements OnInit, OnDestroy { publishBluePrint() { this.create(); - this.zipFile.generateAsync({type: 'blob'}) + this.zipFile.generateAsync({ type: 'blob' }) .then(blob => { const formData = new FormData(); formData.append('file', blob); @@ -165,7 +169,7 @@ export class DesignerComponent implements OnInit, OnDestroy { this.packageCreationService.downloadPackage(this.viewedPackage.artifactName + '/' + this.viewedPackage.artifactVersion) .subscribe(response => { - const blob = new Blob([response], {type: 'application/octet-stream'}); + const blob = new Blob([response], { type: 'application/octet-stream' }); this.packageCreationExtractionService.extractBlobToStore(blob); }); } @@ -207,6 +211,7 @@ export class DesignerComponent implements OnInit, OnDestroy { distinctUntilChanged((a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)), takeUntil(this.ngUnsubscribe)) .subscribe(state => { + this.designerState = state; if (state.sourceContent) { console.log('inside desinger.component---> ', state); // generate graph from store objects if exist @@ -227,7 +232,7 @@ export class DesignerComponent implements OnInit, OnDestroy { setLinkVertices: false, marginX: 10, marginY: 10, - clusterPadding: {top: 100, left: 30, right: 10, bottom: 100}, + clusterPadding: { top: 100, left: 30, right: 10, bottom: 100 }, rankDir: 'TB' }); this.actions = []; @@ -463,7 +468,7 @@ export class DesignerComponent implements OnInit, OnDestroy { saveBluePrintToDataBase() { this.create(); - this.zipFile.generateAsync({type: 'blob'}) + this.zipFile.generateAsync({ type: 'blob' }) .then(blob => { this.packageCreationService.savePackage(blob).subscribe( bluePrintDetailModels => { @@ -478,9 +483,28 @@ export class DesignerComponent implements OnInit, OnDestroy { }); } - openFunctionAttributes(customActionName: string) { - console.log('opening here function attributes'); + openActionAttributes(customActionName: string) { + console.log('opening here action attributes'); + this.currentActionName = customActionName; this.actionAttributesSideBar = true; + this.functionAttributeSidebar = false; this.designerStore.setCurrentAction(customActionName); + /* tslint:disable:no-string-literal */ + this.steps = Object.keys(this.designerState.template.workflows[customActionName]['steps']); + } + + openFunctionAttributes(customFunctionName: string) { + // console.log(customFunctionName); + this.actionAttributesSideBar = false; + this.functionAttributeSidebar = true; + // console.log(this.designerState.template.workflows[this.currentActionName] + // ['steps'][customFunctionName]['target']); + this.designerStore.setCurrentFunction(this.designerState.template.workflows[this.currentActionName] + ['steps'][customFunctionName]['target']); + } + + getTarget(stepname) { + return this.designerState.template.workflows[this.currentActionName] + ['steps'][stepname]['target']; } } 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 c59478d91..857654c56 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 @@ -169,4 +169,11 @@ export class DesignerStore extends Store<DesignerDashboardState> { actionName: customActionName }); } + + setCurrentFunction(customFunctionName: string) { + this.setState({ + ...this.state, + functionName: customFunctionName + }); + } } 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 index 3107c9368..ab5bb123e 100644 --- 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 @@ -3,12 +3,12 @@ <div class="col"> <div class="form-group"> <label for="exampleInputEmail1">Function Instance Name</label> - <input type="text" [(ngModel)]="currentFuncion['instance-name']" class="form-control" + <input disabled type="text" [(ngModel)]="currentFuncion['instance-name']" class="form-control" placeholder="Function Instance Name"> </div> <div class="form-group mb-0"> <label>Function Type</label> - <label class="attribute-value">component-resource-resolution</label> + <label class="attribute-value">{{currentFuncion['type']}}</label> </div> <div class="form-group"> <label for="exampleFormControlTextarea1">Description</label> @@ -50,7 +50,7 @@ <div class="row"> <div class="col"> <!--list--> - <div class="attribute-wrap" *ngIf="artifactPrefix"> + <div class="attribute-wrap" [hidden]="!artifactPrefix"> <div class="form-group"> <label for="exampleFormControlTextarea">artifact-prefix-names <i class="icon-required-star" type="button" @@ -58,6 +58,8 @@ </div> <div class="custom-control custom-radio custom-control-inline"> <input type="radio" id="functionRadioInline" name="functionRadioInline" + [checked]="!currentFuncion['inputs']['artifact-prefix-names']?.get_input" + (click)="setArtifact(true)" class="custom-control-input"> <label class="custom-control-label" for="functionRadioInline">Pre-defined Template</label> @@ -204,7 +206,7 @@ </div> </div> </div> - <button class="btn btn-info" (click)="displayFunctionData()">Save</button> + <button class="btn btn-info" (click)="saveFunctionData()">Save</button> </div> <!--function - Select Template - Modal--> 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 index 20305e853..347f304c8 100644 --- 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 @@ -7,6 +7,8 @@ import { CBAPackage } from '../../package-creation/mapping-models/CBAPacakge.mod import { TemplateAndMapping } from '../../package-creation/template-mapping/TemplateAndMapping'; import { FunctionsStore } from '../functions.store'; import { NodeProcess, NodeTemplate } from '../model/desinger.nodeTemplate.model'; +import { DesignerDashboardState } from '../model/designer.dashboard.state'; +import { Action } from '../action-attributes/models/Action'; @Component({ selector: 'app-functions-attribute', @@ -28,6 +30,11 @@ export class FunctionsAttributeComponent implements OnInit, OnDestroy { artifactPrefix = false; currentFuncion = new NodeProcess(); nodeTemplates = new NodeTemplate(''); + designerState: DesignerDashboardState; + actionName = ''; + functionName = ''; + interfaceChildName = ''; + constructor( private designerStore: DesignerStore, @@ -37,13 +44,33 @@ export class FunctionsAttributeComponent implements OnInit, OnDestroy { } 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.designerStore.state$.subscribe(designerDashboardState => { + this.designerState = designerDashboardState; + this.actionName = this.designerState.actionName; + const action = this.designerState.template.workflows[this.actionName] as Action; + this.currentFuncion = new NodeProcess(); + try { + console.log(action); + if (action) { + // this.designerState.functionName + const child = Object.keys(action.steps)[0]; + this.functionName = this.designerState.functionName; + console.log(this.designerState.template.node_templates); + console.log(this.designerState); + console.log(this.designerState.template.node_templates[this.functionName]); + // this.currentFuncion = this.designerState.template.node_templates[this.functionName]; + // reset inouts&outputs + this.requiredInputs = new Map<string, {}>(); + this.requiredOutputs = new Map<string, {}>(); + this.OptionalInputs = new Map<string, {}>(); + this.optionalOutputs = new Map<string, {}>(); + this.toNodeProcess(this.designerState.template.node_templates[this.functionName], this.functionName); + const type = this.designerState.template.node_templates[this.functionName].type; + this.getNodeType(type); + this.onInitMapping(); + } + } catch (e) { } + }); this.packageCreationStore.state$ .subscribe(cbaPackage => { @@ -65,25 +92,86 @@ export class FunctionsAttributeComponent implements OnInit, OnDestroy { this.setIsMappingOrTemplate(key, templateAndMapping, isFromTemplate); }); }); - this.getNodeType('component-resource-resolution'); } + onInitMapping() { + // selectedTemplates , templateAndMappingMap + this.selectedTemplates = new Map<string, TemplateAndMapping>(); + try { + const functionMap = this.designerState.template.node_templates[this.functionName].artifacts; + console.log(this.templateAndMappingMap); + + Object.keys(functionMap).forEach((file) => { + const filename = file.substring(0, file.lastIndexOf('-')); + console.log(filename); + if (this.templateAndMappingMap.has(filename)) { + this.selectedTemplates.set(filename, this.templateAndMappingMap.get(filename)); + } + }); + + + } catch (e) { } + } + + toNodeProcess(nodeTemplate, functionName) { + console.log(nodeTemplate); + this.currentFuncion['instance-name'] = functionName; + // tslint:disable-next-line: no-string-literal + this.currentFuncion['type'] = nodeTemplate['type']; + if (nodeTemplate.interfaces && Object.keys(nodeTemplate.interfaces).length > 0) { + const nodeName = Object.keys(nodeTemplate.interfaces)[0]; + // console.log(Object.keys(nodeTemplate.interfaces)); + // tslint:disable-next-line: no-string-literal + const inputs = nodeTemplate.interfaces[nodeName]['operations']['process']['inputs']; + // tslint:disable-next-line: no-string-literal + const outputs = nodeTemplate.interfaces[nodeName]['operations']['process']['outputs']; + + // console.log(inputs); + + if (inputs) { + for (const [key, value] of Object.entries(inputs)) { + console.log(key + ' - ' + value); + this.currentFuncion.inputs[key] = value; + } + } + if (outputs) { + for (const [key, value] of Object.entries(outputs)) { + console.log(key + '-' + value); + this.currentFuncion.outputs[key] = value; + } + } + } + } ngOnDestroy() { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); } - displayFunctionData() { + addTemplates() { } + saveFunctionData() { + this.nodeTemplates = new NodeTemplate(''); // tslint:disable-next-line: variable-name const node_templates = {}; - const type = 'component-resource-resolution'; - const instanceName = this.currentFuncion['instance-name']; + const finalFunctionData = this.currentFuncion; + // tslint:disable-next-line: no-string-literal + const type = finalFunctionData['type']; + const instanceName = finalFunctionData['instance-name']; // insert selected templates in nodeTemplates.artifacts this.selectedTemplates.forEach((value, key) => { console.log(key); console.log(value); + console.log(finalFunctionData.inputs['artifact-prefix-names']); + + if (finalFunctionData.inputs['artifact-prefix-names'] === undefined) { + finalFunctionData.inputs['artifact-prefix-names'] = [key]; + } else if ( + Array.isArray(finalFunctionData.inputs['artifact-prefix-names']) && + !finalFunctionData.inputs['artifact-prefix-names'].includes(key) + ) { + finalFunctionData.inputs['artifact-prefix-names'].push(key); + } if (value.isMapping) { this.nodeTemplates.artifacts[key + '-mapping'] = { @@ -101,22 +189,24 @@ export class FunctionsAttributeComponent implements OnInit, OnDestroy { }); // instantiate the final node_template object to save - this.nodeTemplates.type = 'component-resource-resolution'; - node_templates[this.currentFuncion['instance-name']] = this.nodeTemplates; + this.nodeTemplates.type = type; + node_templates[finalFunctionData['instance-name']] = this.nodeTemplates; - delete this.currentFuncion['instance-name']; + delete finalFunctionData['instance-name']; + // tslint:disable-next-line: no-string-literal + delete finalFunctionData['type']; this.nodeTemplates.interfaces = { - ResourceResolutionComponent: { + [this.interfaceChildName]: { operations: { process: { - ...this.currentFuncion, + ...finalFunctionData, } } } }; - console.log(this.currentFuncion); + console.log(finalFunctionData); console.log(node_templates); // tslint:disable-next-line: no-unused-expression this.designerStore.addNodeTemplate(instanceName, type, node_templates[instanceName]); @@ -137,10 +227,9 @@ export class FunctionsAttributeComponent implements OnInit, OnDestroy { } - addTemplates() { } setArtifact(predefined: boolean) { if (predefined) { - + this.currentFuncion.inputs['artifact-prefix-names'] = []; } else { this.currentFuncion.inputs['artifact-prefix-names'] = { get_input: 'template-prefix' }; } @@ -177,27 +266,45 @@ export class FunctionsAttributeComponent implements OnInit, OnDestroy { this.functionStore.state$ .subscribe(state => { console.log(state); + console.log(nodeName); const functions = state.serverFunctions; // tslint:disable-next-line: prefer-for-of for (let i = 0; i < functions.length; i++) { if (functions[i].modelName === nodeName) { // tslint:disable: no-string-literal console.log(functions[i].definition['interfaces']); - this.getInputFields(functions[i].definition['interfaces'], 'ResourceResolutionComponent', 'inputs'); - this.getInputFields(functions[i].definition['interfaces'], 'ResourceResolutionComponent', 'outputs'); + this.getInputFields(functions[i].definition['interfaces'], 'outputs'); + this.getInputFields(functions[i].definition['interfaces'], 'inputs'); break; } } }); } - getInputFields(interfaces, nodeName, type) { + getInputFields(interfaces, type) { + + if (type === 'inputs') { + this.requiredInputs = new Map<string, {}>(); + this.OptionalInputs = new Map<string, {}>(); + } else { + this.requiredOutputs = new Map<string, {}>(); + this.optionalOutputs = new Map<string, {}>(); + + } + const nodeName = Object.keys(interfaces)[0]; + this.interfaceChildName = nodeName; + console.log(nodeName + ' ------ ' + type); console.log(interfaces[nodeName]['operations']['process'][type]); const fields = interfaces[nodeName]['operations']['process'][type]; - + this.artifactPrefix = false; for (const [key, value] of Object.entries(fields)) { if (key === 'artifact-prefix-names') { this.artifactPrefix = true; + // in edit&view mode need to check first if this input||output already exists + } else if (key in this.currentFuncion.inputs) { + this.requiredInputs.set(key, Object.assign({}, value)); + } else if (key in this.currentFuncion.outputs) { + this.requiredOutputs.set(key, Object.assign({}, value)); } else if (value['required']) { console.log('This field is required = ' + key); if (type === 'inputs') { diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.dashboard.state.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.dashboard.state.ts index b52eb7cc3..2da7adf31 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.dashboard.state.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.dashboard.state.ts @@ -26,6 +26,7 @@ export class DesignerDashboardState { template: TopologyTemplate; sourceContent: string; actionName: string; + functionName: string; constructor() { this.template = new TopologyTemplate(); diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/desinger.nodeTemplate.model.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/desinger.nodeTemplate.model.ts index bd3240b88..a33db249d 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/desinger.nodeTemplate.model.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/desinger.nodeTemplate.model.ts @@ -3,10 +3,10 @@ export class NodeTemplate { properties?: { 'dependency-node-templates'?: string[] }; - interfaces?: {}; artifacts?: {}; cabapilities?: {}; requirements?: {}; + interfaces?: {}; constructor(type) { this.type = type; 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 e42304ad6..fb21d3bd7 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 @@ -76,6 +76,7 @@ </header> <div class="container-fluid body-container"> + <ngx-ui-loader></ngx-ui-loader> <div class="container"> <div class="creat-action-container"> <!-- <a class="action-button save" [hidden]="!isSaveEnabled" (click)="saveBluePrint()"> 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 c7285774e..96d798c86 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 @@ -19,22 +19,23 @@ limitations under the License. ============LICENSE_END============================================ */ -import {Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core'; -import {FilesContent, FolderNodeElement, MetaDataTabModel} from './mapping-models/metadata/MetaDataTab.model'; +import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { FilesContent, FolderNodeElement, MetaDataTabModel } from './mapping-models/metadata/MetaDataTab.model'; import * as JSZip from 'jszip'; -import {PackageCreationStore} from './package-creation.store'; -import {CBAPackage, Definition} from './mapping-models/CBAPacakge.model'; -import {PackageCreationModes} from './creationModes/PackageCreationModes'; -import {PackageCreationBuilder} from './creationModes/PackageCreationBuilder'; -import {PackageCreationUtils} from './package-creation.utils'; -import {MetadataTabComponent} from './metadata-tab/metadata-tab.component'; -import {Router} from '@angular/router'; -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'; +import { PackageCreationStore } from './package-creation.store'; +import { CBAPackage, Definition } from './mapping-models/CBAPacakge.model'; +import { PackageCreationModes } from './creationModes/PackageCreationModes'; +import { PackageCreationBuilder } from './creationModes/PackageCreationBuilder'; +import { PackageCreationUtils } from './package-creation.utils'; +import { MetadataTabComponent } from './metadata-tab/metadata-tab.component'; +import { Router } from '@angular/router'; +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'; +import { NgxUiLoaderService } from 'ngx-ui-loader'; @Component({ @@ -55,6 +56,7 @@ export class PackageCreationComponent extends ComponentCanDeactivate implements private router: Router, private tourService: TourService, private toastService: ToastrService, + private ngxService: NgxUiLoaderService, private designerStore: DesignerStore) { super(); @@ -62,8 +64,8 @@ export class PackageCreationComponent extends ComponentCanDeactivate implements counter = 0; modes: object[] = [ - {name: 'Designer Mode', style: 'mode-icon icon-designer-mode'}, - {name: 'Scripting Mode', style: 'mode-icon icon-scripting-mode'}]; + { name: 'Designer Mode', style: 'mode-icon icon-designer-mode' }, + { name: 'Scripting Mode', style: 'mode-icon icon-scripting-mode' }]; metaDataTab: MetaDataTabModel = new MetaDataTabModel(); folder: FolderNodeElement = new FolderNodeElement(); zipFile: JSZip = new JSZip(); @@ -71,10 +73,10 @@ export class PackageCreationComponent extends ComponentCanDeactivate implements definition: Definition = new Definition(); isSaveEnabled = false; - @ViewChild(MetadataTabComponent, {static: false}) + @ViewChild(MetadataTabComponent, { static: false }) metadataTabComponent: MetadataTabComponent; - @ViewChild('nameit', {static: true}) + @ViewChild('nameit', { static: true }) elementRef: ElementRef; versionPattern = '^(\\d+\\.)?(\\d+\\.)?(\\*|\\d+)$'; metadataClasses = 'nav-item nav-link active complete'; @@ -108,6 +110,7 @@ export class PackageCreationComponent extends ComponentCanDeactivate implements } saveBluePrint() { + this.ngxService.start(); console.log(this.cbaPackage); FilesContent.clear(); let packageCreationModes: PackageCreationModes; @@ -126,7 +129,7 @@ export class PackageCreationComponent extends ComponentCanDeactivate implements saveBluePrintToDataBase() { this.create(); - this.zipFile.generateAsync({type: 'blob'}) + this.zipFile.generateAsync({ type: 'blob' }) .then(blob => { this.packageCreationService.savePackage(blob).subscribe( bluePrintDetailModels => { @@ -139,6 +142,8 @@ export class PackageCreationComponent extends ComponentCanDeactivate implements }, error => { // this.toastService.error('error happened when editing ' + error.message); console.log('Error -' + error.message); + }, () => { + this.ngxService.stop(); }); }); } diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html index 494256eea..f2aaf5d3a 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/filter-by-tags/filter-by-tags.component.html @@ -1,7 +1,8 @@ <div class="dropdown packagesFilter w-100"> <input class="dropdown-toggle" type="text"> - <div class="dropdown-text">Filter By Tags <span class="fillteredTags">{{checkBoxTages.substr(0,checkBoxTages.length-1)}}</span></div> - <ul class="dropdown-content w-100"> + <div class="dropdown-text">Filter By Tags <span + class="fillteredTags">{{checkBoxTages.substr(0,checkBoxTages.length-1)}}</span></div> + <!-- <ul class="dropdown-content w-100"> <li> <div class="form-group"> <input type="text" (input)="reloadChanges($event)" class="form-control" placeholder="Search" autofocus> @@ -14,5 +15,21 @@ </div> </li> <li class="reset-filter"><a (click)="resetFilter()">Reset filter</a></li> - </ul> -</div> + </ul> --> + + <div class="dropdown-content w-100"> + <div class="form-group"> + <input type="text" (input)="reloadChanges($event)" class="form-control" placeholder="Search" autofocus> + </div> + <ul> + <li *ngFor="let tag of viewedTags"> + <div class="custom-control custom-checkbox"> + <input type="checkbox" (click)="reloadPackages($event)" class="custom-control-input" id={{tag}} + #checkboxes> + <label class="custom-control-label" for={{tag}}>{{tag}}</label> + </div> + </li> + </ul> + <div class="reset-filter"><a (click)="resetFilter()">Reset filter</a></div> + </div> +</div>
\ No newline at end of file diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts index 30677f161..7e6bbbe59 100644 --- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts +++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/packages-dashboard/package-list/package-list.component.ts @@ -39,6 +39,7 @@ export class PackageListComponent implements OnInit { ngOnInit() { + this.ngxLoader.start(); this.packagesStore.getAll(); } |