From 5fe73a4533b96f1407c1a9f915c534627b99578a Mon Sep 17 00:00:00 2001 From: vlo-rte Date: Wed, 17 Feb 2021 16:06:30 +0100 Subject: [PATCH 01/45] [OC-1440] New logging screen filters --- .../modules/archives/archives.component.html | 60 +--- .../modules/archives/archives.component.ts | 286 ++--------------- .../app/modules/archives/archives.module.ts | 4 +- .../logging-filters.component.html | 14 +- .../logging-filters.component.ts | 97 +----- .../logging-table.component.html | 2 + .../logging-table/logging-table.component.ts | 39 ++- .../modules/logging/logging.component.html | 5 +- .../src/app/modules/logging/logging.module.ts | 4 +- .../archives-logging-filters.component.html | 65 ++++ .../archives-logging-filters.component.ts | 290 ++++++++++++++++++ .../archives-logging-filters.module.ts | 31 ++ ui/main/src/assets/i18n/en.json | 24 +- ui/main/src/assets/i18n/fr.json | 24 +- 14 files changed, 502 insertions(+), 443 deletions(-) create mode 100644 ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.component.html create mode 100644 ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.component.ts create mode 100644 ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.module.ts diff --git a/ui/main/src/app/modules/archives/archives.component.html b/ui/main/src/app/modules/archives/archives.component.html index fa72fe36f9..2032fc9ebd 100644 --- a/ui/main/src/app/modules/archives/archives.component.html +++ b/ui/main/src/app/modules/archives/archives.component.html @@ -12,61 +12,7 @@
- - -
-
- - - - -
-
- - -
-
- - -
-
- - - - -
-
- - -
-
- - -
-
- - -
-
- - -
-
+
@@ -113,7 +59,7 @@ archive.result.businessPeriod archive.result.title archive.result.summary - archive.result.service + archive.result.service @@ -127,7 +73,7 @@ {{ card.process + '.' + card.processVersion + '.' + card.summary.key}} - {{ findServiceLabelForProcess(card.process) }} + {{ filtersTemplate.findServiceLabelForProcess(card.process) }}
diff --git a/ui/main/src/app/modules/archives/archives.component.ts b/ui/main/src/app/modules/archives/archives.component.ts index 580f3da503..7b6a4835ac 100644 --- a/ui/main/src/app/modules/archives/archives.component.ts +++ b/ui/main/src/app/modules/archives/archives.component.ts @@ -9,7 +9,7 @@ import {Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core'; -import {Observable, Subject} from 'rxjs'; +import {Subject} from 'rxjs'; import {AppState} from '@ofStore/index'; import {ProcessesService} from '@ofServices/processes.service'; import {Store} from '@ngrx/store'; @@ -17,35 +17,15 @@ import {takeUntil} from 'rxjs/operators'; import {FormControl, FormGroup} from '@angular/forms'; import {ConfigService} from '@ofServices/config.service'; import {TimeService} from '@ofServices/time.service'; -import {NgbDateStruct, NgbModal, NgbModalOptions, NgbModalRef, NgbTimeStruct} from '@ng-bootstrap/ng-bootstrap'; -import {DateTimeNgb} from '@ofModel/datetime-ngb.model'; +import {NgbModal, NgbModalOptions, NgbModalRef} from '@ng-bootstrap/ng-bootstrap'; import {CardService} from '@ofServices/card.service'; import {LightCard} from '@ofModel/light-card.model'; import {Page} from '@ofModel/page.model'; import {ExportService} from '@ofServices/export.service'; import {TranslateService} from '@ngx-translate/core'; import {Card} from '@ofModel/card.model'; -import {buildSettingsOrConfigSelector} from '@ofStore/selectors/settings.x.config.selectors'; +import {ArchivesLoggingFiltersComponent} from "../share/archives-logging-filters/archives-logging-filters.component"; -export enum FilterDateTypes { - PUBLISH_DATE_FROM_PARAM = 'publishDateFrom', - PUBLISH_DATE_TO_PARAM = 'publishDateTo', - ACTIVE_FROM_PARAM = 'activeFrom', - ACTIVE_TO_PARAM = 'activeTo' - -} - -export const checkElement = (enumeration: typeof FilterDateTypes, value: string): boolean => { - let result = false; - if (Object.values(enumeration).map(enumValue => enumValue.toString()).includes(value)) { - result = true; - } - return result; -}; - -export const transformToTimestamp = (date: NgbDateStruct, time: NgbTimeStruct): string => { - return new DateTimeNgb(date, time).formatDateTime(); -}; @Component({ selector: 'of-archives', @@ -60,34 +40,18 @@ export class ArchivesComponent implements OnDestroy, OnInit { size: number; archiveForm: FormGroup; - filters; results: LightCard[]; currentPage = 0; resultsNumber: number = 0; hasResult = false; firstQueryHasBeenDone = false; - // Filter values - serviceDropdownList = []; - serviceDropdownSettings = {}; - processDropdownList = []; - processDropdownListWhenSelectedService = []; - processesWithoutServiceDropdownList = []; - processDropdownSettings = {}; - stateDropdownListWhenSelectedProcess = []; - stateDropdownSettings = {}; - tagsDropdownList = []; - tagsDropdownSettings = {}; - // View card modalRef: NgbModalRef; @ViewChild('cardDetail') cardDetailTemplate: ElementRef; + @ViewChild('filters') filtersTemplate: ArchivesLoggingFiltersComponent; selectedCard : Card; - processesDropdownListPerServices = new Map(); - statesDropdownListPerProcesses = new Map(); - processesGroups: {id: string, processes: string[]}[]; - constructor(private store: Store, private processesService: ProcessesService, private configService: ConfigService, @@ -108,211 +72,11 @@ export class ArchivesComponent implements OnDestroy, OnInit { activeFrom: new FormControl(''), activeTo: new FormControl(''), }); - - } ngOnInit() { - this.tags = this.configService.getConfigValue('archive.filters.tags.list'); this.size = this.configService.getConfigValue('archive.filters.page.size', 10); this.results = new Array(); - this.processesGroups = this.processesService.getProcessGroups(); - this.processesService.getAllProcesses().forEach((process) => { - const id = process.id; - let itemName = process.name; - if (!itemName) { - itemName = id; - } - this.processDropdownList.push({ id: id, itemName: itemName, i18nPrefix: `${process.id}.${process.version}` }); - }); - this.processDropdownListWhenSelectedService = []; - this.stateDropdownListWhenSelectedProcess = []; - - if (!!this.tags) { - this.tags.forEach(tag => this.tagsDropdownList.push({ id: tag.value, itemName: tag.label })); - } - - this.loadAllProcessesPerServices(); - this.loadAllStatesPerProcesses(); - - this.getLocale().pipe(takeUntil(this.unsubscribe$)).subscribe(locale => { - this.translate.use(locale); - this.translate.get(['archive.selectServiceText','archive.selectProcessText','archive.selectStateText', - 'archive.selectTagText']) - .subscribe(translations => { - this.serviceDropdownSettings = { - text: translations['archive.selectServiceText'], - badgeShowLimit: 1, - enableSearchFilter: true - } - this.processDropdownSettings = { - text: translations['archive.selectProcessText'], - badgeShowLimit: 1, - enableSearchFilter: true - } - this.stateDropdownSettings = { - text: translations['archive.selectStateText'], - badgeShowLimit: 1, - enableSearchFilter: true - } - this.tagsDropdownSettings = { - text: translations['archive.selectTagText'], - badgeShowLimit: 1, - enableSearchFilter: true - }; - }) - }); - this.changeProcessesWhenSelectService(); - this.changeStatesWhenSelectProcess(); - } - - addProcessesDropdownList(processesDropdownList: any[]): void { - processesDropdownList.forEach( processDropdownList => - this.processDropdownListWhenSelectedService.push(processDropdownList) ); - } - - addStatesDropdownList(statesDropdownList: any[]): void { - statesDropdownList.forEach( stateDropdownList => - this.stateDropdownListWhenSelectedProcess.push(stateDropdownList) ); - } - - changeProcessesWhenSelectService(): void { - this.archiveForm.get('service').valueChanges.subscribe((selectedServices) => { - - if (!! selectedServices && selectedServices.length > 0) { - this.processDropdownListWhenSelectedService = []; - selectedServices.forEach(service => { - - if (service.id == '--') - this.addProcessesDropdownList(this.processesWithoutServiceDropdownList); - else - this.addProcessesDropdownList(this.processesDropdownListPerServices.get(service.id)); - }); - } - else - this.processDropdownListWhenSelectedService = []; - }); - } - - changeStatesWhenSelectProcess(): void { - this.archiveForm.get('process').valueChanges.subscribe((selectedProcesses) => { - - if (!! selectedProcesses && selectedProcesses.length > 0) { - this.stateDropdownListWhenSelectedProcess = []; - selectedProcesses.forEach(process => - this.addStatesDropdownList(this.statesDropdownListPerProcesses.get(process.id)) - ); - } - else - this.stateDropdownListWhenSelectedProcess = []; - }); - } - - findServiceForProcess(processId : string) : string { - for (let group of this.processesGroups) { - if (group.processes.find(process => process == processId)) - return group.id; - } - return ''; - } - - findServiceLabelForProcess(processId : string) : string { - const serviceId = this.findServiceForProcess(processId); - return (!! serviceId && serviceId != '') ? serviceId : "service.defaultLabel"; - } - - loadAllProcessesPerServices(): void { - this.processesService.getAllProcesses().forEach(process => { - - const service = this.findServiceForProcess(process.id); - if (service != '') { - let processes = (!! this.processesDropdownListPerServices.get(service) ? this.processesDropdownListPerServices.get(service) : []); - processes.push({id: process.id, itemName: process.name, i18nPrefix: `${process.id}.${process.version}`}); - this.processesDropdownListPerServices.set(service, processes); - } - else - this.processesWithoutServiceDropdownList.push({ id: process.id, itemName: process.name, i18nPrefix: `${process.id}.${process.version}` }); - }); - if (this.processesWithoutServiceDropdownList.length > 0) - this.serviceDropdownList.push({ id: '--', itemName: "service.defaultLabel" }); - - const services = Array.from(this.processesDropdownListPerServices.keys()); - services.forEach(service => this.serviceDropdownList.push({ id: service, itemName: service })); - } - - loadAllStatesPerProcesses(): void { - this.processesService.getAllProcesses().forEach(process => { - - let statesDropdownList = []; - for (let state in process.states) - statesDropdownList.push({id: process.id + '.' + state, itemName: process.states[state].name, i18nPrefix: `${process.id}.${process.version}`}); - this.statesDropdownListPerProcesses.set(process.id, statesDropdownList); - }); - } - - displayServiceFilter() { - return !!this.serviceDropdownList && this.serviceDropdownList.length > 1 ; - } - - protected getLocale(): Observable { - return this.store.select(buildSettingsOrConfigSelector('locale')); - } - - /** - * Transforms the filters list to Map - */ - filtersToMap = (filters: any) : void => { - this.filters = new Map(); - Object.keys(filters).forEach(key => { - const element = filters[key]; - // if the form element is date - if (element) { - if (checkElement(FilterDateTypes, key)) - this.dateFilterToMap(key, element); - else { - if (element.length) { - const ids = []; - if (key == 'state') - this.stateFilterToMap(element); - else if (key == 'service') - this.serviceFilterToMap(element); - else { - element.forEach(val => ids.push(val.id)); - this.filters.set(key, ids); - } - } - } - } - }); - } - - dateFilterToMap(key: string, element: any) { - const { date, time } = element; - if (date) { - const timeStamp = this.timeService.toNgBTimestamp(transformToTimestamp(date, time)); - if (timeStamp !== 'NaN') - this.filters.set(key, [timeStamp]); - } - } - - stateFilterToMap(element: any) { - const ids = []; - element.forEach(val => ids.push(val.id.substring(val.id.indexOf('.') + 1))); - this.filters.set('state', ids); - } - - serviceFilterToMap(element: any) { - const ids = []; - - element.forEach(service => { - if (service.id == '--') - this.processesWithoutServiceDropdownList.forEach(process => ids.push(process.id)) - else - this.processesDropdownListPerServices.get(service.id).forEach(process => ids.push(process.id)) - }); - - if (!this.filters.get('process')) - this.filters.set('process', ids); } resetForm() { @@ -322,13 +86,12 @@ export class ArchivesComponent implements OnDestroy, OnInit { this.resultsNumber = 0; } - sendQuery(page_number): void { const { value } = this.archiveForm; - this.filtersToMap(value); - this.filters.set('size', [this.size.toString()]); - this.filters.set('page', [page_number]); - this.cardService.fetchArchivedCards(this.filters) + this.filtersTemplate.filtersToMap(value); + this.filtersTemplate.filters.set('size', [this.size.toString()]); + this.filtersTemplate.filters.set('page', [page_number]); + this.cardService.fetchArchivedCards(this.filtersTemplate.filters) .pipe(takeUntil(this.unsubscribe$)) .subscribe((page: Page) => { this.resultsNumber = page.totalElements; @@ -339,7 +102,6 @@ export class ArchivesComponent implements OnDestroy, OnInit { page.content.forEach(card => this.loadTranslationForCardIfNeeded(card)); this.results = page.content; }); - } loadTranslationForCardIfNeeded(card: LightCard) { @@ -357,14 +119,13 @@ export class ArchivesComponent implements OnDestroy, OnInit { // EXPORT TO EXCEL - initExportArchiveData(): void { const exportArchiveData = []; - this.filters.set('size', [this.resultsNumber.toString()]); - this.filters.set('page', [0]); + this.filtersTemplate.filters.set('size', [this.resultsNumber.toString()]); + this.filtersTemplate.filters.set('page', [0]); - this.cardService.fetchArchivedCards(this.filters).pipe(takeUntil(this.unsubscribe$)) + this.cardService.fetchArchivedCards(this.filtersTemplate.filters).pipe(takeUntil(this.unsubscribe$)) .subscribe((page: Page) => { const lines = page.content; @@ -373,17 +134,28 @@ export class ArchivesComponent implements OnDestroy, OnInit { const businessDateColumnName = this.translateColomn('archive.result.businessPeriod'); const titleColumnName = this.translateColomn('archive.result.title'); const summaryColumnName = this.translateColomn('archive.result.summary'); + const serviceColumnName = this.translateColomn('archive.result.service'); lines.forEach((card: LightCard) => { if (typeof card !== undefined) { // TO DO translation for old process should be done , but loading local arrive to late , solution to find - exportArchiveData.push({ - [severityColumnName]: card.severity, - [publishDateColumnName]: this.timeService.formatDateTime(card.publishDate), - [businessDateColumnName]: this.displayTime(card.startDate) + '-' + this.displayTime(card.endDate), - [titleColumnName]: this.translateColomn(card.process + '.' + card.processVersion + '.' + card.title.key, card.title.parameters), - [summaryColumnName]: this.translateColomn(card.process + '.' + card.processVersion + '.' + card.summary.key, card.summary.parameters) - }); + if (this.filtersTemplate.displayServiceFilter()) + exportArchiveData.push({ + [severityColumnName]: card.severity, + [publishDateColumnName]: this.timeService.formatDateTime(card.publishDate), + [businessDateColumnName]: this.displayTime(card.startDate) + '-' + this.displayTime(card.endDate), + [titleColumnName]: this.translateColomn(card.process + '.' + card.processVersion + '.' + card.title.key, card.title.parameters), + [summaryColumnName]: this.translateColomn(card.process + '.' + card.processVersion + '.' + card.summary.key, card.summary.parameters), + [serviceColumnName]: this.translateColomn(this.filtersTemplate.findServiceLabelForProcess(card.process)) + }); + else + exportArchiveData.push({ + [severityColumnName]: card.severity, + [publishDateColumnName]: this.timeService.formatDateTime(card.publishDate), + [businessDateColumnName]: this.displayTime(card.startDate) + '-' + this.displayTime(card.endDate), + [titleColumnName]: this.translateColomn(card.process + '.' + card.processVersion + '.' + card.title.key, card.title.parameters), + [summaryColumnName]: this.translateColomn(card.process + '.' + card.processVersion + '.' + card.summary.key, card.summary.parameters) + }); } }); this.exportService.exportAsExcelFile(exportArchiveData, 'Archive'); diff --git a/ui/main/src/app/modules/archives/archives.module.ts b/ui/main/src/app/modules/archives/archives.module.ts index 52e0d197f4..17bf2b22ba 100644 --- a/ui/main/src/app/modules/archives/archives.module.ts +++ b/ui/main/src/app/modules/archives/archives.module.ts @@ -19,6 +19,7 @@ import {DatetimeFilterModule} from '../share/datetime-filter/datetime-filter.mod import {MultiFilterModule} from 'app/modules/share/multi-filter/multi-filter.module'; import {CardDetailModule} from 'app/modules/share/card-detail/card-detail.module'; import {ArchivesEntryPointComponent} from './archives-entry-point.component'; +import {ArchivesLoggingFiltersModule} from "../share/archives-logging-filters/archives-logging-filters.module"; @NgModule({ imports: [ @@ -30,7 +31,8 @@ import {ArchivesEntryPointComponent} from './archives-entry-point.component'; NgbModule, DatetimeFilterModule, MultiFilterModule, - CardDetailModule + CardDetailModule, + ArchivesLoggingFiltersModule ], declarations: [ diff --git a/ui/main/src/app/modules/logging/components/logging-filters/logging-filters.component.html b/ui/main/src/app/modules/logging/components/logging-filters/logging-filters.component.html index 491420d186..a021a0c95b 100644 --- a/ui/main/src/app/modules/logging/components/logging-filters/logging-filters.component.html +++ b/ui/main/src/app/modules/logging/components/logging-filters/logging-filters.component.html @@ -5,19 +5,13 @@ +
-
- -
+ + +
diff --git a/ui/main/src/app/modules/logging/components/logging-filters/logging-filters.component.ts b/ui/main/src/app/modules/logging/components/logging-filters/logging-filters.component.ts index 9e40418ee9..9404e69c90 100644 --- a/ui/main/src/app/modules/logging/components/logging-filters/logging-filters.component.ts +++ b/ui/main/src/app/modules/logging/components/logging-filters/logging-filters.component.ts @@ -7,7 +7,7 @@ * This file is part of the OperatorFabric project. */ -import {Component, Input, OnDestroy, OnInit} from '@angular/core'; +import {Component, Input, OnDestroy, OnInit, ViewChild} from '@angular/core'; import {AppState} from '@ofStore/index'; import {Store} from '@ngrx/store'; import {FormControl, FormGroup} from '@angular/forms'; @@ -15,35 +15,10 @@ import {FormControl, FormGroup} from '@angular/forms'; import {SendLoggingQuery} from '@ofActions/logging.actions'; import {ConfigService} from '@ofServices/config.service'; import {TimeService} from '@ofServices/time.service'; -import {NgbDateStruct, NgbTimeStruct} from '@ng-bootstrap/ng-bootstrap'; -import {DateTimeNgb} from '@ofModel/datetime-ngb.model'; -import {TranslateService} from '@ngx-translate/core'; -import {buildSettingsOrConfigSelector} from '@ofStore/selectors/settings.x.config.selectors'; -import {Observable, Subject} from 'rxjs'; -import {takeUntil} from 'rxjs/operators'; +import {Subject} from 'rxjs'; +import {ArchivesLoggingFiltersComponent} from "../../../share/archives-logging-filters/archives-logging-filters.component"; -export enum FilterDateTypes { - PUBLISH_DATE_FROM_PARAM = 'publishDateFrom', - PUBLISH_DATE_TO_PARAM = 'publishDateTo', - ACTIVE_FROM_PARAM = 'activeFrom', - ACTIVE_TO_PARAM = 'activeTo' - -} - - -export const checkElement = (enumeration: typeof FilterDateTypes, value: string): boolean => { - let result = false; - if (Object.values(enumeration).map(enumValue => enumValue.toString()).includes(value)) { - result = true; - } - return result; -}; - -export const transformToTimestamp = (date: NgbDateStruct, time: NgbTimeStruct): string => { - return new DateTimeNgb(date, time).formatDateTime(); -}; - @Component({ selector: 'of-logging-filters', templateUrl: './logging-filters.component.html', @@ -57,15 +32,16 @@ export class LoggingFiltersComponent implements OnInit, OnDestroy { size = 10; loggingForm: FormGroup; - dropdownList = []; - dropdownSettings = {}; + @ViewChild('filters') filtersTemplate: ArchivesLoggingFiltersComponent; public submittedOnce = false; @Input() public processData: []; - constructor(private store: Store, private timeService: TimeService, private configService: ConfigService, private translate: TranslateService) { + constructor(private store: Store, + private timeService: TimeService, + private configService: ConfigService) { } @@ -73,72 +49,27 @@ export class LoggingFiltersComponent implements OnInit, OnDestroy { this.size = this.configService.getConfigValue('archive.filters.page.size', 10); this.loggingForm = new FormGroup( { + tags: new FormControl([]), + state: new FormControl([]), process: new FormControl([]), + service: new FormControl([]), publishDateFrom: new FormControl(''), publishDateTo: new FormControl(''), activeFrom: new FormControl(''), activeTo: new FormControl('') } ); - this.dropdownList = this.processData; - - this.getLocale().pipe(takeUntil(this.unsubscribe$)).subscribe(locale => { - this.translate.use(locale); - this.translate.get(['logging.filters.selectProcessText']) - .subscribe(translations => { - this.dropdownSettings = { - text: translations['logging.filters.selectProcessText'], - enableSearchFilter: true, - badgeShowLimit: 4, - classes: 'custom-class-example' - } - }) - }); - } - - protected getLocale(): Observable { - return this.store.select(buildSettingsOrConfigSelector('locale')); } sendQuery() { const {value} = this.loggingForm; - const params = this.filtersToMap(value); - params.set('size', [this.size.toString()]); - params.set('page', ['0']); - this.store.dispatch(new SendLoggingQuery({params})); + this.filtersTemplate.filtersToMap(value); + this.filtersTemplate.filters.set('size', [this.size.toString()]); + this.filtersTemplate.filters.set('page', ['0']); + this.store.dispatch(new SendLoggingQuery({params: this.filtersTemplate.filters})); this.submittedOnce = true; } - /** - * Transforms the filters list to Map - */ - filtersToMap = (filters: any): Map => { - const params = new Map(); - Object.keys(filters).forEach(key => { - const element = filters[key]; - // if the form element is date - if (element) { - if (checkElement(FilterDateTypes, key)) { - const {date, time} = element; - if (date) { - const timeStamp = this.timeService.toNgBTimestamp(transformToTimestamp(date, time)); - if (timeStamp !== 'NaN') { - params.set(key, [timeStamp]); - } - } - } else { - if (element.length) { - const idProcessArray = []; - element.forEach(val => idProcessArray.push(val.id)); - params.set(key, idProcessArray); - } - } - } - }); - return params; - } - - resetForm() { this.loggingForm.reset(); diff --git a/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.html b/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.html index 2168442f6c..75a56ae651 100644 --- a/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.html +++ b/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.html @@ -17,6 +17,7 @@ logging.summary logging.description logging.sender + logging.service @@ -31,6 +32,7 @@ {{element.sender}} + {{ parentComponent.filters.filtersTemplate.findServiceLabelForProcess(element.process) }}
diff --git a/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.ts b/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.ts index fb6c2316ad..603bfd6cfd 100644 --- a/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.ts +++ b/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * Copyright (c) 2020, RTEi (http://www.rte-international.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public @@ -23,6 +23,7 @@ import { TranslateService } from '@ngx-translate/core'; import { ExportService } from '@ofServices/export.service'; import { FlushLoggingResult, UpdateLoggingPage } from '@ofStore/actions/logging.actions'; import { ConfigService } from '@ofServices/config.service'; +import { LoggingComponent } from "../../logging.component"; @Component({ @@ -32,9 +33,9 @@ import { ConfigService } from '@ofServices/config.service'; }) export class LoggingTableComponent implements OnInit, OnDestroy { - @Input() results: LineOfLoggingResult[]; @Input() processStateDescription: Map; + @Input() displayServiceColumn: boolean; displayedResult: string; exportLoggingData: Array ; page = 0; @@ -44,8 +45,13 @@ export class LoggingTableComponent implements OnInit, OnDestroy { unsubscribe$: Subject = new Subject(); - constructor(public timeService: TimeService, private cardService: CardService, - private store: Store, private translate: TranslateService, private exportService: ExportService, private configService: ConfigService) { + constructor(public timeService: TimeService, + private cardService: CardService, + private store: Store, + private translate: TranslateService, + private exportService: ExportService, + private configService: ConfigService, + private parentComponent: LoggingComponent) { } ngOnInit() { @@ -92,16 +98,27 @@ export class LoggingTableComponent implements OnInit, OnDestroy { const summaryColumnName = this.translateColomn('logging.summary'); const descriptionColumnName = this.translateColomn('logging.description'); const senderColumnName = this.translateColomn('logging.sender'); + const serviceColumnName = this.translateColomn('logging.service'); lines.forEach( (line: LineOfLoggingResult) => { if (typeof line !== undefined) { - this.exportLoggingData.push({ - [timeOfActionColumnName]: this.timeService.formatDateTime(line.businessDate), - [titleColumnName]: this.translateColomn(line.i18nKeyForTitle.key, line.i18nKeyForTitle.parameters), - [summaryColumnName]: this.translateColomn(line.i18nKeyForSummary.key, line.i18nKeyForSummary.parameters), - [descriptionColumnName]: this.translateColomn(this.processStateDescription.get(line.process + '.' + line.state)), - [senderColumnName]: line.sender - }); + if (this.displayServiceColumn) + this.exportLoggingData.push({ + [timeOfActionColumnName]: this.timeService.formatDateTime(line.businessDate), + [titleColumnName]: this.translateColomn(line.i18nKeyForTitle.key, line.i18nKeyForTitle.parameters), + [summaryColumnName]: this.translateColomn(line.i18nKeyForSummary.key, line.i18nKeyForSummary.parameters), + [descriptionColumnName]: this.translateColomn(this.processStateDescription.get(line.process + '.' + line.state)), + [senderColumnName]: line.sender, + [serviceColumnName]: this.translateColomn(this.parentComponent.filters.filtersTemplate.findServiceLabelForProcess(line.process)) + }); + else + this.exportLoggingData.push({ + [timeOfActionColumnName]: this.timeService.formatDateTime(line.businessDate), + [titleColumnName]: this.translateColomn(line.i18nKeyForTitle.key, line.i18nKeyForTitle.parameters), + [summaryColumnName]: this.translateColomn(line.i18nKeyForSummary.key, line.i18nKeyForSummary.parameters), + [descriptionColumnName]: this.translateColomn(this.processStateDescription.get(line.process + '.' + line.state)), + [senderColumnName]: line.sender + }); } }); this.exportService.exportAsExcelFile(this.exportLoggingData, 'Logging'); diff --git a/ui/main/src/app/modules/logging/logging.component.html b/ui/main/src/app/modules/logging/logging.component.html index 4a58a69e4b..03f320fd41 100644 --- a/ui/main/src/app/modules/logging/logging.component.html +++ b/ui/main/src/app/modules/logging/logging.component.html @@ -15,7 +15,10 @@
- + +
diff --git a/ui/main/src/app/modules/logging/logging.module.ts b/ui/main/src/app/modules/logging/logging.module.ts index da5d3ceff9..1b92adf1b6 100644 --- a/ui/main/src/app/modules/logging/logging.module.ts +++ b/ui/main/src/app/modules/logging/logging.module.ts @@ -18,6 +18,7 @@ import {LoggingComponent} from './logging.component'; import {LoggingFiltersComponent} from './components/logging-filters/logging-filters.component'; import {DatetimeFilterModule} from '../../modules/share/datetime-filter/datetime-filter.module'; import {MultiFilterModule} from '../share/multi-filter/multi-filter.module'; +import {ArchivesLoggingFiltersModule} from "../share/archives-logging-filters/archives-logging-filters.module"; @NgModule({ @@ -29,7 +30,8 @@ import {MultiFilterModule} from '../share/multi-filter/multi-filter.module'; TranslateModule, NgbModule, DatetimeFilterModule, - MultiFilterModule + MultiFilterModule, + ArchivesLoggingFiltersModule ], declarations: [ LoggingComponent, diff --git a/ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.component.html b/ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.component.html new file mode 100644 index 0000000000..beb5291787 --- /dev/null +++ b/ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.component.html @@ -0,0 +1,65 @@ + + + + + + + + +
+ + +
+
+ + + + +
+
+ + +
+
+ + +
+
+ + + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
\ No newline at end of file diff --git a/ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.component.ts b/ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.component.ts new file mode 100644 index 0000000000..d207034dec --- /dev/null +++ b/ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.component.ts @@ -0,0 +1,290 @@ +/* Copyright (c) 2021, RTE (http://www.rte-france.com) + * See AUTHORS.txt + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + * This file is part of the OperatorFabric project. + */ + +import {Component, Input, OnDestroy, OnInit} from '@angular/core'; +import {ConfigService} from "@ofServices/config.service"; +import {Card} from "@ofModel/card.model"; +import {LightCard} from "@ofModel/light-card.model"; +import {FormGroup} from "@angular/forms"; +import {ProcessesService} from "@ofServices/processes.service"; +import {takeUntil} from "rxjs/operators"; +import {Observable, Subject} from "rxjs"; +import {buildSettingsOrConfigSelector} from "@ofSelectors/settings.x.config.selectors"; +import {Store} from "@ngrx/store"; +import {AppState} from "@ofStore/index"; +import {TranslateService} from "@ngx-translate/core"; +import {TimeService} from "@ofServices/time.service"; +import {NgbDateStruct, NgbTimeStruct} from "@ng-bootstrap/ng-bootstrap"; +import {DateTimeNgb} from "@ofModel/datetime-ngb.model"; + +export enum FilterDateTypes { + PUBLISH_DATE_FROM_PARAM = 'publishDateFrom', + PUBLISH_DATE_TO_PARAM = 'publishDateTo', + ACTIVE_FROM_PARAM = 'activeFrom', + ACTIVE_TO_PARAM = 'activeTo' + +} + +export const checkElement = (enumeration: typeof FilterDateTypes, value: string): boolean => { + let result = false; + if (Object.values(enumeration).map(enumValue => enumValue.toString()).includes(value)) { + result = true; + } + return result; +}; + +export const transformToTimestamp = (date: NgbDateStruct, time: NgbTimeStruct): string => { + return new DateTimeNgb(date, time).formatDateTime(); +}; + +@Component({ + selector: 'of-archives-logging-filters', + templateUrl: './archives-logging-filters.component.html' +}) +export class ArchivesLoggingFiltersComponent implements OnInit, OnDestroy { + + @Input() public card: Card | LightCard; + @Input() parentForm: FormGroup; + + unsubscribe$: Subject = new Subject(); + + tags: any[]; + filters; + + // Filter values + serviceDropdownList = []; + serviceDropdownSettings = {}; + processDropdownList = []; + processDropdownListWhenSelectedService = []; + processesWithoutServiceDropdownList = []; + processDropdownSettings = {}; + stateDropdownListWhenSelectedProcess = []; + stateDropdownSettings = {}; + tagsDropdownList = []; + tagsDropdownSettings = {}; + + processesDropdownListPerServices = new Map(); + statesDropdownListPerProcesses = new Map(); + processesGroups: {id: string, processes: string[]}[]; + + constructor(private store: Store, + private translate: TranslateService, + private configService: ConfigService, + private timeService: TimeService, + private processesService: ProcessesService) { + } + + ngOnInit() { + this.tags = this.configService.getConfigValue('archive.filters.tags.list'); + this.processesGroups = this.processesService.getProcessGroups(); + + this.processesService.getAllProcesses().forEach((process) => { + const id = process.id; + let itemName = process.name; + if (!itemName) { + itemName = id; + } + this.processDropdownList.push({ id: id, itemName: itemName, i18nPrefix: `${process.id}.${process.version}` }); + }); + this.processDropdownListWhenSelectedService = []; + this.stateDropdownListWhenSelectedProcess = []; + + if (!!this.tags) { + this.tags.forEach(tag => this.tagsDropdownList.push({ id: tag.value, itemName: tag.label })); + } + + this.loadAllProcessesPerServices(); + this.loadAllStatesPerProcesses(); + + this.getLocale().pipe(takeUntil(this.unsubscribe$)).subscribe(locale => { + this.translate.use(locale); + this.translate.get(['filters.selectServiceText','filters.selectProcessText','filters.selectStateText', + 'filters.selectTagText']) + .subscribe(translations => { + this.serviceDropdownSettings = { + text: translations['filters.selectServiceText'], + badgeShowLimit: 1, + enableSearchFilter: true + } + this.processDropdownSettings = { + text: translations['filters.selectProcessText'], + badgeShowLimit: 1, + enableSearchFilter: true + } + this.stateDropdownSettings = { + text: translations['filters.selectStateText'], + badgeShowLimit: 1, + enableSearchFilter: true + } + this.tagsDropdownSettings = { + text: translations['filters.selectTagText'], + badgeShowLimit: 1, + enableSearchFilter: true + }; + }) + }); + + this.changeProcessesWhenSelectService(); + this.changeStatesWhenSelectProcess(); + } + + /** + * Transforms the filters list to Map + */ + filtersToMap = (filters: any) : void => { + this.filters = new Map(); + Object.keys(filters).forEach(key => { + const element = filters[key]; + // if the form element is date + if (element) { + if (checkElement(FilterDateTypes, key)) + this.dateFilterToMap(key, element); + else { + if (element.length) { + const ids = []; + if (key == 'state') + this.stateFilterToMap(element); + else if (key == 'service') + this.serviceFilterToMap(element); + else { + element.forEach(val => ids.push(val.id)); + this.filters.set(key, ids); + } + } + } + } + }); + } + + dateFilterToMap(key: string, element: any) { + const { date, time } = element; + if (date) { + const timeStamp = this.timeService.toNgBTimestamp(transformToTimestamp(date, time)); + if (timeStamp !== 'NaN') + this.filters.set(key, [timeStamp]); + } + } + + stateFilterToMap(element: any) { + const ids = []; + element.forEach(val => ids.push(val.id.substring(val.id.indexOf('.') + 1))); + this.filters.set('state', ids); + } + + serviceFilterToMap(element: any) { + const ids = []; + + element.forEach(service => { + if (service.id == '--') + this.processesWithoutServiceDropdownList.forEach(process => ids.push(process.id)) + else + this.processesDropdownListPerServices.get(service.id).forEach(process => ids.push(process.id)) + }); + + if (!this.filters.get('process')) + this.filters.set('process', ids); + } + + addProcessesDropdownList(processesDropdownList: any[]): void { + processesDropdownList.forEach( processDropdownList => + this.processDropdownListWhenSelectedService.push(processDropdownList) ); + } + + addStatesDropdownList(statesDropdownList: any[]): void { + statesDropdownList.forEach( stateDropdownList => + this.stateDropdownListWhenSelectedProcess.push(stateDropdownList) ); + } + + changeProcessesWhenSelectService(): void { + this.parentForm.get('service').valueChanges.subscribe((selectedServices) => { + + if (!! selectedServices && selectedServices.length > 0) { + this.processDropdownListWhenSelectedService = []; + selectedServices.forEach(service => { + + if (service.id == '--') + this.addProcessesDropdownList(this.processesWithoutServiceDropdownList); + else + this.addProcessesDropdownList(this.processesDropdownListPerServices.get(service.id)); + }); + } + else + this.processDropdownListWhenSelectedService = []; + }); + } + + changeStatesWhenSelectProcess(): void { + this.parentForm.get('process').valueChanges.subscribe((selectedProcesses) => { + + if (!! selectedProcesses && selectedProcesses.length > 0) { + this.stateDropdownListWhenSelectedProcess = []; + selectedProcesses.forEach(process => + this.addStatesDropdownList(this.statesDropdownListPerProcesses.get(process.id)) + ); + } + else + this.stateDropdownListWhenSelectedProcess = []; + }); + } + + findServiceForProcess(processId : string) : string { + for (let group of this.processesGroups) { + if (group.processes.find(process => process == processId)) + return group.id; + } + return ''; + } + + loadAllProcessesPerServices(): void { + this.processesService.getAllProcesses().forEach(process => { + + const service = this.findServiceForProcess(process.id); + if (service != '') { + let processes = (!! this.processesDropdownListPerServices.get(service) ? this.processesDropdownListPerServices.get(service) : []); + processes.push({id: process.id, itemName: process.name, i18nPrefix: `${process.id}.${process.version}`}); + this.processesDropdownListPerServices.set(service, processes); + } + else + this.processesWithoutServiceDropdownList.push({ id: process.id, itemName: process.name, i18nPrefix: `${process.id}.${process.version}` }); + }); + if (this.processesWithoutServiceDropdownList.length > 0) + this.serviceDropdownList.push({ id: '--', itemName: "service.defaultLabel" }); + + const services = Array.from(this.processesDropdownListPerServices.keys()); + services.forEach(service => this.serviceDropdownList.push({ id: service, itemName: service })); + } + + loadAllStatesPerProcesses(): void { + this.processesService.getAllProcesses().forEach(process => { + + let statesDropdownList = []; + for (let state in process.states) + statesDropdownList.push({id: process.id + '.' + state, itemName: process.states[state].name, i18nPrefix: `${process.id}.${process.version}`}); + this.statesDropdownListPerProcesses.set(process.id, statesDropdownList); + }); + } + + displayServiceFilter() { + return !!this.serviceDropdownList && this.serviceDropdownList.length > 1 ; + } + + protected getLocale(): Observable { + return this.store.select(buildSettingsOrConfigSelector('locale')); + } + + findServiceLabelForProcess(processId : string) : string { + const serviceId = this.findServiceForProcess(processId); + return (!! serviceId && serviceId != '') ? serviceId : "service.defaultLabel"; + } + + ngOnDestroy() { + this.unsubscribe$.next(); + this.unsubscribe$.complete(); + } +} diff --git a/ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.module.ts b/ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.module.ts new file mode 100644 index 0000000000..db0a06ec76 --- /dev/null +++ b/ui/main/src/app/modules/share/archives-logging-filters/archives-logging-filters.module.ts @@ -0,0 +1,31 @@ +/* Copyright (c) 2021, RTE (http://www.rte-france.com) + * See AUTHORS.txt + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + * This file is part of the OperatorFabric project. + */ + +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {TranslateModule} from '@ngx-translate/core'; +import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; +import {MultiFilterModule} from 'app/modules/share/multi-filter/multi-filter.module'; +import {ArchivesLoggingFiltersComponent} from "./archives-logging-filters.component"; + + +@NgModule({ + declarations: [ArchivesLoggingFiltersComponent], + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + TranslateModule, + NgbModule, + MultiFilterModule + ], + exports: [ArchivesLoggingFiltersComponent] +}) +export class ArchivesLoggingFiltersModule { } diff --git a/ui/main/src/assets/i18n/en.json b/ui/main/src/assets/i18n/en.json index 0016005b1b..5cb38a50f2 100755 --- a/ui/main/src/assets/i18n/en.json +++ b/ui/main/src/assets/i18n/en.json @@ -128,10 +128,6 @@ }, "archive": { "filters": { - "service": "SERVICE", - "process": "PROCESS", - "state": "STATE", - "tags": "TAGS", "publishDateFrom": "PUBLISH FROM", "publishDateTo": "PUBLISH TO", "activeFrom": "ACTIVE FROM", @@ -147,22 +143,18 @@ }, "noResult": "Your search did not match any results.", "exportToExcel" : "Export data", - "resultsNumber":"Results number", - "selectServiceText": "Select a Service", - "selectProcessText": "Select a Process", - "selectStateText": "Select a State", - "selectTagText": "Select a Tag" + "resultsNumber":"Results number" }, "logging": { "filters": { - "process": "PROCESS", - "selectProcessText": "Select a Process" + "process": "PROCESS" }, "timeOfAction": "TIME OF ACTION", "title": "TITLE", "summary": "SUMMARY", "description": "DESCRIPTION", "sender": "ACTOR", + "service": "SERVICE", "noResult": "Your search did not match any results.", "ExportTOExcel": "Export data", "resultsNumber":"Results number" @@ -347,5 +339,15 @@ "to": "to", "of": "of", "page": "Page" + }, + "filters": { + "service": "SERVICE", + "process": "PROCESS", + "state": "STATE", + "tags": "TAGS", + "selectServiceText": "Select a Service", + "selectProcessText": "Select a Process", + "selectStateText": "Select a State", + "selectTagText": "Select a Tag" } } diff --git a/ui/main/src/assets/i18n/fr.json b/ui/main/src/assets/i18n/fr.json index b14f355303..e02cd39089 100755 --- a/ui/main/src/assets/i18n/fr.json +++ b/ui/main/src/assets/i18n/fr.json @@ -128,10 +128,6 @@ }, "archive": { "filters": { - "service": "SERVICE", - "process": "PROCESSUS", - "state": "ETAT", - "tags": "ETIQUETTES", "publishDateFrom": "PUBLIE A PARTIR DE", "publishDateTo": "PUBLIE JUSQU'A", "activeFrom": "ACTIVE A PARTIR DE", @@ -147,22 +143,18 @@ }, "noResult": "Votre recherche ne correspond à aucun résultat.", "exportToExcel" : "Exporter les données", - "resultsNumber":"Nombre de résultats", - "selectServiceText": "Sélectionner un Service", - "selectProcessText": "Sélectionner un Processus", - "selectStateText": "Sélectionner un Etat", - "selectTagText": "Sélectionner une Etiquette" + "resultsNumber":"Nombre de résultats" }, "logging": { "filters": { - "process": "PROCESSUS", - "selectProcessText": "Sélectionner un Processus" + "process": "PROCESSUS" }, "timeOfAction": "MOMENT DE L'ACTION", "title": "TITRE", "summary": "RESUME", "description": "DESCRIPTION", "sender": "EMETTEUR", + "service": "SERVICE", "noResult": "Votre recherche ne correspond à aucun résultat.", "ExportTOExcel": "Exporter les données", "resultsNumber":"Nombre de résultats" @@ -347,5 +339,15 @@ "to": "à", "of": "de", "page": "Page" + }, + "filters": { + "service": "SERVICE", + "process": "PROCESSUS", + "state": "ETAT", + "tags": "ETIQUETTES", + "selectServiceText": "Sélectionner un Service", + "selectProcessText": "Sélectionner un Processus", + "selectStateText": "Sélectionner un Etat", + "selectTagText": "Sélectionner une Etiquette" } } From 6b9acc008ff6434fddf04c0dd48059c70f4ddc5f Mon Sep 17 00:00:00 2001 From: Alexandra Guironnet Date: Mon, 22 Feb 2021 14:31:20 +0100 Subject: [PATCH 02/45] [OC-1500] Sonar - empty constructors --- .../template/en/chart-line.handlebars | 4 +- ui/main/src/app/common/error/app-error.ts | 8 ++- .../confirmation-dialog.component.ts | 7 +-- .../components/table/admin-table.directive.ts | 12 +++-- .../modules/archives/archives.component.ts | 49 +++++++++---------- .../init-chart/init-chart.component.ts | 34 ++++--------- .../logging-table/logging-table.component.ts | 43 ++++++++-------- .../monitoring-table.component.ts | 33 ++++++------- .../menus/menu-link/menu-link.component.html | 10 ++-- .../menus/menu-link/menu-link.component.ts | 21 +++----- .../base-setting/base-setting.component.html | 13 ----- ...component.ts => base-setting.directive.ts} | 18 +++---- .../checkbox-setting.component.ts | 14 +++--- .../list-setting/list-setting.component.ts | 7 ++- .../multi-settings.component.ts | 7 ++- .../text-setting/text-setting.component.ts | 7 ++- .../app/modules/settings/settings.module.ts | 7 +-- .../src/app/services/export.service.spec.ts | 34 ------------- ui/main/src/app/services/export.service.ts | 13 ++--- ui/main/src/app/services/services.module.ts | 4 +- .../store/actions/authentication.actions.ts | 47 ++++++++---------- ui/main/src/app/store/actions/feed.actions.ts | 8 +-- .../app/store/actions/light-card.actions.ts | 19 +------ ui/main/src/app/store/actions/menu.actions.ts | 11 ++--- .../store/reducers/authentication.reducer.ts | 11 ++--- 25 files changed, 164 insertions(+), 277 deletions(-) delete mode 100644 ui/main/src/app/modules/settings/components/settings/base-setting/base-setting.component.html rename ui/main/src/app/modules/settings/components/settings/base-setting/{base-setting.component.ts => base-setting.directive.ts} (87%) delete mode 100644 ui/main/src/app/services/export.service.spec.ts diff --git a/src/test/utils/karate/businessconfig/resources/bundle_defaultProcess/template/en/chart-line.handlebars b/src/test/utils/karate/businessconfig/resources/bundle_defaultProcess/template/en/chart-line.handlebars index 70310360c8..34e6cc4804 100644 --- a/src/test/utils/karate/businessconfig/resources/bundle_defaultProcess/template/en/chart-line.handlebars +++ b/src/test/utils/karate/businessconfig/resources/bundle_defaultProcess/template/en/chart-line.handlebars @@ -1,6 +1,6 @@

-Daily electrical consumption forcast +Daily electrical consumption forecast

@@ -47,4 +47,4 @@ var myChart = new Chart(ctx, { } }); - \ No newline at end of file + diff --git a/ui/main/src/app/common/error/app-error.ts b/ui/main/src/app/common/error/app-error.ts index d2ed6fb2f7..3dd7422960 100644 --- a/ui/main/src/app/common/error/app-error.ts +++ b/ui/main/src/app/common/error/app-error.ts @@ -10,5 +10,11 @@ // TODO I'm not sure why this class is necessary. What does new AppError(null) mean?? export class AppError { - constructor(originalError? ) {} + + public originalError; + + constructor(originalError? ) { + this.originalError = originalError; + } + } diff --git a/ui/main/src/app/modules/admin/components/confirmation-dialog/confirmation-dialog.component.ts b/ui/main/src/app/modules/admin/components/confirmation-dialog/confirmation-dialog.component.ts index e50e36b944..e1a8a4d087 100644 --- a/ui/main/src/app/modules/admin/components/confirmation-dialog/confirmation-dialog.component.ts +++ b/ui/main/src/app/modules/admin/components/confirmation-dialog/confirmation-dialog.component.ts @@ -8,14 +8,14 @@ * This file is part of the OperatorFabric project. */ -import {Component, Input, OnInit} from '@angular/core'; +import {Component, Input} from '@angular/core'; import {NgbActiveModal} from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'of-confirmation-dialog', templateUrl: './confirmation-dialog.component.html' }) -export class ConfirmationDialogComponent implements OnInit { +export class ConfirmationDialogComponent { @Input() title: string; @Input() message: string; @@ -24,9 +24,6 @@ export class ConfirmationDialogComponent implements OnInit { constructor(private activeModal: NgbActiveModal) { } - ngOnInit() { - } - public decline() { this.activeModal.close(false); } diff --git a/ui/main/src/app/modules/admin/components/table/admin-table.directive.ts b/ui/main/src/app/modules/admin/components/table/admin-table.directive.ts index 4d25e5eac0..7079c32527 100644 --- a/ui/main/src/app/modules/admin/components/table/admin-table.directive.ts +++ b/ui/main/src/app/modules/admin/components/table/admin-table.directive.ts @@ -169,8 +169,10 @@ export abstract class AdminTableDirective implements OnInit, OnDestroy { () => { // If modal is closed this.refreshData(); // This refreshes the data when the modal is closed after a change }, - () => { }); // If the modal is dismissed (by clicking the "close" button, the top right cross icon - // or clicking outside the modal, there is no need to refresh the data + () => { + // If the modal is dismissed (by clicking the "close" button, the top right cross icon + // or clicking outside the modal, there is no need to refresh the data + }); } if (columnId === 'delete') { this.openDeleteConfirmationDialog(params.data); @@ -206,8 +208,10 @@ export abstract class AdminTableDirective implements OnInit, OnDestroy { this.refreshData(); // This refreshes the data when the modal is closed after a change // Data creation doesn't need to be propagated to the user table }, - () => { }); // If modal is dismissed (by clicking the "close" button, the top right cross icon - // or clicking outside the modal, there is no need to refresh the data + () => { + // If modal is dismissed (by clicking the "close" button, the top right cross icon + // or clicking outside the modal, there is no need to refresh the data + }); } refreshData() { diff --git a/ui/main/src/app/modules/archives/archives.component.ts b/ui/main/src/app/modules/archives/archives.component.ts index 7b6a4835ac..a9b68caeb6 100644 --- a/ui/main/src/app/modules/archives/archives.component.ts +++ b/ui/main/src/app/modules/archives/archives.component.ts @@ -24,7 +24,7 @@ import {Page} from '@ofModel/page.model'; import {ExportService} from '@ofServices/export.service'; import {TranslateService} from '@ngx-translate/core'; import {Card} from '@ofModel/card.model'; -import {ArchivesLoggingFiltersComponent} from "../share/archives-logging-filters/archives-logging-filters.component"; +import {ArchivesLoggingFiltersComponent} from '../share/archives-logging-filters/archives-logging-filters.component'; @Component({ @@ -42,7 +42,7 @@ export class ArchivesComponent implements OnDestroy, OnInit { results: LightCard[]; currentPage = 0; - resultsNumber: number = 0; + resultsNumber = 0; hasResult = false; firstQueryHasBeenDone = false; @@ -50,14 +50,13 @@ export class ArchivesComponent implements OnDestroy, OnInit { modalRef: NgbModalRef; @ViewChild('cardDetail') cardDetailTemplate: ElementRef; @ViewChild('filters') filtersTemplate: ArchivesLoggingFiltersComponent; - selectedCard : Card; + selectedCard: Card; constructor(private store: Store, private processesService: ProcessesService, private configService: ConfigService, private timeService: TimeService, private cardService: CardService, - private exportService: ExportService, private translate: TranslateService, private modalService: NgbModal ) { @@ -76,7 +75,7 @@ export class ArchivesComponent implements OnDestroy, OnInit { ngOnInit() { this.size = this.configService.getConfigValue('archive.filters.page.size', 10); - this.results = new Array(); + this.results = []; } resetForm() { @@ -97,8 +96,7 @@ export class ArchivesComponent implements OnDestroy, OnInit { this.resultsNumber = page.totalElements; this.currentPage = page_number + 1; // page on ngb-pagination component start at 1 , and page on backend start at 0 this.firstQueryHasBeenDone = true; - if (page.content.length > 0) this.hasResult = true; - else this.hasResult = false; + this.hasResult = page.content.length > 0; page.content.forEach(card => this.loadTranslationForCardIfNeeded(card)); this.results = page.content; }); @@ -129,12 +127,12 @@ export class ArchivesComponent implements OnDestroy, OnInit { .subscribe((page: Page) => { const lines = page.content; - const severityColumnName = this.translateColomn('archive.result.severity'); - const publishDateColumnName = this.translateColomn('archive.result.publishDate'); - const businessDateColumnName = this.translateColomn('archive.result.businessPeriod'); - const titleColumnName = this.translateColomn('archive.result.title'); - const summaryColumnName = this.translateColomn('archive.result.summary'); - const serviceColumnName = this.translateColomn('archive.result.service'); + const severityColumnName = this.translateColumn('archive.result.severity'); + const publishDateColumnName = this.translateColumn('archive.result.publishDate'); + const businessDateColumnName = this.translateColumn('archive.result.businessPeriod'); + const titleColumnName = this.translateColumn('archive.result.title'); + const summaryColumnName = this.translateColumn('archive.result.summary'); + const serviceColumnName = this.translateColumn('archive.result.service'); lines.forEach((card: LightCard) => { if (typeof card !== undefined) { @@ -144,21 +142,21 @@ export class ArchivesComponent implements OnDestroy, OnInit { [severityColumnName]: card.severity, [publishDateColumnName]: this.timeService.formatDateTime(card.publishDate), [businessDateColumnName]: this.displayTime(card.startDate) + '-' + this.displayTime(card.endDate), - [titleColumnName]: this.translateColomn(card.process + '.' + card.processVersion + '.' + card.title.key, card.title.parameters), - [summaryColumnName]: this.translateColomn(card.process + '.' + card.processVersion + '.' + card.summary.key, card.summary.parameters), - [serviceColumnName]: this.translateColomn(this.filtersTemplate.findServiceLabelForProcess(card.process)) + [titleColumnName]: this.translateColumn(card.process + '.' + card.processVersion + '.' + card.title.key, card.title.parameters), + [summaryColumnName]: this.translateColumn(card.process + '.' + card.processVersion + '.' + card.summary.key, card.summary.parameters), + [serviceColumnName]: this.translateColumn(this.filtersTemplate.findServiceLabelForProcess(card.process)) }); else exportArchiveData.push({ [severityColumnName]: card.severity, [publishDateColumnName]: this.timeService.formatDateTime(card.publishDate), [businessDateColumnName]: this.displayTime(card.startDate) + '-' + this.displayTime(card.endDate), - [titleColumnName]: this.translateColomn(card.process + '.' + card.processVersion + '.' + card.title.key, card.title.parameters), - [summaryColumnName]: this.translateColomn(card.process + '.' + card.processVersion + '.' + card.summary.key, card.summary.parameters) + [titleColumnName]: this.translateColumn(card.process + '.' + card.processVersion + '.' + card.title.key, card.title.parameters), + [summaryColumnName]: this.translateColumn(card.process + '.' + card.processVersion + '.' + card.summary.key, card.summary.parameters) }); } }); - this.exportService.exportAsExcelFile(exportArchiveData, 'Archive'); + ExportService.exportAsExcelFile(exportArchiveData, 'Archive'); }); } @@ -166,14 +164,14 @@ export class ArchivesComponent implements OnDestroy, OnInit { this.initExportArchiveData(); } - translateColomn(key: string | Array, interpolateParams?: Object): any { - let translatedColomn: number; + translateColumn(key: string | Array, interpolateParams?: Object): any { + let translatedColumn: number; this.translate.get(key, interpolateParams) .pipe(takeUntil(this.unsubscribe$)) - .subscribe((translate) => { translatedColomn = translate; }); + .subscribe((translate) => { translatedColumn = translate; }); - return translatedColomn; + return translatedColumn; } @@ -189,10 +187,9 @@ export class ArchivesComponent implements OnDestroy, OnInit { } getPublishDateTranslationParams(): any { - const param = { + return { 'time': this.timeService.formatDateTime(this.selectedCard.publishDate) - } - return param; + }; } ngOnDestroy() { diff --git a/ui/main/src/app/modules/feed/components/time-line/init-chart/init-chart.component.ts b/ui/main/src/app/modules/feed/components/time-line/init-chart/init-chart.component.ts index a0baeab192..181b6e0db5 100644 --- a/ui/main/src/app/modules/feed/components/time-line/init-chart/init-chart.component.ts +++ b/ui/main/src/app/modules/feed/components/time-line/init-chart/init-chart.component.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,7 +8,7 @@ */ -import {Component, Input, OnDestroy, OnInit} from '@angular/core'; +import {Component, Input, OnInit} from '@angular/core'; import * as _ from 'lodash-es'; import * as moment from 'moment'; import {Store} from '@ngrx/store'; @@ -16,20 +16,14 @@ import {AppState} from '@ofStore/index'; import {FilterType} from '@ofServices/filter.service'; import {ApplyFilter} from '@ofActions/feed.actions'; import {TimeService} from '@ofServices/time.service'; -import {GlobalStyleService} from '@ofServices/global-style.service'; -const forwardWeekConf = { - start: {year: 0, month: 0, week: 1, day: 0, hour: 0, minute: 0, second: 0}, - end: {year: 0, month: 0, week: 1, day: 0, hour: 0, minute: 0, second: 0} -}; - @Component({ selector: 'of-init-chart', templateUrl: './init-chart.component.html', styleUrls: ['./init-chart.component.scss'] }) -export class InitChartComponent implements OnInit, OnDestroy { +export class InitChartComponent implements OnInit { @Input() confDomain; @@ -52,7 +46,7 @@ export class InitChartComponent implements OnInit, OnDestroy { public endDate; - constructor(private store: Store, private time: TimeService, private globalStyleService: GlobalStyleService) { + constructor(private store: Store, private time: TimeService) { } @@ -112,11 +106,7 @@ export class InitChartComponent implements OnInit, OnDestroy { selectZoomButton(buttonTitle) { this.buttonList.forEach(button => { - if (button.buttonTitle === buttonTitle) { - button.selected = true; - } else { - button.selected = false; - } + button.selected = button.buttonTitle === buttonTitle; }); } @@ -138,7 +128,7 @@ export class InitChartComponent implements OnInit, OnDestroy { } case '7D': { startDomain = moment().minutes(0).second(0).millisecond(0).subtract(12, 'hours'); - // set position to a mutliple of 4 + // set position to a multiple of 4 for (let i = 0; i < 4; i++) { if (((startDomain.hours() - i) % 4) === 0) { startDomain.subtract(i, 'hours'); @@ -207,13 +197,9 @@ export class InitChartComponent implements OnInit, OnDestroy { } } - - ngOnDestroy() { - } - /** : - * apply arrow button clicked : switch the graph context with the zoom level configurated + * apply arrow button clicked : switch the graph context with the zoom level configured * at the left or right of our actual button selected * @param direction receive by child component custom-timeline-chart */ @@ -254,8 +240,8 @@ export class InitChartComponent implements OnInit, OnDestroy { startDomain = this.goForward(startDomain); endDomain = this.goForward(endDomain); } else { - startDomain = this.goBackword(startDomain); - endDomain = this.goBackword(endDomain); + startDomain = this.goBackward(startDomain); + endDomain = this.goBackward(endDomain); } this.setStartAndEndDomain(startDomain.valueOf(), endDomain.valueOf()); @@ -278,7 +264,7 @@ export class InitChartComponent implements OnInit, OnDestroy { } } - goBackword(dateToMove: moment.Moment) { + goBackward(dateToMove: moment.Moment) { switch (this.domainId) { case 'TR': return dateToMove.subtract(2, 'hour'); diff --git a/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.ts b/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.ts index 603bfd6cfd..9b2adf484c 100644 --- a/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.ts +++ b/ui/main/src/app/modules/logging/components/logging-table/logging-table.component.ts @@ -12,7 +12,7 @@ import { Component, Input, OnInit, OnDestroy } from '@angular/core'; import { LineOfLoggingResult } from '@ofModel/line-of-logging-result.model'; import { TimeService } from '@ofServices/time.service'; import { Moment } from 'moment-timezone'; -import { CardService } from '../../../../services/card.service'; +import { CardService } from '@ofServices/card.service'; import { selectLoggingCount, selectLoggingFilter } from '@ofSelectors/logging.selectors'; import { Store, select } from '@ngrx/store'; import { Page } from '@ofModel/page.model'; @@ -23,7 +23,7 @@ import { TranslateService } from '@ngx-translate/core'; import { ExportService } from '@ofServices/export.service'; import { FlushLoggingResult, UpdateLoggingPage } from '@ofStore/actions/logging.actions'; import { ConfigService } from '@ofServices/config.service'; -import { LoggingComponent } from "../../logging.component"; +import { LoggingComponent } from '../../logging.component'; @Component({ @@ -49,7 +49,6 @@ export class LoggingTableComponent implements OnInit, OnDestroy { private cardService: CardService, private store: Store, private translate: TranslateService, - private exportService: ExportService, private configService: ConfigService, private parentComponent: LoggingComponent) { } @@ -61,7 +60,7 @@ export class LoggingTableComponent implements OnInit, OnDestroy { catchError(err => of(0)) ); this.size = this.configService.getConfigValue('archive.filters.page.size', 10); - + this.store.select(selectLoggingFilter) .pipe(takeUntil(this.unsubscribe$)) .subscribe(filters => { @@ -93,35 +92,35 @@ export class LoggingTableComponent implements OnInit, OnDestroy { .subscribe((page: Page) => { const lines = page.content; - const timeOfActionColumnName = this.translateColomn('logging.timeOfAction'); - const titleColumnName = this.translateColomn('logging.title'); - const summaryColumnName = this.translateColomn('logging.summary'); - const descriptionColumnName = this.translateColomn('logging.description'); - const senderColumnName = this.translateColomn('logging.sender'); - const serviceColumnName = this.translateColomn('logging.service'); + const timeOfActionColumnName = this.translateColumn('logging.timeOfAction'); + const titleColumnName = this.translateColumn('logging.title'); + const summaryColumnName = this.translateColumn('logging.summary'); + const descriptionColumnName = this.translateColumn('logging.description'); + const senderColumnName = this.translateColumn('logging.sender'); + const serviceColumnName = this.translateColumn('logging.service'); lines.forEach( (line: LineOfLoggingResult) => { if (typeof line !== undefined) { if (this.displayServiceColumn) this.exportLoggingData.push({ [timeOfActionColumnName]: this.timeService.formatDateTime(line.businessDate), - [titleColumnName]: this.translateColomn(line.i18nKeyForTitle.key, line.i18nKeyForTitle.parameters), - [summaryColumnName]: this.translateColomn(line.i18nKeyForSummary.key, line.i18nKeyForSummary.parameters), - [descriptionColumnName]: this.translateColomn(this.processStateDescription.get(line.process + '.' + line.state)), + [titleColumnName]: this.translateColumn(line.i18nKeyForTitle.key, line.i18nKeyForTitle.parameters), + [summaryColumnName]: this.translateColumn(line.i18nKeyForSummary.key, line.i18nKeyForSummary.parameters), + [descriptionColumnName]: this.translateColumn(this.processStateDescription.get(line.process + '.' + line.state)), [senderColumnName]: line.sender, - [serviceColumnName]: this.translateColomn(this.parentComponent.filters.filtersTemplate.findServiceLabelForProcess(line.process)) + [serviceColumnName]: this.translateColumn(this.parentComponent.filters.filtersTemplate.findServiceLabelForProcess(line.process)) }); else this.exportLoggingData.push({ [timeOfActionColumnName]: this.timeService.formatDateTime(line.businessDate), - [titleColumnName]: this.translateColomn(line.i18nKeyForTitle.key, line.i18nKeyForTitle.parameters), - [summaryColumnName]: this.translateColomn(line.i18nKeyForSummary.key, line.i18nKeyForSummary.parameters), - [descriptionColumnName]: this.translateColomn(this.processStateDescription.get(line.process + '.' + line.state)), + [titleColumnName]: this.translateColumn(line.i18nKeyForTitle.key, line.i18nKeyForTitle.parameters), + [summaryColumnName]: this.translateColumn(line.i18nKeyForSummary.key, line.i18nKeyForSummary.parameters), + [descriptionColumnName]: this.translateColumn(this.processStateDescription.get(line.process + '.' + line.state)), [senderColumnName]: line.sender }); } }); - this.exportService.exportAsExcelFile(this.exportLoggingData, 'Logging'); + ExportService.exportAsExcelFile(this.exportLoggingData, 'Logging'); }); } @@ -129,14 +128,14 @@ export class LoggingTableComponent implements OnInit, OnDestroy { this.initExportLoggingData(); } - translateColomn(key: string | Array, interpolateParams?: Object): any { - let translatedColomn: number; + translateColumn(key: string | Array, interpolateParams?: Object): any { + let translatedColumn: number; this.translate.get(key, interpolateParams) .pipe(takeUntil(this.unsubscribe$)) - .subscribe((translate) => { translatedColomn = translate; }); + .subscribe((translate) => { translatedColumn = translate; }); - return translatedColomn; + return translatedColumn; } diff --git a/ui/main/src/app/modules/monitoring/components/monitoring-table/monitoring-table.component.ts b/ui/main/src/app/modules/monitoring/components/monitoring-table/monitoring-table.component.ts index 58ea674b22..db6134f880 100644 --- a/ui/main/src/app/modules/monitoring/components/monitoring-table/monitoring-table.component.ts +++ b/ui/main/src/app/modules/monitoring/components/monitoring-table/monitoring-table.component.ts @@ -39,7 +39,6 @@ export class MonitoringTableComponent implements OnDestroy { constructor(readonly timeService: TimeService , private translate: TranslateService - , private exportService: ExportService , private store: Store , private modalService: NgbModal ) { @@ -59,22 +58,22 @@ export class MonitoringTableComponent implements OnDestroy { this.exportMonitoringData = []; let time: string, businessPeriod: string, processName: any, title: any, summary: any, status: any; - const timeColumnName = this.translateColomn('monitoring.time'); - const businessPeriodColumnName = this.translateColomn('monitoring.businessPeriod'); - const processColumnName = this.translateColomn('monitoring.filters.process'); - const titleColumnName = this.translateColomn('monitoring.title'); - const summaryColumnName = this.translateColomn('monitoring.summary'); - const statusColumnName = this.translateColomn('monitoring.status'); - const severityColumnName = this.translateColomn('monitoring.severity'); + const timeColumnName = this.translateColumn('monitoring.time'); + const businessPeriodColumnName = this.translateColumn('monitoring.businessPeriod'); + const processColumnName = this.translateColumn('monitoring.filters.process'); + const titleColumnName = this.translateColumn('monitoring.title'); + const summaryColumnName = this.translateColumn('monitoring.summary'); + const statusColumnName = this.translateColumn('monitoring.status'); + const severityColumnName = this.translateColumn('monitoring.severity'); this.result.forEach((line: LineOfMonitoringResult) => { if (typeof line !== undefined) { time = this.displayTime(line.creationDateTime); businessPeriod = this.displayTime(line.beginningOfBusinessPeriod).concat(this.displayTime(line.endOfBusinessPeriod)); - processName = this.translateColomn(line.processName); - title = this.translateColomn(line.title.key, line.title.parameters); - summary = this.translateColomn(line.summary.key, line.summary.parameters); - status = this.translateColomn(line.coordinationStatus); + processName = this.translateColumn(line.processName); + title = this.translateColumn(line.title.key, line.title.parameters); + summary = this.translateColumn(line.summary.key, line.summary.parameters); + status = this.translateColumn(line.coordinationStatus); this.exportMonitoringData.push({ [timeColumnName]: time, @@ -91,19 +90,19 @@ export class MonitoringTableComponent implements OnDestroy { export(): void { this.initExportMonitoringData(); - this.exportService.exportAsExcelFile(this.exportMonitoringData, 'Monitoring'); + ExportService.exportAsExcelFile(this.exportMonitoringData, 'Monitoring'); } - translateColomn(key: string | Array, interpolateParams?: Object): any { - let translatedColomn: number; + translateColumn(key: string | Array, interpolateParams?: Object): any { + let translatedColumn: number; this.translate.get(key, interpolateParams) .pipe(takeUntil(this.unsubscribe$)) .subscribe((translate) => { - translatedColomn = translate; + translatedColumn = translate; }); - return translatedColomn; + return translatedColumn; } ngOnDestroy() { diff --git a/ui/main/src/app/modules/navbar/menus/menu-link/menu-link.component.html b/ui/main/src/app/modules/navbar/menus/menu-link/menu-link.component.html index 8004e9746a..dfbb065317 100644 --- a/ui/main/src/app/modules/navbar/menus/menu-link/menu-link.component.html +++ b/ui/main/src/app/modules/navbar/menus/menu-link/menu-link.component.html @@ -1,4 +1,4 @@ - + @@ -7,15 +7,15 @@ -
+ -
+ -
+ \ No newline at end of file +
diff --git a/ui/main/src/app/modules/navbar/menus/menu-link/menu-link.component.ts b/ui/main/src/app/modules/navbar/menus/menu-link/menu-link.component.ts index 6e7d7840de..e8f938f5b0 100644 --- a/ui/main/src/app/modules/navbar/menus/menu-link/menu-link.component.ts +++ b/ui/main/src/app/modules/navbar/menus/menu-link/menu-link.component.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,34 +8,29 @@ */ -import {Component, Input, OnInit} from '@angular/core'; -import {Menu, MenuEntry, MenuEntryLinkTypeEnum} from "@ofModel/menu.model"; -import {Store} from "@ngrx/store"; -import {AppState} from "@ofStore/index"; -import { ConfigService} from "@ofServices/config.service"; +import {Component, Input} from '@angular/core'; +import {Menu, MenuEntry, MenuEntryLinkTypeEnum} from '@ofModel/menu.model'; @Component({ selector: 'of-menu-link', templateUrl: './menu-link.component.html', styleUrls: ['./menu-link.component.scss'] }) -export class MenuLinkComponent implements OnInit { +export class MenuLinkComponent { @Input() public menu: Menu; @Input() public menuEntry: MenuEntry; - - constructor(private store: Store,private configService: ConfigService) { + + constructor() { + // No body because all members are Inputs. } - LynkType = MenuEntryLinkTypeEnum + LinkType = MenuEntryLinkTypeEnum; public hasLinkType(type: MenuEntryLinkTypeEnum) { return this.menuEntry.linkType === type; } - ngOnInit() { - - } } diff --git a/ui/main/src/app/modules/settings/components/settings/base-setting/base-setting.component.html b/ui/main/src/app/modules/settings/components/settings/base-setting/base-setting.component.html deleted file mode 100644 index 50a5fa4b49..0000000000 --- a/ui/main/src/app/modules/settings/components/settings/base-setting/base-setting.component.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - -

- base-setting works! -

diff --git a/ui/main/src/app/modules/settings/components/settings/base-setting/base-setting.component.ts b/ui/main/src/app/modules/settings/components/settings/base-setting/base-setting.directive.ts similarity index 87% rename from ui/main/src/app/modules/settings/components/settings/base-setting/base-setting.component.ts rename to ui/main/src/app/modules/settings/components/settings/base-setting/base-setting.directive.ts index 1bea7b6c10..cafa556ce4 100644 --- a/ui/main/src/app/modules/settings/components/settings/base-setting/base-setting.component.ts +++ b/ui/main/src/app/modules/settings/components/settings/base-setting/base-setting.directive.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,7 +8,7 @@ */ -import {Component, Input, OnDestroy, OnInit} from '@angular/core'; +import {Directive, Injectable, Input, OnDestroy, OnInit} from '@angular/core'; import {AppState} from '@ofStore/index'; import {Store} from '@ngrx/store'; import {PatchSettings} from '@ofActions/settings.actions'; @@ -19,11 +19,9 @@ import {FormGroup} from '@angular/forms'; import * as _ from 'lodash-es'; import {selectIdentifier} from '@ofSelectors/authentication.selectors'; -@Component({ - selector: 'of-base-setting', - templateUrl: './base-setting.component.html' -}) -export class BaseSettingComponent implements OnInit, OnDestroy { +@Directive() +@Injectable() +export abstract class BaseSettingDirective implements OnInit, OnDestroy { @Input() public settingPath: string; @Input() public messagePlaceholder: string; @@ -33,7 +31,7 @@ export class BaseSettingComponent implements OnInit, OnDestroy { form: FormGroup; private baseSettings = {}; - constructor(protected store: Store) { + protected constructor(protected store: Store) { } @@ -73,9 +71,7 @@ export class BaseSettingComponent implements OnInit, OnDestroy { this.ngUnsubscribe$.complete(); } - protected updateValue(value: any) { - - } + protected abstract updateValue(value: any); protected initFormGroup(): FormGroup { return null; diff --git a/ui/main/src/app/modules/settings/components/settings/checkbox-setting/checkbox-setting.component.ts b/ui/main/src/app/modules/settings/components/settings/checkbox-setting/checkbox-setting.component.ts index a9fd38fc88..0102f0891b 100644 --- a/ui/main/src/app/modules/settings/components/settings/checkbox-setting/checkbox-setting.component.ts +++ b/ui/main/src/app/modules/settings/components/settings/checkbox-setting/checkbox-setting.component.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,17 +9,17 @@ import {Component, Input, OnDestroy, OnInit} from '@angular/core'; -import {BaseSettingComponent} from "../base-setting/base-setting.component"; -import {Store} from "@ngrx/store"; -import {AppState} from "@ofStore/index"; -import {FormControl, FormGroup} from "@angular/forms"; +import {BaseSettingDirective} from '../base-setting/base-setting.directive'; +import {Store} from '@ngrx/store'; +import {AppState} from '@ofStore/index'; +import {FormControl, FormGroup} from '@angular/forms'; @Component({ selector: 'of-checkbox-setting', templateUrl: './checkbox-setting.component.html', styleUrls: ['./checkbox-setting.component.scss'] }) -export class CheckboxSettingComponent extends BaseSettingComponent implements OnInit, OnDestroy { +export class CheckboxSettingComponent extends BaseSettingDirective implements OnInit, OnDestroy { @Input() public labelClass: string; @@ -35,7 +35,7 @@ export class CheckboxSettingComponent extends BaseSettingComponent implements On return new FormGroup({ setting: new FormControl('') }, {updateOn: 'change'}); - //No need for validators are the checkbox input type can only create boolean values + // No need for validators are the checkbox input type can only create boolean values } updateValue(value) { diff --git a/ui/main/src/app/modules/settings/components/settings/list-setting/list-setting.component.ts b/ui/main/src/app/modules/settings/components/settings/list-setting/list-setting.component.ts index 57bd0fde9f..79686c9341 100644 --- a/ui/main/src/app/modules/settings/components/settings/list-setting/list-setting.component.ts +++ b/ui/main/src/app/modules/settings/components/settings/list-setting/list-setting.component.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,9 +8,8 @@ */ - import {Component, Input, OnDestroy, OnInit} from '@angular/core'; -import {BaseSettingComponent} from '../base-setting/base-setting.component'; +import {BaseSettingDirective} from '../base-setting/base-setting.directive'; import {AppState} from '@ofStore/index'; import {Store} from '@ngrx/store'; import {AbstractControl, FormControl, FormGroup, Validators} from '@angular/forms'; @@ -22,7 +21,7 @@ import {Observable, of} from 'rxjs'; selector: 'of-list-setting', templateUrl: './list-setting.component.html' }) -export class ListSettingComponent extends BaseSettingComponent implements OnInit, OnDestroy { +export class ListSettingComponent extends BaseSettingDirective implements OnInit, OnDestroy { @Input() values: ({ value: string, label: (I18n | string) } | string)[]; preparedList: { value: string, label: Observable }[]; diff --git a/ui/main/src/app/modules/settings/components/settings/multi-settings/multi-settings.component.ts b/ui/main/src/app/modules/settings/components/settings/multi-settings/multi-settings.component.ts index cbc4494d70..9e68d4cc13 100644 --- a/ui/main/src/app/modules/settings/components/settings/multi-settings/multi-settings.component.ts +++ b/ui/main/src/app/modules/settings/components/settings/multi-settings/multi-settings.component.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,9 +8,8 @@ */ - import {Component, OnDestroy, OnInit} from '@angular/core'; -import {BaseSettingComponent} from '../base-setting/base-setting.component'; +import {BaseSettingDirective} from '../base-setting/base-setting.directive'; import {Store} from '@ngrx/store'; import {AppState} from '@ofStore/index'; import {FormControl, FormGroup, Validators} from '@angular/forms'; @@ -19,7 +18,7 @@ import {FormControl, FormGroup, Validators} from '@angular/forms'; selector: 'of-multi-settings', templateUrl: './multi-settings.component.html' }) -export class MultiSettingsComponent extends BaseSettingComponent implements OnInit, OnDestroy { +export class MultiSettingsComponent extends BaseSettingDirective implements OnInit, OnDestroy { constructor(protected store: Store) { super(store); diff --git a/ui/main/src/app/modules/settings/components/settings/text-setting/text-setting.component.ts b/ui/main/src/app/modules/settings/components/settings/text-setting/text-setting.component.ts index 8d2d39fe50..ae2c5f309a 100644 --- a/ui/main/src/app/modules/settings/components/settings/text-setting/text-setting.component.ts +++ b/ui/main/src/app/modules/settings/components/settings/text-setting/text-setting.component.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,9 +8,8 @@ */ - import {Component, Input, OnDestroy, OnInit} from '@angular/core'; -import {BaseSettingComponent} from '../base-setting/base-setting.component'; +import {BaseSettingDirective} from '../base-setting/base-setting.directive'; import {AppState} from '@ofStore/index'; import {Store} from '@ngrx/store'; import {FormControl, FormGroup, Validators} from '@angular/forms'; @@ -20,7 +19,7 @@ import {FormControl, FormGroup, Validators} from '@angular/forms'; selector: 'of-text-setting', templateUrl: './text-setting.component.html' }) -export class TextSettingComponent extends BaseSettingComponent implements OnInit, OnDestroy { +export class TextSettingComponent extends BaseSettingDirective implements OnInit, OnDestroy { @Input() pattern: string; @Input() disabled: boolean; diff --git a/ui/main/src/app/modules/settings/settings.module.ts b/ui/main/src/app/modules/settings/settings.module.ts index 5057ae0c17..d61fa08b87 100644 --- a/ui/main/src/app/modules/settings/settings.module.ts +++ b/ui/main/src/app/modules/settings/settings.module.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,12 +8,10 @@ */ - import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {SettingsRoutingModule} from './settings-routing.module'; import {SettingsComponent} from './components/settings/settings.component'; -import {BaseSettingComponent} from './components/settings/base-setting/base-setting.component'; import {TextSettingComponent} from './components/settings/text-setting/text-setting.component'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {TranslateModule} from '@ngx-translate/core'; @@ -21,11 +19,10 @@ import {ListSettingComponent} from './components/settings/list-setting/list-sett import {MultiSettingsComponent} from './components/settings/multi-settings/multi-settings.component'; import {TypeAheadSettingsComponent} from './components/settings/type-ahead-settings/type-ahead-settings.component'; import {TypeaheadModule} from 'ngx-type-ahead'; -import { CheckboxSettingComponent } from './components/settings/checkbox-setting/checkbox-setting.component'; +import {CheckboxSettingComponent} from './components/settings/checkbox-setting/checkbox-setting.component'; @NgModule({ declarations: [SettingsComponent - , BaseSettingComponent , TextSettingComponent , ListSettingComponent , MultiSettingsComponent diff --git a/ui/main/src/app/services/export.service.spec.ts b/ui/main/src/app/services/export.service.spec.ts deleted file mode 100644 index 2ee87475ae..0000000000 --- a/ui/main/src/app/services/export.service.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) - * Copyright (c) 2020, RTEi (http://www.rte-international.com) - * See AUTHORS.txt - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * SPDX-License-Identifier: MPL-2.0 - * This file is part of the OperatorFabric project. - */ - -import { TestBed } from '@angular/core/testing'; -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { StoreModule } from '@ngrx/store'; -import { appReducer } from '@ofStore/index'; - -import { ExportService } from './export.service'; - -describe('ExportService', () => { - let service: ExportService; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [HttpClientTestingModule, - StoreModule.forRoot(appReducer)], - providers: [ExportService] - - }); - service = TestBed.inject(ExportService); - - }); - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/ui/main/src/app/services/export.service.ts b/ui/main/src/app/services/export.service.ts index 1c1cb56d9f..9f23eb2c58 100644 --- a/ui/main/src/app/services/export.service.ts +++ b/ui/main/src/app/services/export.service.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * Copyright (c) 2020, RTEi (http://www.rte-international.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public @@ -7,27 +7,22 @@ * SPDX-License-Identifier: MPL-2.0 * This file is part of the OperatorFabric project. */ -import {Injectable} from '@angular/core'; import * as XLSX from 'xlsx'; import {saveAs} from 'file-saver-es'; const EXCEL_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'; const EXCEL_EXTENSION = '.xlsx'; -@Injectable() -export class ExportService { +export abstract class ExportService { - constructor() { - } - - public exportAsExcelFile(json: any[], excelFileName: string): void { + public static exportAsExcelFile(json: any[], excelFileName: string): void { const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(json); const workbook: XLSX.WorkBook = { Sheets: { 'data': worksheet }, SheetNames: ['data'] }; const excelBuffer: any = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); this.saveAsExcelFile(excelBuffer, excelFileName); } - private saveAsExcelFile(buffer: any, fileName: string): void { + private static saveAsExcelFile(buffer: any, fileName: string): void { const data: Blob = new Blob([buffer], { type: EXCEL_TYPE }); diff --git a/ui/main/src/app/services/services.module.ts b/ui/main/src/app/services/services.module.ts index b16100d548..b05b94992c 100644 --- a/ui/main/src/app/services/services.module.ts +++ b/ui/main/src/app/services/services.module.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com)Copyright (c) 2020, RTEi (http://www.rte-international.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * Copyright (c) 2020, RTEi (http://www.rte-international.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public @@ -27,7 +27,6 @@ import {GlobalStyleService} from '@ofServices/global-style.service'; import {AppService} from './app.service'; import {GroupsService} from './groups.service'; import {EntitiesService} from './entities.service'; -import {ExportService} from './export.service'; import {ReminderService} from '@ofServices/reminder/reminder.service'; @NgModule({ @@ -38,7 +37,6 @@ import {ReminderService} from '@ofServices/reminder/reminder.service'; ConfigService, SettingsService, CardService, - ExportService, AuthenticationService, TimeService, ProcessesService, diff --git a/ui/main/src/app/store/actions/authentication.actions.ts b/ui/main/src/app/store/actions/authentication.actions.ts index e2055bac3e..a1f25d97bc 100644 --- a/ui/main/src/app/store/actions/authentication.actions.ts +++ b/ui/main/src/app/store/actions/authentication.actions.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,26 +8,25 @@ */ - import {Action} from '@ngrx/store'; import {Guid} from 'guid-typescript'; -import {Message} from "@ofModel/message.model"; +import {Message} from '@ofModel/message.model'; export enum AuthenticationActionTypes { InitAuthStatus = '[Authentication] Init Authentication Status' - ,CheckAuthenticationStatus = '[Authentication] Check Authentication Status' - ,AcceptLogIn = '[Authentication] Accept the user log in attempt' - ,RejectLogIn = '[Authentication] Reject the user log in attempt' - ,TryToLogIn = '[Authentication] Try to log the user in' - ,TryToLogOut = '[Authentication] Try to log the user out' - ,AcceptLogOut = '[Authentication] Accept the user log out attempt' - ,AcceptLogOutSuccess = '[Authentication] Success Accept the user log out attempt' - ,CheckImplicitFlowAuthenticationStatus = '[Authentication] Check Authentication Status specifically for the Implicit Flow' - ,UselessAuthAction = '[Authentication] Test purpose action' + , CheckAuthenticationStatus = '[Authentication] Check Authentication Status' + , AcceptLogIn = '[Authentication] Accept the user log in attempt' + , RejectLogIn = '[Authentication] Reject the user log in attempt' + , TryToLogIn = '[Authentication] Try to log the user in' + , TryToLogOut = '[Authentication] Try to log the user out' + , AcceptLogOut = '[Authentication] Accept the user log out attempt' + , AcceptLogOutSuccess = '[Authentication] Success Accept the user log out attempt' + , CheckImplicitFlowAuthenticationStatus = '[Authentication] Check Authentication Status specifically for the Implicit Flow' + , UselessAuthAction = '[Authentication] Test purpose action' // TODO the following actions should be merge with password and code flow management of authentication - ,ImplicitallyAuthenticated = '[Authentication] User is authentication using Implicit Flow' - ,UnAuthenticationFromImplicitFlow = '[Authentication] User is log out by implicit Flow internal managment' - ,UnableToRefreshOrGetToken = '[Authentication] The token can not be refresh or we cannot get a token' + , ImplicitlyAuthenticated = '[Authentication] User is authentication using Implicit Flow' + , UnAuthenticationFromImplicitFlow = '[Authentication] User is log out by implicit Flow internal management' + , UnableToRefreshOrGetToken = '[Authentication] The token can not be refresh or we cannot get a token' } /** @@ -38,8 +37,8 @@ export class PayloadForSuccessfulAuthentication { public clientId: Guid, public token: string, public expirationDate: Date, - public firstName?:string, - public lastName?:string) { + public firstName?: string, + public lastName?: string) { } } @@ -51,7 +50,7 @@ export class InitAuthStatus implements Action { /* istanbul ignore next */ readonly type = AuthenticationActionTypes.InitAuthStatus; /* istanbul ignore next */ - constructor(public payload:{code: string}){} + constructor(public payload: {code: string}) {} } /** @@ -81,10 +80,10 @@ export class AcceptLogIn implements Action { */ export class TryToLogIn implements Action { /* istanbul ignore next */ - readonly type= AuthenticationActionTypes.TryToLogIn; + readonly type = AuthenticationActionTypes.TryToLogIn; /* istanbul ignore next */ - constructor(public payload: {username: string, password: string}){} + constructor(public payload: {username: string, password: string}) {} } /** @@ -112,11 +111,7 @@ export class RejectLogIn implements Action { * */ export class AcceptLogOut implements Action { - /* istanbul ignore next */ readonly type = AuthenticationActionTypes.AcceptLogOut; - - /* istanbul ignore next */ - constructor(){} } /** @@ -133,7 +128,7 @@ export class CheckImplicitFlowAuthenticationStatus implements Action { readonly type = AuthenticationActionTypes.CheckImplicitFlowAuthenticationStatus; } -export class UselessAuthAction implements Action{ +export class UselessAuthAction implements Action { /* istanbul ignore next */ readonly type = AuthenticationActionTypes.UselessAuthAction; @@ -141,7 +136,7 @@ export class UselessAuthAction implements Action{ export class ImplicitlyAuthenticated implements Action { /* istanbul ignore next */ - readonly type = AuthenticationActionTypes.ImplicitallyAuthenticated; + readonly type = AuthenticationActionTypes.ImplicitlyAuthenticated; } export class UnAuthenticationFromImplicitFlow implements Action { diff --git a/ui/main/src/app/store/actions/feed.actions.ts b/ui/main/src/app/store/actions/feed.actions.ts index 36cbb07f76..07c382742d 100644 --- a/ui/main/src/app/store/actions/feed.actions.ts +++ b/ui/main/src/app/store/actions/feed.actions.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -33,16 +33,10 @@ export class ApplyFilter implements Action { export class ChangeSort implements Action { readonly type = FeedActionTypes.ChangeSort; - /* istanbul ignore next */ - constructor() { - } } export class ChangeReadSort implements Action { readonly type = FeedActionTypes.ChangeReadSort; - - constructor() { - } } export class ResetFilter implements Action { diff --git a/ui/main/src/app/store/actions/light-card.actions.ts b/ui/main/src/app/store/actions/light-card.actions.ts index 92ac372d69..7bed7bb7e9 100644 --- a/ui/main/src/app/store/actions/light-card.actions.ts +++ b/ui/main/src/app/store/actions/light-card.actions.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,7 +8,6 @@ */ - import {Action} from '@ngrx/store'; import {LightCard} from '@ofModel/light-card.model'; @@ -16,7 +15,6 @@ export enum LightCardActionTypes { LoadLightCards = '[LCard] Load', EmptyLightCards = '[LCard] Empty', LoadLightCardsSuccess = '[LCard] Load Success', - LoadLightCardsExtendedData = '[LCard] Load Extended Data', LoadLightCardsFailure = '[LCard] Load Fail', SelectLightCard = '[LCard] Select One', ClearLightCardSelection = '[LCard] Clear Light Card Selection', @@ -41,16 +39,7 @@ export class EmptyLightCards implements Action { export class LoadLightCardsSuccess implements Action { readonly type = LightCardActionTypes.LoadLightCardsSuccess; - /* istanbul ignore next */ - constructor(public payload: { lightCards: LightCard[] }) { - } -} - -export class LoadLightCardsExtendedData implements Action { - readonly type = LightCardActionTypes.LoadLightCardsExtendedData; - - /* istanbul ignore next */ - constructor() { + constructor(public payload: {lightCards: LightCard[]} ) { } } @@ -76,8 +65,6 @@ export class ClearLightCardSelection implements Action { readonly type = LightCardActionTypes.ClearLightCardSelection; - constructor() { - } } export class AddLightCardFailure implements Action { @@ -115,8 +102,6 @@ export class UpdateALightCard implements Action { export class LightCardAlreadyUpdated implements Action { readonly type = LightCardActionTypes.LightCardAlreadyUpdated; - constructor() { - } } export type LightCardActions = diff --git a/ui/main/src/app/store/actions/menu.actions.ts b/ui/main/src/app/store/actions/menu.actions.ts index 452f755204..fad9b75c0e 100644 --- a/ui/main/src/app/store/actions/menu.actions.ts +++ b/ui/main/src/app/store/actions/menu.actions.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,24 +8,19 @@ */ - import {Action} from '@ngrx/store'; -import {Menu} from "@ofModel/menu.model"; +import {Menu} from '@ofModel/menu.model'; export enum MenuActionTypes { LoadMenu = '[Menu] Load Menu', LoadMenuSuccess = '[Menu] Load Menu Success', LoadMenuFailure = '[Menu] Load Menu Fail', HandleUnexpectedError = '[Menu] Handle unexpected error', - + } // needed by NGRX entities export class LoadMenu implements Action { readonly type = MenuActionTypes.LoadMenu; - - /* istanbul ignore next */ - constructor() { - } } export class LoadMenuFailure implements Action { readonly type = MenuActionTypes.LoadMenuFailure; diff --git a/ui/main/src/app/store/reducers/authentication.reducer.ts b/ui/main/src/app/store/reducers/authentication.reducer.ts index 187560ea79..f0a821077a 100644 --- a/ui/main/src/app/store/reducers/authentication.reducer.ts +++ b/ui/main/src/app/store/reducers/authentication.reducer.ts @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, RTE (http://www.rte-france.com) +/* Copyright (c) 2018-2021, RTE (http://www.rte-france.com) * See AUTHORS.txt * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,7 +8,6 @@ */ - import {AuthenticationActions, AuthenticationActionTypes} from '@ofActions/authentication.actions'; import {authInitialState, AuthState} from '@ofStates/authentication.state'; @@ -21,7 +20,7 @@ export function reducer(state: AuthState = authInitialState, action: Authenticat ...state, code: action.payload.code, message: null - } + }; } case AuthenticationActionTypes.AcceptLogIn: { @@ -60,7 +59,7 @@ export function reducer(state: AuthState = authInitialState, action: Authenticat message: action.payload.error }; } - case AuthenticationActionTypes.ImplicitallyAuthenticated: { + case AuthenticationActionTypes.ImplicitlyAuthenticated: { return { ...state, isImplicitlyAuthenticated: true @@ -70,7 +69,7 @@ export function reducer(state: AuthState = authInitialState, action: Authenticat return { ...state, isImplicitlyAuthenticated: false - } + }; } default: @@ -97,4 +96,4 @@ export const getExpirationTime = (state: AuthState) => { } else { return UTC_beginning_time; } -} +}; From 76e25e91a6c3a95eb4598ccb247169191b9eb573 Mon Sep 17 00:00:00 2001 From: freddidierRTE Date: Wed, 24 Feb 2021 08:12:08 +0100 Subject: [PATCH 03/45] [OC-1502] Bug - correct rendering of chosen values in multi-select input field Signed-off-by: freddidierRTE --- ui/main/src/assets/styles/styles.scss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ui/main/src/assets/styles/styles.scss b/ui/main/src/assets/styles/styles.scss index b176a90895..16f0044d59 100644 --- a/ui/main/src/assets/styles/styles.scss +++ b/ui/main/src/assets/styles/styles.scss @@ -545,8 +545,11 @@ type-ahead > .badge-primary { } -.opfab-multiselect .c-token { - width: 85%; +// Apply only on archives and logging pages as we want only one value in to see in the input field +.archives-page .opfab-multiselect .c-token, +.archives-login .opfab-multiselect .c-token + { + width: 85%; } .opfab-multiselect::after { From 15efb812f08b5d8786550acb79427afcf59e9d7b Mon Sep 17 00:00:00 2001 From: Alexandra Guironnet Date: Wed, 24 Feb 2021 16:34:44 +0100 Subject: [PATCH 04/45] [OC-1089] Add perimeter management to admin screen --- ui/main/src/app/common/utilities.ts | 19 +++ ui/main/src/app/model/perimeter.model.ts | 31 ++++ ui/main/src/app/model/processes.model.ts | 9 +- .../src/app/model/userWithPerimeters.model.ts | 8 +- .../app/modules/admin/admin-routing.module.ts | 5 + .../app/modules/admin/admin.component.html | 3 + ui/main/src/app/modules/admin/admin.module.ts | 33 +++- .../action-cell-renderer.component.html | 0 .../action-cell-renderer.component.ts | 2 +- .../array-cell-renderer.component.html | 0 .../array-cell-renderer.component.ts | 0 .../entity-cell-renderer.component.ts | 2 +- .../group-cell-renderer.component.ts | 2 +- .../process-cell-renderer.component.ts | 25 +++ .../state-rights-cell-renderer.component.html | 18 ++ .../state-rights-cell-renderer.component.scss | 21 +++ .../state-rights-cell-renderer.component.ts | 48 ++++++ .../edit-entity-modal.component.html} | 18 +- .../edit-entity-modal.component.scss} | 0 .../edit-entity-modal.component.ts} | 24 +-- .../groups/edit-group-modal.component.html | 64 +++++++ .../groups/edit-group-modal.component.scss | 17 ++ .../groups/edit-group-modal.component.ts | 112 ++++++++++++ .../edit-perimeter-modal.component.html | 76 +++++++++ .../edit-perimeter-modal.component.scss | 23 +++ .../edit-perimeter-modal.component.ts | 159 ++++++++++++++++++ .../users/edit-user-modal.component.html | 1 + .../users/edit-user-modal.component.ts | 4 +- .../components/table/admin-table.directive.ts | 19 ++- .../table/entities-table.component.ts | 6 +- .../table/groups-table.component.ts | 6 +- .../table/perimeters-table.component.ts | 28 +++ .../components/table/users-table.component.ts | 2 +- .../modules/admin/services/sharing.service.ts | 13 +- .../components/detail/detail.component.ts | 22 +-- .../feedconfiguration.component.ts | 93 +++++----- .../app/modules/logging/logging.component.ts | 14 +- .../single-filter.component.html | 2 +- .../single-filter/single-filter.component.ts | 3 +- .../modules/usercard/usercard.component.ts | 121 +++++++------ .../src/app/services/perimeters.service.ts | 113 +++++++++++++ ui/main/src/assets/i18n/en.json | 22 ++- ui/main/src/assets/i18n/fr.json | 24 ++- ui/main/src/environments/environment.prod.ts | 4 +- ui/main/src/environments/environment.ts | 4 +- 45 files changed, 1006 insertions(+), 214 deletions(-) create mode 100644 ui/main/src/app/common/utilities.ts create mode 100644 ui/main/src/app/model/perimeter.model.ts rename ui/main/src/app/modules/admin/components/{table => cell-renderers}/action-cell-renderer.component.html (100%) rename ui/main/src/app/modules/admin/components/{table => cell-renderers}/action-cell-renderer.component.ts (96%) rename ui/main/src/app/modules/admin/components/{table => cell-renderers}/array-cell-renderer.component.html (100%) rename ui/main/src/app/modules/admin/components/{table => cell-renderers}/array-cell-renderer.component.ts (100%) rename ui/main/src/app/modules/admin/components/{table => cell-renderers}/entity-cell-renderer.component.ts (94%) rename ui/main/src/app/modules/admin/components/{table => cell-renderers}/group-cell-renderer.component.ts (94%) create mode 100644 ui/main/src/app/modules/admin/components/cell-renderers/process-cell-renderer.component.ts create mode 100644 ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.html create mode 100644 ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.scss create mode 100644 ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.ts rename ui/main/src/app/modules/admin/components/editmodal/{groups-entities/edit-entity-group-modal.component.html => entities/edit-entity-modal.component.html} (68%) rename ui/main/src/app/modules/admin/components/editmodal/{groups-entities/edit-entity-group-modal.component.scss => entities/edit-entity-modal.component.scss} (100%) rename ui/main/src/app/modules/admin/components/editmodal/{groups-entities/edit-entity-group-modal.component.ts => entities/edit-entity-modal.component.ts} (76%) create mode 100644 ui/main/src/app/modules/admin/components/editmodal/groups/edit-group-modal.component.html create mode 100644 ui/main/src/app/modules/admin/components/editmodal/groups/edit-group-modal.component.scss create mode 100644 ui/main/src/app/modules/admin/components/editmodal/groups/edit-group-modal.component.ts create mode 100644 ui/main/src/app/modules/admin/components/editmodal/perimeters/edit-perimeter-modal.component.html create mode 100644 ui/main/src/app/modules/admin/components/editmodal/perimeters/edit-perimeter-modal.component.scss create mode 100644 ui/main/src/app/modules/admin/components/editmodal/perimeters/edit-perimeter-modal.component.ts create mode 100644 ui/main/src/app/modules/admin/components/table/perimeters-table.component.ts create mode 100644 ui/main/src/app/services/perimeters.service.ts diff --git a/ui/main/src/app/common/utilities.ts b/ui/main/src/app/common/utilities.ts new file mode 100644 index 0000000000..0745cd90ba --- /dev/null +++ b/ui/main/src/app/common/utilities.ts @@ -0,0 +1,19 @@ +/* Copyright (c) 2021, RTE (http://www.rte-france.com) + * See AUTHORS.txt + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + * This file is part of the OperatorFabric project. + */ + +import {Process} from '@ofModel/processes.model'; + +export abstract class Utilities { + + public static getI18nPrefixFromProcess (process: Process): string { + return process.id + '.' + process.version + '.'; + } + +} + diff --git a/ui/main/src/app/model/perimeter.model.ts b/ui/main/src/app/model/perimeter.model.ts new file mode 100644 index 0000000000..e9a8f9006b --- /dev/null +++ b/ui/main/src/app/model/perimeter.model.ts @@ -0,0 +1,31 @@ +/* Copyright (c) 2021, RTE (http://www.rte-france.com) + * See AUTHORS.txt + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + * This file is part of the OperatorFabric project. + */ + +export class Perimeter { + public constructor( + readonly id: string, + readonly process: string, + readonly stateRights: Array, + ) { + } + +} + +export class StateRight { + + constructor( + readonly state: string, + readonly right: RightsEnum + ) { + } +} + +export enum RightsEnum { + Write = 'Write', ReceiveAndWrite = 'ReceiveAndWrite', Receive = 'Receive' +} diff --git a/ui/main/src/app/model/processes.model.ts b/ui/main/src/app/model/processes.model.ts index 39fbaed59a..620d989149 100644 --- a/ui/main/src/app/model/processes.model.ts +++ b/ui/main/src/app/model/processes.model.ts @@ -31,11 +31,8 @@ export class Process { return null; } } -} - -export const unfouundProcess: Process = new Process('', '', 'process.not-found', - [], null, null); +} export class UiVisibility { @@ -87,12 +84,10 @@ export class Response { export enum AcknowledgmentAllowedEnum { ALWAYS = 'Always', - NEVER = 'Never', + NEVER = 'Never', ONLY_WHEN_RESPONSE_DISABLED_FOR_USER = 'OnlyWhenResponseDisabledForUser' } -type Omit = Pick>; - export enum InputType { TEXT, LIST, diff --git a/ui/main/src/app/model/userWithPerimeters.model.ts b/ui/main/src/app/model/userWithPerimeters.model.ts index 9c801c8a9e..d2224328b5 100644 --- a/ui/main/src/app/model/userWithPerimeters.model.ts +++ b/ui/main/src/app/model/userWithPerimeters.model.ts @@ -7,7 +7,8 @@ * This file is part of the OperatorFabric project. */ -import { User } from '@ofModel/user.model'; +import {User} from '@ofModel/user.model'; +import {RightsEnum} from '@ofModel/perimeter.model'; export class UserWithPerimeters { @@ -30,11 +31,6 @@ export class ComputedPerimeter { } -export enum RightsEnum { - Write = 'Write', ReceiveAndWrite = 'ReceiveAndWrite', Receive = 'Receive' -} - - export function userRight(rights: RightsEnum) { let result; switch (rights) { diff --git a/ui/main/src/app/modules/admin/admin-routing.module.ts b/ui/main/src/app/modules/admin/admin-routing.module.ts index 0c1a443ef3..41e156e090 100644 --- a/ui/main/src/app/modules/admin/admin-routing.module.ts +++ b/ui/main/src/app/modules/admin/admin-routing.module.ts @@ -14,6 +14,7 @@ import {AdminComponent} from './admin.component'; import {UsersTableComponent} from './components/table/users-table.component'; import {GroupsTableComponent} from './components/table/groups-table.component'; import {EntitiesTableComponent} from './components/table/entities-table.component'; +import {PerimetersTableComponent} from './components/table/perimeters-table.component'; const defaultPath = 'users'; @@ -34,6 +35,10 @@ const routes: Routes = [ path: 'groups', component: GroupsTableComponent }, + { + path: 'perimeters', + component: PerimetersTableComponent + }, { path: '**', redirectTo: defaultPath } diff --git a/ui/main/src/app/modules/admin/admin.component.html b/ui/main/src/app/modules/admin/admin.component.html index d123337ffa..ab53633743 100644 --- a/ui/main/src/app/modules/admin/admin.component.html +++ b/ui/main/src/app/modules/admin/admin.component.html @@ -20,6 +20,9 @@ +
diff --git a/ui/main/src/app/modules/admin/admin.module.ts b/ui/main/src/app/modules/admin/admin.module.ts index 6aad6ba628..3f2d620929 100644 --- a/ui/main/src/app/modules/admin/admin.module.ts +++ b/ui/main/src/app/modules/admin/admin.module.ts @@ -17,18 +17,25 @@ import {AdminRoutingModule} from './admin-routing.module'; import {TranslateModule} from '@ngx-translate/core'; import {AppErrorHandler} from 'app/common/error/app-error-handler'; import {ConfirmationDialogComponent} from './components/confirmation-dialog/confirmation-dialog.component'; -import {EditEntityGroupModalComponent} from './components/editmodal/groups-entities/edit-entity-group-modal.component'; import {UsersTableComponent} from './components/table/users-table.component'; import {EditUserModalComponent} from './components/editmodal/users/edit-user-modal.component'; import {EntitiesTableComponent} from './components/table/entities-table.component'; import {GroupsTableComponent} from './components/table/groups-table.component'; import {AgGridModule} from 'ag-grid-angular'; import {MultiFilterModule} from '../share/multi-filter/multi-filter.module'; -import {ArrayCellRendererComponent} from './components/table/array-cell-renderer.component'; -import {ActionCellRendererComponent} from './components/table/action-cell-renderer.component'; -import {GroupCellRendererComponent} from './components/table/group-cell-renderer.component'; -import {EntityCellRendererComponent} from './components/table/entity-cell-renderer.component'; +import {ArrayCellRendererComponent} from './components/cell-renderers/array-cell-renderer.component'; +import {ActionCellRendererComponent} from './components/cell-renderers/action-cell-renderer.component'; +import {GroupCellRendererComponent} from './components/cell-renderers/group-cell-renderer.component'; +import {EntityCellRendererComponent} from './components/cell-renderers/entity-cell-renderer.component'; import {SharingService} from './services/sharing.service'; +import {PerimetersTableComponent} from './components/table/perimeters-table.component'; +import {StateRightsCellRendererComponent} from './components/cell-renderers/state-rights-cell-renderer.component'; +import {EditEntityModalComponent} from './components/editmodal/entities/edit-entity-modal.component'; +import {EditGroupModalComponent} from './components/editmodal/groups/edit-group-modal.component'; +import {EditPerimeterModalComponent} from './components/editmodal/perimeters/edit-perimeter-modal.component'; +import {SingleFilterModule} from '../share/single-filter/single-filter.module'; +import {ProcessCellRendererComponent} from './components/cell-renderers/process-cell-renderer.component'; +import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; @NgModule({ declarations: [ @@ -36,13 +43,18 @@ import {SharingService} from './services/sharing.service'; UsersTableComponent, EntitiesTableComponent, GroupsTableComponent, + PerimetersTableComponent, EditUserModalComponent, ConfirmationDialogComponent, - EditEntityGroupModalComponent, + EditEntityModalComponent, + EditGroupModalComponent, + EditPerimeterModalComponent, ActionCellRendererComponent, ArrayCellRendererComponent, GroupCellRendererComponent, - EntityCellRendererComponent + EntityCellRendererComponent, + ProcessCellRendererComponent, + StateRightsCellRendererComponent ], @@ -54,12 +66,15 @@ import {SharingService} from './services/sharing.service'; , CommonModule , MultiFilterModule , TranslateModule + , NgbModule , AgGridModule.withComponents([[ ActionCellRendererComponent, ArrayCellRendererComponent, GroupCellRendererComponent, - EntityCellRendererComponent - ]]) + EntityCellRendererComponent, + ProcessCellRendererComponent, + StateRightsCellRendererComponent + ]]), SingleFilterModule ], providers: [ { provide: ErrorHandler, useClass: AppErrorHandler }, diff --git a/ui/main/src/app/modules/admin/components/table/action-cell-renderer.component.html b/ui/main/src/app/modules/admin/components/cell-renderers/action-cell-renderer.component.html similarity index 100% rename from ui/main/src/app/modules/admin/components/table/action-cell-renderer.component.html rename to ui/main/src/app/modules/admin/components/cell-renderers/action-cell-renderer.component.html diff --git a/ui/main/src/app/modules/admin/components/table/action-cell-renderer.component.ts b/ui/main/src/app/modules/admin/components/cell-renderers/action-cell-renderer.component.ts similarity index 96% rename from ui/main/src/app/modules/admin/components/table/action-cell-renderer.component.ts rename to ui/main/src/app/modules/admin/components/cell-renderers/action-cell-renderer.component.ts index b8ac94b7eb..eabe581700 100644 --- a/ui/main/src/app/modules/admin/components/table/action-cell-renderer.component.ts +++ b/ui/main/src/app/modules/admin/components/cell-renderers/action-cell-renderer.component.ts @@ -14,7 +14,7 @@ import {ICellRendererParams} from 'ag-grid-community'; @Component({ selector: 'of-action-cell-renderer', - templateUrl: 'action-cell-renderer.component.html', + templateUrl: './action-cell-renderer.component.html', }) export class ActionCellRendererComponent implements ICellRendererAngularComp { diff --git a/ui/main/src/app/modules/admin/components/table/array-cell-renderer.component.html b/ui/main/src/app/modules/admin/components/cell-renderers/array-cell-renderer.component.html similarity index 100% rename from ui/main/src/app/modules/admin/components/table/array-cell-renderer.component.html rename to ui/main/src/app/modules/admin/components/cell-renderers/array-cell-renderer.component.html diff --git a/ui/main/src/app/modules/admin/components/table/array-cell-renderer.component.ts b/ui/main/src/app/modules/admin/components/cell-renderers/array-cell-renderer.component.ts similarity index 100% rename from ui/main/src/app/modules/admin/components/table/array-cell-renderer.component.ts rename to ui/main/src/app/modules/admin/components/cell-renderers/array-cell-renderer.component.ts diff --git a/ui/main/src/app/modules/admin/components/table/entity-cell-renderer.component.ts b/ui/main/src/app/modules/admin/components/cell-renderers/entity-cell-renderer.component.ts similarity index 94% rename from ui/main/src/app/modules/admin/components/table/entity-cell-renderer.component.ts rename to ui/main/src/app/modules/admin/components/cell-renderers/entity-cell-renderer.component.ts index d11924bb7b..aa3c91b922 100644 --- a/ui/main/src/app/modules/admin/components/table/entity-cell-renderer.component.ts +++ b/ui/main/src/app/modules/admin/components/cell-renderers/entity-cell-renderer.component.ts @@ -14,7 +14,7 @@ import {AdminItemType} from '../../services/sharing.service'; @Component({ selector: 'of-entity-cell-renderer', - templateUrl: 'array-cell-renderer.component.html' + templateUrl: './array-cell-renderer.component.html' }) export class EntityCellRendererComponent extends ArrayCellRendererComponent { diff --git a/ui/main/src/app/modules/admin/components/table/group-cell-renderer.component.ts b/ui/main/src/app/modules/admin/components/cell-renderers/group-cell-renderer.component.ts similarity index 94% rename from ui/main/src/app/modules/admin/components/table/group-cell-renderer.component.ts rename to ui/main/src/app/modules/admin/components/cell-renderers/group-cell-renderer.component.ts index eea8b0df2c..07b937cf2e 100644 --- a/ui/main/src/app/modules/admin/components/table/group-cell-renderer.component.ts +++ b/ui/main/src/app/modules/admin/components/cell-renderers/group-cell-renderer.component.ts @@ -13,7 +13,7 @@ import {AdminItemType} from '../../services/sharing.service'; @Component({ selector: 'of-group-cell-renderer', - templateUrl: 'array-cell-renderer.component.html', + templateUrl: './array-cell-renderer.component.html', }) export class GroupCellRendererComponent extends ArrayCellRendererComponent { diff --git a/ui/main/src/app/modules/admin/components/cell-renderers/process-cell-renderer.component.ts b/ui/main/src/app/modules/admin/components/cell-renderers/process-cell-renderer.component.ts new file mode 100644 index 0000000000..ecc5b9c803 --- /dev/null +++ b/ui/main/src/app/modules/admin/components/cell-renderers/process-cell-renderer.component.ts @@ -0,0 +1,25 @@ +/* Copyright (c) 2021, RTE (http://www.rte-france.com) + * See AUTHORS.txt + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + * This file is part of the OperatorFabric project. + */ + +import {Component} from '@angular/core'; +import {ArrayCellRendererComponent} from './array-cell-renderer.component'; +import {AdminItemType} from '../../services/sharing.service'; + +@Component({ + selector: 'of-process-cell-renderer', + templateUrl: './array-cell-renderer.component.html', +}) +export class ProcessCellRendererComponent extends ArrayCellRendererComponent { + + /** Defining components extending ArrayCellComponent proved necessary rather than using generics or passing the type as a + * constructor parameter because ag-grid only accepts non-generic class names in column definitions. + * */ + + itemType = AdminItemType.GROUP; +} diff --git a/ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.html b/ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.html new file mode 100644 index 0000000000..fbf7fde7ea --- /dev/null +++ b/ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.html @@ -0,0 +1,18 @@ + + + + + + + + + + {{stateRight.state}} + + + + + diff --git a/ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.scss b/ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.scss new file mode 100644 index 0000000000..145898e526 --- /dev/null +++ b/ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.scss @@ -0,0 +1,21 @@ +/* Copyright (c) 2021, RTE (http://www.rte-france.com) + * See AUTHORS.txt + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + * This file is part of the OperatorFabric project. + */ + +@import "~assets/styles/_variables.scss"; + +/* import bootstrap*/ +@import '../../../../../../node_modules/bootstrap/scss/bootstrap.scss'; + +.opfab-bg-right-receive {background-color: $gray-500;} +.opfab-bg-right-receiveandwrite {background-color: $blue;} +.opfab-bg-right-write {background-color: lighten($blue,30);} + +.badge { + color: $dark; +} diff --git a/ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.ts b/ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.ts new file mode 100644 index 0000000000..c8e0a93697 --- /dev/null +++ b/ui/main/src/app/modules/admin/components/cell-renderers/state-rights-cell-renderer.component.ts @@ -0,0 +1,48 @@ +/* Copyright (c) 2021, RTE (http://www.rte-france.com) + * See AUTHORS.txt + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + * This file is part of the OperatorFabric project. + */ + + +import {Component} from '@angular/core'; +import {ICellRendererAngularComp} from 'ag-grid-angular'; +import {ICellRendererParams} from 'ag-grid-community'; +import {StateRight} from '@ofModel/perimeter.model'; + +@Component({ + selector: 'of-state-rights-cell-renderer', + templateUrl: './state-rights-cell-renderer.component.html', + styleUrls: ['./state-rights-cell-renderer.component.scss'] +}) +export class StateRightsCellRendererComponent implements ICellRendererAngularComp { + + constructor() { + } + + // For explanations regarding ag-grid CellRenderers see + // https://www.ag-grid.com/documentation/angular/component-cell-renderer/#example-rendering-using-angular-components + private _stateRightsValues: StateRight[]; + + + agInit(params: any): void { + + this._stateRightsValues = params.getValue(); + + } + + /** This method returns true to signal to the grid that this renderer doesn't need to be recreated if the underlying data changes + * See https://www.ag-grid.com/documentation/angular/component-cell-renderer/#handling-refresh + * */ + refresh(params: ICellRendererParams): boolean { + return true; + } + + get stateRightsValues(): StateRight[] { + return this._stateRightsValues; + } + +} diff --git a/ui/main/src/app/modules/admin/components/editmodal/groups-entities/edit-entity-group-modal.component.html b/ui/main/src/app/modules/admin/components/editmodal/entities/edit-entity-modal.component.html similarity index 68% rename from ui/main/src/app/modules/admin/components/editmodal/groups-entities/edit-entity-group-modal.component.html rename to ui/main/src/app/modules/admin/components/editmodal/entities/edit-entity-modal.component.html index a455c7024b..cd3dc7b6be 100644 --- a/ui/main/src/app/modules/admin/components/editmodal/groups-entities/edit-entity-group-modal.component.html +++ b/ui/main/src/app/modules/admin/components/editmodal/entities/edit-entity-modal.component.html @@ -10,14 +10,13 @@