diff options
author | andre.schmid <andre.schmid@est.tech> | 2022-09-23 12:31:12 +0100 |
---|---|---|
committer | Michael Morris <michael.morris@est.tech> | 2022-10-05 08:18:25 +0000 |
commit | 6ed5592ccb3b2bdb61403f1d1d41d93088cb0709 (patch) | |
tree | 1978737dc736d000dbb34a9ddc50a7e2008ab573 | |
parent | 404bfc9c50e95df1e75dbf8325fae41bfd96871a (diff) |
Add data type view/workspace
Implements a data type workspace, based on the Service/VF workspace,
where it is possible to view a data type information.
Issue-ID: SDC-4193
Signed-off-by: André Schmid <andre.schmid@est.tech>
Change-Id: Ica341efa43e70b4ac85d42d22a1397e0ab6e2794
29 files changed, 1179 insertions, 117 deletions
diff --git a/catalog-ui/configurations/menu.js b/catalog-ui/configurations/menu.js index 38f504bb57..4b462b752a 100644 --- a/catalog-ui/configurations/menu.js +++ b/catalog-ui/configurations/menu.js @@ -299,6 +299,9 @@ const SDC_MENU_CONFIG = { {"text": "Deployment", "action": "onMenuItemPressed", "state": "workspace.deployment"}, {"text": "Properties Assignment", "action": "onMenuItemPressed", "state": "workspace.properties_assignment"}, {"text": "Attributes & Outputs", "action": "onMenuItemPressed", "state": "workspace.attributes_outputs"} + ], + "DataType": [ + {"text": "General", "action": "onMenuItemPressed", "state": "general"}, ] } diff --git a/catalog-ui/src/app/app.ts b/catalog-ui/src/app/app.ts index e7e2828eb5..ba9bd44e03 100644 --- a/catalog-ui/src/app/app.ts +++ b/catalog-ui/src/app/app.ts @@ -29,12 +29,7 @@ import './modules/directive-module.ts'; import './modules/service-module'; import './modules/view-model-module.ts'; import {SdcUiCommon, SdcUiComponents, SdcUiServices} from 'onap-ui-angular'; -import { - CookieService, - DataTypesService, - EcompHeaderService, - LeftPaletteLoaderService -} from "./services"; +import {CookieService, DataTypesService, EcompHeaderService, LeftPaletteLoaderService} from "./services"; import {CacheService, CatalogService, HomeService} from "./services-ng2"; import {AuthenticationService} from "app/ng2/services/authentication.service"; import {CHANGE_COMPONENT_CSAR_VERSION_FLAG, PREVIOUS_CSAR_COMPONENT, States} from "./utils"; @@ -216,7 +211,14 @@ ng1appModule.config([ ); $stateProvider.state( - 'workspace', { + States.TYPE_WORKSPACE, { + url: '/:previousState/type-workspace/:type/:id/:subPage', + template: '<app-type-workspace></app-type-workspace>', + } + ); + + $stateProvider.state( + States.WORKSPACE, { url: '/:previousState/workspace/:id/:type/', params: { 'importedFile': null, @@ -228,7 +230,6 @@ ng1appModule.config([ controller: viewModelsModuleName + '.WorkspaceViewModel', resolve: { injectComponent: ['$stateParams', 'ComponentFactory', 'workspaceService', 'Sdc.Services.CacheService', function ($stateParams, ComponentFactory: ComponentFactory, workspaceService: WorkspaceService, cacheService: CacheService) { - if ($stateParams.id && $stateParams.id.length) { //need to check length in case ID is an empty string return ComponentFactory.getComponentWithMetadataFromServer($stateParams.type.toUpperCase(), $stateParams.id).then( (component: Component) => { @@ -316,7 +317,6 @@ ng1appModule.config([ parent: 'workspace', resolve: { componentData: ['injectComponent', '$stateParams', function (injectComponent: Component, $stateParams) { - //injectComponent.componentService = null; // this is for not passing the service so no one will use old api and start using new api $stateParams.component = injectComponent; return injectComponent; }], @@ -401,7 +401,6 @@ ng1appModule.config([ template: '<composition-page></composition-page>', resolve: { componentData: ['injectComponent', '$stateParams', function (injectComponent: Component, $stateParams) { - //injectComponent.componentService = null; // this is for not passing the service so no one will use old api and start using new api $stateParams.component = injectComponent; return injectComponent; }], @@ -672,7 +671,6 @@ ng1appModule.run([ //handle http config $http.defaults.withCredentials = true; - // $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w'; $http.defaults.headers.common[cookieService.getUserIdSuffix()] = cookieService.getUserId(); DataTypesService.loadDataTypesCache(null); @@ -723,15 +721,15 @@ ng1appModule.run([ }; let onStateChangeStart: Function = (event, toState, toParams, fromState, fromParams): void => { - console.info((new Date()).getTime()); - console.info('$stateChangeStart', toState.name); + console.debug((new Date()).getTime()); + console.debug('$stateChangeStart', toState.name); if (toState.name !== 'error-403' && !authService.getLoggedinUser()) { authService.authenticate().subscribe((userInfo: IUserProperties) => { if (!doesUserHasAccess(toState, userInfo)) { $state.go('error-403'); - console.info('User has no permissions'); + console.debug('User has no permissions'); return; } authService.setLoggedinUser(userInfo); @@ -740,7 +738,6 @@ ng1appModule.run([ removeLoader(); if (authService.getLoggedinUser().role === 'ADMIN') { - // toState.name = "adminDashboard"; $state.go("adminDashboard", toParams); return; } @@ -769,11 +766,10 @@ ng1appModule.run([ if (!doesUserHasAccess(toState, authService.getLoggedinUser())) { event.preventDefault(); $state.go('error-403'); - console.info('User has no permissions'); + console.debug('User has no permissions'); } if (authService.getLoggedinUser().role === 'ADMIN') { - // toState.name = "adminDashboard"; $state.go("adminDashboard", toParams); return; } @@ -798,7 +794,7 @@ ng1appModule.run([ }; let onStateChangeSuccess: Function = (event, toState, toParams, fromState, fromParams): void => { - console.info('$stateChangeSuccess', toState.name); + console.debug('$stateChangeSuccess', toState.name); // Workaround in case we are entering other state then workspace (user move to catalog) // remove the changeComponentCsarVersion, user should open again the VSP list and select one for update. @@ -831,7 +827,7 @@ ng1appModule.run([ let registerStateChangeStartWatcher: Function = (): void => { internalDeregisterStateChangeStartWatcher(); - console.info('registerStateChangeStartWatcher $stateChangeStart'); + console.debug('registerStateChangeStartWatcher $stateChangeStart'); deregisterStateChangeStartWatcher = $rootScope.$on('$stateChangeStart', (event, toState, toParams, fromState, fromParams): void => { onStateChangeStart(event, toState, toParams, fromState, fromParams); }); diff --git a/catalog-ui/src/app/models/data-types.ts b/catalog-ui/src/app/models/data-types.ts index 7fc788bf93..3b0833b5b4 100644 --- a/catalog-ui/src/app/models/data-types.ts +++ b/catalog-ui/src/app/models/data-types.ts @@ -29,36 +29,39 @@ import {PROPERTY_DATA} from "../utils/constants"; export class DataTypeModel { - //server data - name:string; - uniqueId:string; - derivedFromName:string; - derivedFrom:DataTypeModel; - creationTime:string; - modificationTime:string; + name: string; + uniqueId: string; + derivedFromName: string; + derivedFrom: DataTypeModel; + description: string; + creationTime: string; + modificationTime: string; properties: Array<PropertyBEModel>; attributes: Array<AttributeBEModel>; model: Model; - constructor(dataType: DataTypeModel) { - if (dataType) { - this.uniqueId = dataType.uniqueId; - this.name = dataType.name; - this.derivedFromName = dataType.derivedFromName; - if (dataType.derivedFrom) { - this.derivedFrom = new DataTypeModel(dataType.derivedFrom); - } - this.creationTime = dataType.creationTime; - this.modificationTime = dataType.modificationTime; - if (dataType.properties) { - this.properties = []; - dataType.properties.forEach(property => { - this.properties.push(new PropertyBEModel(property)); - }); - } - this.attributes = dataType.attributes; - this.model = dataType.model; + constructor(dataType?: DataTypeModel) { + if (!dataType) { + return; } + + this.uniqueId = dataType.uniqueId; + this.name = dataType.name; + this.description = dataType.description; + this.derivedFromName = dataType.derivedFromName; + if (dataType.derivedFrom) { + this.derivedFrom = new DataTypeModel(dataType.derivedFrom); + } + this.creationTime = dataType.creationTime; + this.modificationTime = dataType.modificationTime; + if (dataType.properties) { + this.properties = []; + dataType.properties.forEach(property => { + this.properties.push(new PropertyBEModel(property)); + }); + } + this.attributes = dataType.attributes; + this.model = dataType.model; } public toJSON = ():any => { diff --git a/catalog-ui/src/app/modules/directive-module.ts b/catalog-ui/src/app/modules/directive-module.ts index 25d8607b6b..70ceb0fed3 100644 --- a/catalog-ui/src/app/modules/directive-module.ts +++ b/catalog-ui/src/app/modules/directive-module.ts @@ -96,6 +96,8 @@ import {DistributionComponent} from '../ng2/pages/workspace/disribution/distribu import {AttributesOutputsComponent} from "../ng2/pages/attributes-outputs/attributes-outputs.page.component"; import {InterfaceDefinitionComponent} from "../ng2/pages/interface-definition/interface-definition.page.component"; import {ToscaFunctionComponent} from '../ng2/pages/properties-assignment/tosca-function/tosca-function.component'; +import {TypeWorkspaceComponent} from "../ng2/pages/type-workspace/type-workspace.component"; +import {TypeWorkspaceGeneralComponent} from "../ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component"; let moduleName: string = 'Sdc.Directives'; let directiveModule: ng.IModule = angular.module(moduleName, []); @@ -321,3 +323,15 @@ directiveModule.directive('toscaFunction', downgradeComponent({ inputs: ['componentInstanceMap', 'property'], outputs: [] }) as angular.IDirectiveFactory); + +directiveModule.directive('appTypeWorkspace', downgradeComponent({ + component: TypeWorkspaceComponent, + inputs: [], + outputs: [] +}) as angular.IDirectiveFactory); + +directiveModule.directive('appTypeWorkspaceGeneral', downgradeComponent({ + component: TypeWorkspaceGeneralComponent, + inputs: [], + outputs: [] +}) as angular.IDirectiveFactory); diff --git a/catalog-ui/src/app/modules/view-model-module.ts b/catalog-ui/src/app/modules/view-model-module.ts index dd08135f33..084219ab1a 100644 --- a/catalog-ui/src/app/modules/view-model-module.ts +++ b/catalog-ui/src/app/modules/view-model-module.ts @@ -37,6 +37,11 @@ import {ManagementWorkflowViewModel} from "../view-models/workspace/tabs/managem import {InterfaceOperationViewModel} from "../view-models/workspace/tabs/interface-operation/interface-operation-view-model"; import {NetworkCallFlowViewModel} from "../view-models/workspace/tabs/network-call-flow/network-call-flow-view-model"; import {InterfaceDefinitionViewModel} from "../view-models/workspace/tabs/interface-definition/interface-definition-view-model"; +import {TypeWorkspaceComponent} from "../ng2/pages/type-workspace/type-workspace.component"; +import {downgradeComponent} from "@angular/upgrade/static"; +import {WorkspaceMenuComponent} from "../ng2/pages/type-workspace/workspace-menu/workspace-menu.component"; +import {TypeWorkspaceGeneralComponent} from "../ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component"; + let moduleName:string = 'Sdc.ViewModels'; let viewModelModule:ng.IModule = angular.module(moduleName, []); @@ -61,4 +66,7 @@ viewModelModule .controller(moduleName + '.ManagementWorkflowViewModel', ManagementWorkflowViewModel) .controller(moduleName + '.InterfaceOperationViewModel', InterfaceOperationViewModel) .controller(moduleName + '.InterfaceDefinitionViewModel', InterfaceDefinitionViewModel) - .controller(moduleName + '.NetworkCallFlowViewModel', NetworkCallFlowViewModel); + .controller(moduleName + '.NetworkCallFlowViewModel', NetworkCallFlowViewModel) + .controller(moduleName + '.TypeWorkspaceComponent', downgradeComponent({ component: TypeWorkspaceComponent })) + .controller(moduleName + '.WorkspaceMenuComponent', downgradeComponent({ component: WorkspaceMenuComponent })) + .controller(moduleName + '.TypeWorkspaceGeneralComponent', downgradeComponent({ component: TypeWorkspaceGeneralComponent })); diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts index 7153f0a841..801b663d69 100644 --- a/catalog-ui/src/app/ng2/app.module.ts +++ b/catalog-ui/src/app/ng2/app.module.ts @@ -108,6 +108,7 @@ import {ElementService} from "./services/element.service"; import {ModelService} from "./services/model.service"; import {ToscaArtifactService} from "./services/tosca-artifact.service"; import {InterfaceDefinitionModule} from "./pages/interface-definition/interface-definition.module"; +import {TypeWorkspaceModule} from "./pages/type-workspace/type-workspace.module"; declare const __ENV__: string; @@ -172,6 +173,7 @@ export function configServiceFactory(config: ConfigService, authService: Authent ServiceDependenciesModule, ServiceDependenciesEditorModule, WorkspaceModule, + TypeWorkspaceModule, ModalsModule, CatalogModule, HomeModule, diff --git a/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts b/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts index 3bd2255488..2b7be9cdeb 100644 --- a/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts +++ b/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts @@ -19,17 +19,13 @@ */ import * as _ from "lodash"; -import {Component, Inject, Input, Output, EventEmitter, OnInit, OnDestroy, OnChanges} from "@angular/core"; -import {IHostedApplication, IUserProperties} from "app/models"; -import {MenuItemGroup, MenuItem} from "app/utils"; +import {Component, EventEmitter, Inject, Input, OnChanges, OnInit, Output} from "@angular/core"; +import {IHostedApplication, IUserProperties, Plugin, PluginsConfiguration} from "app/models"; +import {MenuItem, MenuItemGroup} from "app/utils"; import {AuthenticationService} from "../../../services/authentication.service"; -import {SdcConfigToken, ISdcConfig} from "../../../config/sdc-config.config"; +import {ISdcConfig, SdcConfigToken} from "../../../config/sdc-config.config"; import {TranslateService} from "../../../shared/translator/translate.service"; -import {PluginsConfiguration, Plugin} from "app/models"; -import { Subscription } from "rxjs"; -// import { Store } from "@ngrx/store"; -// import { AppState } from "app/ng2/store/app.state"; -// import * as unsavedChangesReducer from 'app/ng2/store/reducers/unsaved-changes.reducer'; +import {Subscription} from "rxjs"; declare const window:any; @Component({ @@ -111,13 +107,13 @@ export class TopNavComponent implements OnInit, OnChanges { ngOnChanges(changes) { if (changes['menuModel']) { - console.log('menuModel was changed!'); + console.debug('menuModel was changed!'); this.generateMenu(); } } ngOnInit() { - console.log('Nav is init!', this.menuModel); + console.debug('Nav is init!', this.menuModel); this.user = this.authService.getLoggedinUser(); this.topNavPlugins = _.filter(PluginsConfiguration.plugins, (plugin: Plugin) => { return plugin.pluginDisplayOptions["tab"] !== undefined; @@ -190,7 +186,7 @@ export class TopNavComponent implements OnInit, OnChanges { if (item.callback) { (item.callback.apply(undefined, item.params)).then(onSuccess, onFailed); - } else { + } else if (this[item.action]) { this[item.action](item.state, item.params).then(onSuccess, onFailed); } } diff --git a/catalog-ui/src/app/ng2/config/sdc-menu.config.factory.ts b/catalog-ui/src/app/ng2/config/sdc-menu.config.factory.ts index 0e2b93dd7c..d2dfc57843 100644 --- a/catalog-ui/src/app/ng2/config/sdc-menu.config.factory.ts +++ b/catalog-ui/src/app/ng2/config/sdc-menu.config.factory.ts @@ -13,10 +13,9 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. -- */ - + import {IAppMenu} from "app/models"; -export function getSdcMenu() : IAppMenu{ - const sdcMenu:IAppMenu = require('./../../../../configurations/menu.js'); - return sdcMenu; +export function getSdcMenu(): IAppMenu { + return require('./../../../../configurations/menu.js'); } diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.html b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.html new file mode 100644 index 0000000000..877c58bd58 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.html @@ -0,0 +1,79 @@ +<!-- + ~ - + ~ ============LICENSE_START======================================================= + ~ Copyright (C) 2022 Nordix Foundation. + ~ ================================================================================ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + ~ SPDX-License-Identifier: Apache-2.0 + ~ ============LICENSE_END========================================================= + --> + +<div class="sdc-workspace-general-step"> + <form class="w-sdc-form" [formGroup]="formGroup"> + <div class="w-sdc-form-section-container"> + <div class="w-sdc-form-columns-wrapper"> + <div class="w-sdc-form-column"> + <div class="upper-general-fields"> + <div class="name-and-category-fields"> + <div class="i-sdc-form-item" [ngClass]="{'error': false}"> + <label class="i-sdc-form-label" [ngClass]="{'required': !isViewOnly}">{{'TYPE_LABEL' | translate}}:</label> + <span>{{dataType.name}}</span> + </div> + + <div class="i-sdc-form-item"> + <label class="i-sdc-form-label" [ngClass]="{'required': !isViewOnly}">{{'MODEL_LABEL' | translate}}:</label> + <span>{{dataType.model ? dataType.model : DEFAULT_MODEL_NAME}}</span> + </div> + + <div class="i-sdc-form-item"> + <label class="i-sdc-form-label" [ngClass]="{'required': !isViewOnly}">{{'DERIVED_FROM_LABEL' | translate}}:</label> + <span>{{dataType.derivedFromName}}</span> + </div> + </div> + </div> + + <div class="i-sdc-form-item description-field"> + <label class="i-sdc-form-label" [ngClass]="{'required': !isViewOnly}">{{'DESCRIPTION_LABEL' | translate}}:</label> + <textarea class="description" + formControlName="description" + [ngClass]="{'view-mode': isViewOnly}" + [required]="true" + [attr.test-id]="description" + [value]="dataType.description"></textarea> + </div> + </div> + + <div class="w-sdc-form-column"> + <div class="meta-data" data-ng-if="component.creationDate"> + <div> + <strong>{{'CREATED_LABEL' | translate}}:</strong> + </div> + <div class="meta-data-item-value">{{dataType.creationTime | date:'MM/dd/yyyy'}}</div> + <div> + <strong>{{'MODIFIED_LABEL' | translate}}:</strong> + </div> + <div class="meta-data-item-value"> + {{dataType.modificationTime | date:'MM/dd/yyyy'}} + </div> + <div> + <strong>{{'UNIQUE_ID_LABEL' | translate}}:</strong> + </div> + <div class="meta-data-item-value">{{dataType.uniqueId}}</div> + </div> + </div> + + </div> + </div> + </form> +</div> diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.less b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.less new file mode 100644 index 0000000000..3d9e984809 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.less @@ -0,0 +1,20 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.spec.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.spec.ts new file mode 100644 index 0000000000..fe7b070354 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.spec.ts @@ -0,0 +1,59 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {TypeWorkspaceGeneralComponent} from './type-workspace-general.component'; +import {ReactiveFormsModule} from "@angular/forms"; +import {TranslateModule} from "../../../shared/translator/translate.module"; +import {TranslateService} from "../../../shared/translator/translate.service"; + +describe('TypeWorkspaceGeneralComponent', () => { + let component: TypeWorkspaceGeneralComponent; + let fixture: ComponentFixture<TypeWorkspaceGeneralComponent>; + let translateServiceMock: Partial<TranslateService> = { + 'translate': jest.fn() + }; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TypeWorkspaceGeneralComponent ], + imports: [ + ReactiveFormsModule, + TranslateModule + ], + providers: [ + {provide: TranslateService, useValue: translateServiceMock} + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TypeWorkspaceGeneralComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.ts new file mode 100644 index 0000000000..8728c3020e --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component.ts @@ -0,0 +1,62 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {Component, Input, OnInit} from '@angular/core'; +import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {DataTypeModel} from "../../../../models/data-types"; +import { DEFAULT_MODEL_NAME } from "app/utils/constants"; + +@Component({ + selector: 'app-type-workspace-general', + templateUrl: './type-workspace-general.component.html', + styleUrls: ['./type-workspace-general.component.less'] +}) +export class TypeWorkspaceGeneralComponent implements OnInit { + @Input() isViewOnly = true; + @Input() dataType: DataTypeModel = new DataTypeModel(); + + DEFAULT_MODEL_NAME = DEFAULT_MODEL_NAME; + + type: FormControl = new FormControl(undefined, [Validators.required, Validators.minLength(1), Validators.maxLength(300)]); + derivedFrom: FormControl = new FormControl(undefined, [Validators.required, Validators.minLength(1)]); + description: FormControl = new FormControl(undefined, [Validators.required, Validators.minLength(1)]); + model: FormControl = new FormControl(undefined, [Validators.required]); + formGroup: FormGroup = new FormGroup({ + 'type': this.type, + 'description': this.description, + 'model': this.model, + 'derivedFrom': this.derivedFrom + }); + + ngOnInit(): void { + this.initForm(); + } + + private initForm(): void { + if (!this.dataType) { + return; + } + this.type.setValue(this.dataType.name); + this.description.setValue(this.dataType.description); + this.model.setValue(this.dataType.model); + this.derivedFrom.setValue(this.dataType.derivedFrom); + } +} diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.html b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.html new file mode 100644 index 0000000000..8d6ae02598 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.html @@ -0,0 +1,53 @@ +<!-- + ~ - + ~ ============LICENSE_START======================================================= + ~ Copyright (C) 2022 Nordix Foundation. + ~ ================================================================================ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + ~ SPDX-License-Identifier: Apache-2.0 + ~ ============LICENSE_END========================================================= + --> + +<div class="sdc-workspace-container"> + <loader [display]="isLoading"></loader> + <div class="w-sdc-main-container"> + <app-workspace-menu [menuHeader]="dataType.name" + (onMenuUpdate)="onMenuUpdate($event)" + (onClick)="onMenuClick($event)"> + </app-workspace-menu> + + <div class="w-sdc-main-right-container"> + <div class="sdc-workspace-top-bar"> + <div class="progress-container"> + </div> + <div class="sdc-workspace-top-bar-buttons"> + <span class="sprite-new x-btn" (click)="goToBreadcrumbHome()" sdc-smart-tooltip="Close" [title]="'CLOSE_LABEL' | translate"></span> + </div> + </div> + + <div class="w-sdc-main-container-body-content-wrapper"> + <div class="w-sdc-main-container-body-content-header"> + <div class="workspace-tab-title"> + {{currentMenu.text}} + </div> + </div> + <div class="w-sdc-main-container-body-content"> + <app-type-workspace-general *ngIf="currentMenu.state === 'general' && dataType" [dataType]="dataType"></app-type-workspace-general> + </div> + </div> + + </div> + </div> + <top-nav [hideSearch]="true" [menuModel]="breadcrumbsModel" [version]="sdcVersion" [unsavedChanges]="false"></top-nav> +</div> diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.less b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.less new file mode 100644 index 0000000000..4839b24f5e --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.less @@ -0,0 +1,149 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +@import '../../../../assets/styles/variables.less'; +@import '../../../../assets/styles/mixins.less'; +@import '../../../../assets/styles/mixins_old.less'; +@import '../../../../assets/styles/sprite.less'; + +.sdc-workspace-container { + .bg_p; + + .w-sdc-main-right-container { + + padding: 0; + background-color: @main_color_p; + + .sdc-workspace-top-bar { + height: @action_nav_height; + padding: 12px 10px 0 50px; + border-bottom: 1px solid @main_color_o; + display: flex; + justify-content: space-between; + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; + + .progress-container { + flex-grow: 4; + z-index: 1; + display: inline-block; + + .general-view-top-progress { + width: 30%; + margin: 0 auto; + min-width: 140px; + } + } + + .not-latest { + position: absolute; + left: 24px; + top: 20px; + .sprite-new; + .asdc-warning; + display: inline-block; + } + + .sdc-workspace-top-bar-buttons { + + > button, > span:not(.delimiter) { + margin-right: 10px; + vertical-align: middle; + .hand; + + &.sprite-new { + text-indent: 100%; + } + + &.disabled, &:hover.disabled { + pointer-events: none; + } + } + + .delimiter { + height: 32px; + width: 1px; + background-color: @main_color_o; + display: inline-block; + vertical-align: middle; + margin-right: 20px; + } + + display: inline-block; + + } + } + + .workspace-tab-title { + height: 110px; + padding-left: 100px; + line-height: 110px; + .f-type ._28; + } + + .w-sdc-main-container-body-content { + align-items: center; + padding: 0 100px 20px 100px; + + &.third-party { + text-align: left; + padding: 0; + position: absolute; + top: @action_nav_height + @tab_title; + left: 0; + right: 0; + bottom: 0; + } + } + + .w-sdc-main-container-body-content-wrapper { + overflow: auto; + height: calc(~'100% - @{action_nav_height}'); + + .w-sdc-main-container-body-content-header { + display: flex; + + .workspace-tab-title { + flex-grow: 1; + } + + .w-sdc-main-container-body-content-action-buttons { + margin: 72px 100px 0 0; + + > * { + display: inline-block; + vertical-align: middle; + } + + .revert-btn { + text-indent: 100%; + } + + .save-btn { + text-indent: 100%; + } + } + } + } + } +} + diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.spec.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.spec.ts new file mode 100644 index 0000000000..8450da829b --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.spec.ts @@ -0,0 +1,122 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {TypeWorkspaceComponent} from './type-workspace.component'; +import {ReactiveFormsModule} from "@angular/forms"; +import {TranslateModule} from "../../shared/translator/translate.module"; +import {UiElementsModule} from "../../components/ui/ui-elements.module"; +import {DataTypeService} from "../../services/data-type.service"; +import {TranslateService} from "../../shared/translator/translate.service"; +import {WorkspaceMenuComponent} from "./workspace-menu/workspace-menu.component"; +import {TypeWorkspaceGeneralComponent} from "./type-workspace-general/type-workspace-general.component"; +import {LayoutModule} from "../../components/layout/layout.module"; +import {CacheService} from "../../services/cache.service"; +import {IAppMenu, SdcMenuToken} from "../../config/sdc-menu.config"; +import {AuthenticationService} from "../../services/authentication.service"; +import {ISdcConfig, SdcConfigToken} from "../../config/sdc-config.config"; +import {States} from "../../../utils/constants"; +import {IUserProperties} from "../../../models/user"; +import {Observable} from "rxjs/Observable"; + +describe('TypeWorkspaceComponent', () => { + let component: TypeWorkspaceComponent; + let fixture: ComponentFixture<TypeWorkspaceComponent>; + let translateServiceMock: Partial<TranslateService> = { + 'languageChangedObservable': Observable.of(), + 'translate': jest.fn() + }; + let dataTypeServiceMock: Partial<DataTypeService>; + let cacheService: Partial<CacheService> = { + 'get': jest.fn(param => { + if (param === 'version') { + return 'version'; + } + if (param === 'user') { + return {}; + } + }) + }; + let stateMock: Partial<ng.ui.IStateService> = { + 'current': { + 'name': States.TYPE_WORKSPACE + } + }; + let stateParamsMock: Partial<ng.ui.IStateParamsService> = {}; + let injectorMock: Partial<ng.auto.IInjectorService> = { + 'get': jest.fn(param => { + if (param === '$state') { + return stateMock; + } + }) + }; + let sdcMenuMock: Partial<IAppMenu> = { + 'component_workspace_menu_option': { + "DataType": [ + {"text": "General", "action": "onMenuItemPressed", "state": "general"} + ] + } + }; + let sdcConfigMock: Partial<ISdcConfig>; + let user: Partial<IUserProperties> = { + 'role': 'DESIGNER' + } + let authenticationService: Partial<AuthenticationService> = { + 'getLoggedinUser': jest.fn(() => { + return user; + }) + }; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TypeWorkspaceComponent, WorkspaceMenuComponent, TypeWorkspaceGeneralComponent ], + imports: [ + ReactiveFormsModule, + TranslateModule, + UiElementsModule, + LayoutModule + ], + providers: [ + {provide: DataTypeService, useValue: dataTypeServiceMock}, + {provide: TranslateService, useValue: translateServiceMock}, + {provide: CacheService, useValue: cacheService}, + {provide: '$state', useValue: stateMock}, + {provide: '$stateParams', useValue: stateParamsMock}, + {provide: '$injector', useValue: injectorMock}, + {provide: SdcMenuToken, useValue: sdcMenuMock}, + {provide: SdcConfigToken, useValue: sdcConfigMock}, + {provide: AuthenticationService, useValue: authenticationService}, + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TypeWorkspaceComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.ts new file mode 100644 index 0000000000..d0d5ae8c69 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.ts @@ -0,0 +1,91 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {Component, Inject, OnInit} from '@angular/core'; +import {MenuItem, MenuItemGroup} from "../../../utils/menu-handler"; +import {CacheService} from "../../services/cache.service"; +import {DataTypeModel} from "../../../models/data-types"; +import {DataTypeService} from "../../services/data-type.service"; + +@Component({ + selector: 'app-type-workspace', + templateUrl: './type-workspace.component.html', + styleUrls: ['./type-workspace.component.less'] +}) +export class TypeWorkspaceComponent implements OnInit { + + private typeMenuItemGroup: MenuItemGroup; + + isLoading: boolean; + disabled: boolean; + isViewOnly: boolean = true; + sdcVersion: string; + breadcrumbsModel: Array<MenuItemGroup> = []; + dataType: DataTypeModel = new DataTypeModel(); + currentMenu: MenuItem; + + constructor(private dataTypeService: DataTypeService, private cacheService: CacheService, + @Inject('$state') private $state: ng.ui.IStateService, + @Inject('$stateParams') private stateParams) { } + + ngOnInit(): void { + this.sdcVersion = this.cacheService.get('version'); + this.typeMenuItemGroup = this.createTypeBreadcrumb(); + this.loadDataType(); + } + + private loadDataType(): void { + if (this.stateParams.id) { + this.dataTypeService.findById(this.stateParams.id).subscribe(dataType => { + this.dataType = dataType; + this.updateTypeBreadcrumb(); + }, error => { + console.debug('Could not find data type %s', this.stateParams.id, error); + this.goToBreadcrumbHome(); + }); + } else { + this.dataType = new DataTypeModel(); + } + } + + private updateTypeBreadcrumb(): void { + this.typeMenuItemGroup.updateSelectedMenuItemText(`Data Type: ${this.dataType.name}`); + } + + private createTypeBreadcrumb(): MenuItemGroup { + const menuItem = new MenuItem(`Data Type: ${this.dataType ? this.dataType.name : ''}`, undefined, undefined, undefined, [], [], false); + return new MenuItemGroup(0, [menuItem]); + } + + goToBreadcrumbHome(): void { + const homeMenuItemGroup: MenuItemGroup = this.breadcrumbsModel[0]; + this.$state.go(homeMenuItemGroup.menuItems[homeMenuItemGroup.selectedIndex].state); + } + + onMenuUpdate(menuItemGroup: MenuItemGroup): void { + this.breadcrumbsModel.push(...[this.typeMenuItemGroup, menuItemGroup]); + } + + onMenuClick(menuItem: MenuItem): void { + this.currentMenu = menuItem; + } + +} diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.module.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.module.ts new file mode 100644 index 0000000000..d3f391db24 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.module.ts @@ -0,0 +1,58 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {TypeWorkspaceComponent} from "./type-workspace.component"; +import {WorkspaceMenuComponent} from "./workspace-menu/workspace-menu.component"; +import {CacheService} from "../../services/cache.service"; +import {UiElementsModule} from "../../components/ui/ui-elements.module"; +import {LayoutModule} from "../../components/layout/layout.module"; +import {TypeWorkspaceGeneralComponent} from './type-workspace-general/type-workspace-general.component'; +import {UpgradeModule} from "@angular/upgrade/static"; +import {ReactiveFormsModule} from "@angular/forms"; +import {TranslateModule} from "../../shared/translator/translate.module"; +import {DataTypeService} from "../../services/data-type.service"; + +@NgModule({ + imports: [ + CommonModule, + UiElementsModule, + LayoutModule, + UpgradeModule, + ReactiveFormsModule, + TranslateModule, + ], + declarations: [ + TypeWorkspaceComponent, + WorkspaceMenuComponent, + TypeWorkspaceGeneralComponent + ], + providers: [ + CacheService, + WorkspaceMenuComponent, + DataTypeService + ], + entryComponents: [TypeWorkspaceComponent], + exports: [TypeWorkspaceComponent] +}) +export class TypeWorkspaceModule { +} diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.html b/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.html new file mode 100644 index 0000000000..18c6949b46 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.html @@ -0,0 +1,34 @@ +<!-- + ~ - + ~ ============LICENSE_START======================================================= + ~ Copyright (C) 2022 Nordix Foundation. + ~ ================================================================================ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + ~ SPDX-License-Identifier: Apache-2.0 + ~ ============LICENSE_END========================================================= + --> + +<div class="w-sdc-left-sidebar"> + <div class="menu-header" tooltips [attr.tooltip-content]="menuHeader" [title]="menuHeader"> + {{menuHeader}} + </div> + <div class="i-sdc-designer-sidebar-section-content-item" + [ngClass]="{'selected': isSelected(menuItem)}" + *ngFor="let menuItem of leftBarTabs.menuItems"> + <div class="expand-collapse-menu-box-item-text" ng-class="{'disabled': menuItem.isDisabled }"> + <button [attr.data-tests-id]="menuItem.text + 'LeftSideMenu'" type="button" class="i-sdc-designer-sidebar-section-content-item-service-cat" + (click)="menuItem.callback()" [disabled]="menuItem.disabledCategory">{{menuItem.text}}</button> + </div> + </div> +</div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.less b/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.less new file mode 100644 index 0000000000..2df6e6ac8b --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.less @@ -0,0 +1,75 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +@import '../../../../../assets/styles/variables.less'; +@import '../../../../../assets/styles/mixins.less'; + +.w-sdc-left-sidebar { + padding: 0; + background-color: @tlv_color_t; + box-shadow: none; + z-index: 2; + border-right: 1px solid @main_color_o; + + .menu-header { + border-bottom: 1px solid @main_color_o; + height: 53px; + .f-type._16_m; + font-weight: 700; + line-height: 53px; + padding-left: 40px; + padding-right: 10px; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + white-space: nowrap; + } + + .i-sdc-designer-sidebar-section-content-item { + .f-type._13_m; + color: @main_color_m; + margin-left: 20px; + padding-left: 20px; + margin-top: 20px; + height: 17px; + .hand; + + &:hover { + color: @func_color_s; + font-weight: 600; + } + + &.selected { + border-left: 4px solid @main_color_a; + color: @main_color_a; + margin-left: 18px; + padding-left: 18px; + font-weight: 600; + + } + } + +} + +.hand { + cursor: pointer; +} diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.spec.ts b/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.spec.ts new file mode 100644 index 0000000000..a91258c00e --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.spec.ts @@ -0,0 +1,84 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {WorkspaceMenuComponent} from './workspace-menu.component'; +import {CacheService} from "../../../services/cache.service"; +import {States} from "../../../../utils/constants"; +import {IAppMenu} from "../../../../models/app-config"; +import {SdcMenuToken} from "../../../config/sdc-menu.config"; + +describe('WorkspaceMenuComponent', () => { + let component: WorkspaceMenuComponent; + let fixture: ComponentFixture<WorkspaceMenuComponent>; + let cacheService: Partial<CacheService> = { + 'get': jest.fn(param => { + if (param === 'version') { + return 'version'; + } + if (param === 'user') { + return {}; + } + }) + }; + let sdcMenuMock: Partial<IAppMenu> = { + 'component_workspace_menu_option': { + "DataType": [ + {"text": "General", "action": "onMenuItemPressed", "state": "general"} + ] + } + }; + let stateMock: Partial<ng.ui.IStateService> = { + 'current': { + 'name': States.TYPE_WORKSPACE + } + }; + let injectorMock: Partial<ng.auto.IInjectorService> = { + 'get': jest.fn(param => { + if (param === '$state') { + return stateMock; + } + }) + }; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ WorkspaceMenuComponent ], + providers: [ + {provide: CacheService, useValue: cacheService}, + {provide: '$injector', useValue: injectorMock}, + {provide: SdcMenuToken, useValue: sdcMenuMock} + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(WorkspaceMenuComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.ts b/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.ts new file mode 100644 index 0000000000..c5e49d4d7d --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/type-workspace/workspace-menu/workspace-menu.component.ts @@ -0,0 +1,110 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {Component, EventEmitter, Inject, Input, OnInit, Output} from '@angular/core'; +import {MenuItem, MenuItemGroup} from "../../../../utils/menu-handler"; +import {CacheService} from "../../../services/cache.service"; +import {IAppMenu} from "../../../../models/app-config"; +import {IUserProperties} from "../../../../models/user"; +import {SdcMenuToken} from "../../../config/sdc-menu.config"; + +@Component({ + selector: 'app-workspace-menu', + templateUrl: './workspace-menu.component.html', + styleUrls: ['./workspace-menu.component.less'] +}) +export class WorkspaceMenuComponent implements OnInit { + + @Input() menuHeader: string = ''; + @Output() onMenuUpdate: EventEmitter<MenuItemGroup> = new EventEmitter<MenuItemGroup>(); + @Output() onClick: EventEmitter<MenuItem> = new EventEmitter<MenuItem>(); + + private role: string; + private user: IUserProperties; + private $state: ng.ui.IStateService; + private $q: ng.IQService; + + leftBarTabs: MenuItemGroup = new MenuItemGroup(); + + constructor(private cacheService: CacheService, @Inject(SdcMenuToken) private sdcMenu: IAppMenu, @Inject('$injector') $injector) { + this.$state = $injector.get('$state'); + this.$q = $injector.get('$q'); + } + + ngOnInit(): void { + this.user = this.cacheService.get('user'); + this.role = this.user.role; + this.initMenuItems(); + } + + private initMenuItems(): void { + this.leftBarTabs = new MenuItemGroup(); + const menuItemsObjects: MenuItem[] = this.updateMenuItemByRole(this.sdcMenu.component_workspace_menu_option["DataType"], this.role); + + this.leftBarTabs.menuItems = menuItemsObjects.map((item: MenuItem) => { + const menuCallback = () => this[menuItem.action](menuItem); + const menuItem = new MenuItem(item.text, menuCallback, item.state, item.action, item.params, item.blockedForTypes, item.disabledCategory); + if (menuItem.params) { + menuItem.params.state = menuItem.state; + } else { + menuItem.params = {state: menuItem.state}; + } + return menuItem; + }); + this.updateSelectedMenuItem(); + this.onMenuUpdate.emit(this.leftBarTabs); + } + + isSelected(menuItem: MenuItem): boolean { + return this.leftBarTabs.selectedIndex === this.leftBarTabs.menuItems.indexOf(menuItem); + } + + private onMenuItemPressed(menuItem: MenuItem): angular.IPromise<boolean> { + this.leftBarTabs.selectedIndex = this.leftBarTabs.menuItems.indexOf(menuItem); + this.onClick.emit(this.leftBarTabs.menuItems[this.leftBarTabs.selectedIndex]); + const deferred: ng.IDeferred<boolean> = this.$q.defer(); + deferred.resolve(true); + return deferred.promise; + } + + private updateMenuItemByRole(menuItems: MenuItem[], role: string): MenuItem[] { + const filteredMenuItems: MenuItem[] = []; + menuItems.forEach((item: any) => { + if (!(item.disabledRoles && item.disabledRoles.indexOf(role) > -1)) { + filteredMenuItems.push(item); + } + }); + return filteredMenuItems; + } + + private updateSelectedMenuItem(): void { + const stateArray: Array<string> = this.$state.current.name.split('.', 2); + const stateWithoutInternalNavigate: string = stateArray[0] + '.' + stateArray[1]; + const selectedItem: MenuItem = this.leftBarTabs.menuItems.find((item: MenuItem) => { + let itemStateArray: Array<string> = item.state.split('.', 2); + let itemStateWithoutNavigation: string = itemStateArray[0] + '.' + itemStateArray[1]; + return (itemStateWithoutNavigation === stateWithoutInternalNavigate); + }); + this.leftBarTabs.selectedIndex = selectedItem ? this.leftBarTabs.menuItems.indexOf(selectedItem) : 0; + this.onClick.emit(this.leftBarTabs.menuItems[this.leftBarTabs.selectedIndex]); + } + +} diff --git a/catalog-ui/src/app/ng2/services/cookie.service.ts b/catalog-ui/src/app/ng2/services/cookie.service.ts index 61d13186fa..22c1dd310f 100644 --- a/catalog-ui/src/app/ng2/services/cookie.service.ts +++ b/catalog-ui/src/app/ng2/services/cookie.service.ts @@ -18,9 +18,9 @@ * ============LICENSE_END========================================================= */ -import {Injectable, Inject} from '@angular/core'; +import {Inject, Injectable} from '@angular/core'; import {ICookie} from "../../models/app-config"; -import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config"; +import {ISdcConfig, SdcConfigToken} from "../config/sdc-config.config"; @Injectable() export class Cookie2Service { @@ -36,7 +36,6 @@ export class Cookie2Service { if ((junctionName !== null) && (junctionName !== '')) { this.cookiePrefix = this.cookie.prefix + junctionName + '!'; } - console.log("junctionName:" + junctionName); } private getCookieByName = (cookieName:string):string => { diff --git a/catalog-ui/src/app/ng2/services/data-type.service.ts b/catalog-ui/src/app/ng2/services/data-type.service.ts index 70555a5efd..bf500ec16e 100644 --- a/catalog-ui/src/app/ng2/services/data-type.service.ts +++ b/catalog-ui/src/app/ng2/services/data-type.service.ts @@ -19,11 +19,15 @@ */ import * as _ from "lodash"; -import { Injectable } from '@angular/core'; +import {Inject, Injectable} from '@angular/core'; import { DataTypeModel, DataTypesMap, PropertyFEModel, DerivedFEProperty} from "app/models"; import { DataTypesService } from "app/services/data-types-service"; import { PROPERTY_DATA } from "app/utils"; import {DerivedFEAttribute} from "../../models/attributes-outputs/derived-fe-attribute"; +import {ISdcConfig} from "../config/sdc-config.config.factory"; +import {SdcConfigToken} from "../config/sdc-config.config"; +import {HttpClient} from "@angular/common/http"; +import {Observable} from "rxjs/Observable"; /** This is a new service for NG2, to eventually replace app/services/data-types-service.ts * @@ -34,11 +38,16 @@ import {DerivedFEAttribute} from "../../models/attributes-outputs/derived-fe-att @Injectable() export class DataTypeService { public dataTypes: DataTypesMap; + private readonly baseUrl: string; + private readonly dataTypeUrl: string; - constructor(private dataTypeService: DataTypesService) { + constructor(private dataTypeService: DataTypesService, private httpClient: HttpClient, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) { this.dataTypes = dataTypeService.getAllDataTypes(); //This should eventually be replaced by an NG2 call to the backend instead of utilizing Angular1 downgraded component. + this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root; + this.dataTypeUrl = `${this.baseUrl}data-types` } + public getDataTypeByModelAndTypeName(modelName: string, typeName: string): DataTypeModel { this.dataTypes = this.dataTypeService.getAllDataTypesFromModel(modelName); let dataTypeFound = this.dataTypes[typeName]; @@ -64,6 +73,11 @@ export class DataTypeService { return this.dataTypeService.findAllDataTypesByModel(modelName); } + public findById(id: string): Observable<DataTypeModel> { + const url = `${this.dataTypeUrl}/${id}` + return this.httpClient.get<DataTypeModel>(url); + } + public getConstraintsByParentTypeAndUniqueID(rootPropertyType, propertyName){ // const property = this.dataTypes[rootPropertyType].properties.filter(property => // property.name == propertyName); diff --git a/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts b/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts index aab531d205..a3c04bc87b 100644 --- a/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts +++ b/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts @@ -21,14 +21,13 @@ /** * Created by rc2122 on 4/6/2017. */ -import { DataTypesService } from "../../services/data-types-service"; -import ICacheObject = angular.ICacheObject; -import { CookieService } from "../../services/cookie-service"; +import {DataTypesService} from "../../services/data-types-service"; +import {CookieService} from "../../services/cookie-service"; import {ComponentFactory} from "../../utils/component-factory" -import { EventListenerService } from "app/services/event-listener-service"; -import { ModalsHandler } from "app/utils"; -import IScope = angular.IScope; -import { SharingService } from "../services/sharing.service"; +import {EventListenerService} from "app/services/event-listener-service"; +import {ModalsHandler} from "app/utils"; +import {SharingService} from "../services/sharing.service"; +import ICacheObject = angular.ICacheObject; /** Services we need to upgrade from angular1 to angular2 - in the future we need to rewrite them all to angular2 **/ @@ -115,12 +114,6 @@ export const StateParamsServiceFactory = { useFactory: stateParamsServiceFactory, deps: ['$injector'] }; -// -// export const EventListenerServiceProvider = { -// provide: EventListenerService, -// useFactory: eventListenerServiceServiceFactory, -// deps: ['$injector'] -// }; export const NotificationServiceProvider = { provide: 'Notification', diff --git a/catalog-ui/src/app/services/data-types-service.ts b/catalog-ui/src/app/services/data-types-service.ts index ad8dc59b8c..ca30259260 100644 --- a/catalog-ui/src/app/services/data-types-service.ts +++ b/catalog-ui/src/app/services/data-types-service.ts @@ -19,15 +19,16 @@ */ 'use strict'; -import { DataTypePropertyModel } from "../models/data-type-properties"; +import {DataTypePropertyModel} from "../models/data-type-properties"; import { ComponentInstance, - InputModel, + DataTypeModel, DataTypesMap, - PropertyModel, - InputPropertyBase, IAppConfigurtaion, - SchemaProperty, DataTypeModel + InputModel, + InputPropertyBase, + PropertyModel, + SchemaProperty } from "../models"; import {PROPERTY_DATA} from "../utils/constants"; diff --git a/catalog-ui/src/app/utils/constants.ts b/catalog-ui/src/app/utils/constants.ts index 4e268f7087..d6710ed767 100644 --- a/catalog-ui/src/app/utils/constants.ts +++ b/catalog-ui/src/app/utils/constants.ts @@ -281,6 +281,7 @@ export class GraphUIObjects { export class States { + public static WORKSPACE = 'workspace'; public static WORKSPACE_GENERAL = 'workspace.general'; public static WORKSPACE_ACTIVITY_LOG = 'workspace.activity_log'; public static WORKSPACE_DEPLOYMENT_ARTIFACTS = 'workspace.deployment_artifacts'; @@ -303,6 +304,7 @@ export class States { public static WORKSPACE_REQUIREMENTS_AND_CAPABILITIES_EDITABLE = 'workspace.reqAndCapEditable'; public static WORKSPACE_PLUGINS = 'workspace.plugins'; public static WORKSPACE_NG2 = 'workspace.ng2'; + public static TYPE_WORKSPACE = 'type-workspace'; } export class EVENTS { diff --git a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts index 7bed071d7e..0778b2d803 100644 --- a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts @@ -23,38 +23,34 @@ */ 'use strict'; import * as _ from 'lodash'; +import {Component, IAppMenu, IUserProperties, Plugin, PluginsConfiguration, Resource, Service} from 'app/models'; import { - IUserProperties, - IAppMenu, - Resource, - Service, - Component, - Plugin, - PluginsConfiguration, - PluginDisplayOptions -} from 'app/models'; -import { - MenuItem, ModalsHandler, States, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ResourceType, PREVIOUS_CSAR_COMPONENT, - WorkspaceMode, ComponentFactory, ChangeLifecycleStateHandler, Role, ComponentState, MenuItemGroup, MenuHandler + CHANGE_COMPONENT_CSAR_VERSION_FLAG, + ChangeLifecycleStateHandler, + ComponentFactory, + ComponentState, + EVENTS, + MenuHandler, + MenuItem, + MenuItemGroup, + PREVIOUS_CSAR_COMPONENT, + ResourceType, + Role, + States, + WorkspaceMode } from 'app/utils'; -import { - EventListenerService, - LeftPaletteLoaderService, - ProgressService -} from 'app/services'; -import { - CacheService -} from 'app/services-ng2'; -import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular'; -import { AutomatedUpgradeService } from '../../ng2/pages/automated-upgrade/automated-upgrade.service'; -import { CatalogService } from '../../ng2/services/catalog.service'; -import { ComponentServiceNg2 } from '../../ng2/services/component-services/component.service'; -import { EventBusService } from '../../ng2/services/event-bus.service'; -import { HomeService } from '../../ng2/services/home.service'; -import { PluginsService } from '../../ng2/services/plugins.service'; -import { IDependenciesServerResponse } from '../../ng2/services/responses/dependencies-server-response'; -import { WorkspaceNg1BridgeService } from '../../ng2/pages/workspace/workspace-ng1-bridge-service'; -import { WorkspaceService } from '../../ng2/pages/workspace/workspace.service'; +import {EventListenerService, LeftPaletteLoaderService, ProgressService} from 'app/services'; +import {CacheService} from 'app/services-ng2'; +import {SdcUiCommon, SdcUiComponents, SdcUiServices} from 'onap-ui-angular'; +import {AutomatedUpgradeService} from '../../ng2/pages/automated-upgrade/automated-upgrade.service'; +import {CatalogService} from '../../ng2/services/catalog.service'; +import {ComponentServiceNg2} from '../../ng2/services/component-services/component.service'; +import {EventBusService} from '../../ng2/services/event-bus.service'; +import {HomeService} from '../../ng2/services/home.service'; +import {PluginsService} from '../../ng2/services/plugins.service'; +import {IDependenciesServerResponse} from '../../ng2/services/responses/dependencies-server-response'; +import {WorkspaceNg1BridgeService} from '../../ng2/pages/workspace/workspace-ng1-bridge-service'; +import {WorkspaceService} from '../../ng2/pages/workspace/workspace.service'; export interface IWorkspaceViewModelScope extends ng.IScope { @@ -87,7 +83,6 @@ export interface IWorkspaceViewModelScope extends ng.IScope { progressService: ProgressService; progressMessage: string; ComponentServiceNg2: ComponentServiceNg2; - // leftPanelComponents:Array<Models.Components.Component>; //this is in order to load the left panel once, and not wait long time when moving to composition unsavedChanges: boolean; unsavedChangesCallback: Function; unsavedFile: boolean; @@ -184,7 +179,6 @@ export class WorkspaceViewModel { private workspaceService: WorkspaceService) { this.initScope(); - // this.initAfterScope(); this.$scope.updateSelectedMenuItem(this.$state.current.name); } @@ -773,7 +767,7 @@ export class WorkspaceViewModel { }; this.$scope.reload = (component: Component): void => { - const isGeneralTab = this.$state.current.name === 'workspace.general'; + const isGeneralTab = this.$state.current.name === States.WORKSPACE_GENERAL; // nullify the componentCsar in case we are in general tab so we know we didnt came from updateVsp Modal if (isGeneralTab) { this.$state.go(this.$state.current.name, {id: component.uniqueId, componentCsar: null}, {reload: true}); diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json index 71f2b05efd..3f5a10726c 100644 --- a/catalog-ui/src/assets/languages/en_US.json +++ b/catalog-ui/src/assets/languages/en_US.json @@ -567,6 +567,16 @@ "VALUE_EXPRESSION_LABEL": "Value Expression", "OPERATOR_LABEL": "Operator", "CAPABILITY_LABEL": "Capability", + "DATA_TYPE_LABEL": "Data Type", + "MODEL_LABEL": "Model", + "DESCRIPTION_LABEL": "Description", + "DERIVED_FROM_LABEL": "Derived From", + "TYPE_LABEL": "Type", + "CREATED_LABEL": "Created", + "CREATE_LABEL": "Create", + "CLOSE_LABEL": "Close", + "MODIFIED_LABEL": "Modified", + "UNIQUE_ID_LABEL": "Unique Id", "=========== SERVICE IMPORT ===========": "", "IMPORT_FAILURE_MESSAGE_TEXT": "Import Failure - error reading CSAR" } diff --git a/integration-tests/environments/plugins-configuration.yaml b/integration-tests/environments/plugins-configuration.yaml index e69de29bb2..3dfa143b4f 100644 --- a/integration-tests/environments/plugins-configuration.yaml +++ b/integration-tests/environments/plugins-configuration.yaml @@ -0,0 +1,32 @@ +pluginsList: + - pluginId: POLICY + pluginDiscoveryUrl: http://192.168.86.21:9090/policy/ + pluginSourceUrl: http://192.168.86.21:9090/policy/ + pluginStateUrl: "policy" + pluginDisplayOptions: + tab: + displayName: "POLICY" + displayRoles: ["DESIGNER"] + - pluginId: POLICY_LIST + pluginDiscoveryUrl: http://192.168.86.21:8095/artifact + pluginSourceUrl: http://192.168.86.21:8095/artifact + pluginStateUrl: "policy_list" + pluginDisplayOptions: + context: + displayName: "Apex policy" + displayContext: ["SERVICE"] + displayRoles: ["DESIGNER"] + - pluginId: WORKFLOW + pluginDiscoveryUrl: http://192.168.86.21:8184/workflows + pluginSourceUrl: http://192.168.86.21:8184/workflows + pluginStateUrl: "workflowDesigner" + pluginDisplayOptions: + tab: + displayName: "WORKFLOW" + displayRoles: ["DESIGNER", "TESTER"] + context: + displayName: "Workflow Designer" + displayContext: ["VF"] + displayRoles: ["DESIGNER", "TESTER"] + +connectionTimeout: 1000 |