now using generic domains/ did refactors of import/export
TSK-426 fixed test issues
This commit is contained in:
Lars Leo Grätz 2018-03-29 12:14:54 +02:00 committed by Martin Rojas Miguel Angel
parent df4638f2fc
commit a311a60301
24 changed files with 286 additions and 276 deletions

View File

@ -1,8 +1,5 @@
package pro.taskana.rest; package pro.taskana.rest;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -16,10 +13,7 @@ import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import pro.taskana.BaseQuery;
import pro.taskana.Classification; import pro.taskana.Classification;
import pro.taskana.ClassificationQuery;
import pro.taskana.ClassificationService; import pro.taskana.ClassificationService;
import pro.taskana.ClassificationSummary; import pro.taskana.ClassificationSummary;
import pro.taskana.exceptions.ClassificationAlreadyExistException; import pro.taskana.exceptions.ClassificationAlreadyExistException;
@ -31,6 +25,8 @@ import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.rest.resource.ClassificationResource; import pro.taskana.rest.resource.ClassificationResource;
import pro.taskana.rest.resource.mapper.ClassificationMapper; import pro.taskana.rest.resource.mapper.ClassificationMapper;
import java.util.List;
/** /**
* Controller for all {@link Classification} related endpoints. * Controller for all {@link Classification} related endpoints.
*/ */
@ -74,15 +70,6 @@ public class ClassificationController {
return ResponseEntity.status(HttpStatus.OK).body(classificationMapper.toResource(classification)); return ResponseEntity.status(HttpStatus.OK).body(classificationMapper.toResource(classification));
} }
@GetMapping(path = "/domains")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<List<String>> getDomains() {
List<String> domains = new ArrayList<>();
ClassificationQuery classificationQuery = classificationService.createClassificationQuery();
domains = classificationQuery.listValues("DOMAIN", BaseQuery.SortDirection.ASCENDING);
return new ResponseEntity<>(domains, HttpStatus.OK);
}
@PostMapping @PostMapping
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ResponseEntity<ClassificationResource> createClassification( public ResponseEntity<ClassificationResource> createClassification(

View File

@ -1,10 +1,5 @@
package pro.taskana.rest; package pro.taskana.rest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -17,7 +12,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import pro.taskana.Classification; import pro.taskana.Classification;
import pro.taskana.ClassificationQuery; import pro.taskana.ClassificationQuery;
import pro.taskana.ClassificationService; import pro.taskana.ClassificationService;
@ -31,6 +25,11 @@ import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.rest.resource.ClassificationResource; import pro.taskana.rest.resource.ClassificationResource;
import pro.taskana.rest.resource.mapper.ClassificationMapper; import pro.taskana.rest.resource.mapper.ClassificationMapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* Controller for Importing / Exporting classifications. * Controller for Importing / Exporting classifications.
*/ */
@ -68,11 +67,11 @@ public class ClassificationDefinitionController {
Map<String, String> systemIds = classificationService.createClassificationQuery() Map<String, String> systemIds = classificationService.createClassificationQuery()
.list() .list()
.stream() .stream()
.collect(Collectors.toMap(i -> i.getKey() + "|||" + i.getDomain(), ClassificationSummary::getId)); .collect(Collectors.toMap(i -> i.getKey() + "|" + i.getDomain(), ClassificationSummary::getId));
try { try {
for (ClassificationResource classificationResource : classificationResources) { for (ClassificationResource classificationResource : classificationResources) {
if (systemIds.containsKey(classificationResource.key + "|||" + classificationResource.domain)) { if (systemIds.containsKey(classificationResource.key + "|" + classificationResource.domain)) {
classificationService.updateClassification(classificationMapper.toModel(classificationResource)); classificationService.updateClassification(classificationMapper.toModel(classificationResource));
} else { } else {

View File

@ -0,0 +1,25 @@
package pro.taskana.rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import java.util.List;
/**
* Controller for TaskanaEngine related tasks.
*/
@RestController
public class TaskanaEngineController {
@Autowired TaskanaEngineConfiguration taskanaEngineConfiguration;
@GetMapping(path = "/v1/domains", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<List<String>> getDomains() {
return new ResponseEntity<>(taskanaEngineConfiguration.getDomains(), HttpStatus.OK);
}
}

View File

@ -1,9 +1,5 @@
package pro.taskana.rest; package pro.taskana.rest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.PagedResources.PageMetadata; import org.springframework.hateoas.PagedResources.PageMetadata;
@ -22,7 +18,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import pro.taskana.BaseQuery; import pro.taskana.BaseQuery;
import pro.taskana.Workbasket; import pro.taskana.Workbasket;
import pro.taskana.WorkbasketAccessItem; import pro.taskana.WorkbasketAccessItem;
@ -48,6 +43,10 @@ import pro.taskana.rest.resource.mapper.WorkbasketAccessItemMapper;
import pro.taskana.rest.resource.mapper.WorkbasketMapper; import pro.taskana.rest.resource.mapper.WorkbasketMapper;
import pro.taskana.rest.resource.mapper.WorkbasketSummaryResourcesAssembler; import pro.taskana.rest.resource.mapper.WorkbasketSummaryResourcesAssembler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
* Controller for all {@link Workbasket} related endpoints. * Controller for all {@link Workbasket} related endpoints.
*/ */
@ -188,15 +187,6 @@ public class WorkbasketController extends AbstractPagingController {
return result; return result;
} }
@GetMapping(path = "/domains")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<List<String>> getDomains() {
List<String> domains = new ArrayList<>();
WorkbasketQuery workbasketQuery = workbasketService.createWorkbasketQuery();
domains = workbasketQuery.listValues("DOMAIN", BaseQuery.SortDirection.ASCENDING);
return new ResponseEntity<>(domains, HttpStatus.OK);
}
@PutMapping(value = "/{workbasketId}/workbasketAccessItems") @PutMapping(value = "/{workbasketId}/workbasketAccessItems")
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ResponseEntity<Resources<WorkbasketAccessItemResource>> setWorkbasketAccessItems( public ResponseEntity<Resources<WorkbasketAccessItemResource>> setWorkbasketAccessItems(

View File

@ -1,11 +1,5 @@
package pro.taskana.rest; package pro.taskana.rest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -18,7 +12,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import pro.taskana.Workbasket; import pro.taskana.Workbasket;
import pro.taskana.WorkbasketAccessItem; import pro.taskana.WorkbasketAccessItem;
import pro.taskana.WorkbasketQuery; import pro.taskana.WorkbasketQuery;
@ -37,6 +30,12 @@ import pro.taskana.rest.resource.mapper.WorkbasketAccessItemMapper;
import pro.taskana.rest.resource.mapper.WorkbasketDefinitionMapper; import pro.taskana.rest.resource.mapper.WorkbasketDefinitionMapper;
import pro.taskana.rest.resource.mapper.WorkbasketMapper; import pro.taskana.rest.resource.mapper.WorkbasketMapper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* Controller for all {@link WorkbasketDefinition} related endpoints. * Controller for all {@link WorkbasketDefinition} related endpoints.
*/ */
@ -181,6 +180,6 @@ public class WorkbasketDefinitionController {
} }
private String logicalId(String key, String domain) { private String logicalId(String key, String domain) {
return key + "|||" + domain; return key + "|" + domain;
} }
} }

View File

@ -3,7 +3,7 @@
<li id="cl-action-toolbar" class="list-group-item tab-align"> <li id="cl-action-toolbar" class="list-group-item tab-align">
<div class="row"> <div class="row">
<div class="col-xs-9"> <div class="col-xs-9">
<taskana-import-export-component [currentSelection]="'classifications'"></taskana-import-export-component> <taskana-import-export-component [currentSelection]="selectionToImport"></taskana-import-export-component>
</div> </div>
</div> </div>
</li> </li>

View File

@ -1,6 +1,6 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { ClassificationListComponent } from './classification-list.component'; import {ClassificationListComponent} from './classification-list.component';
import {ImportExportComponent} from '../../../import-export/import-export.component'; import {ImportExportComponent} from '../../../import-export/import-export.component';
import {SpinnerComponent} from '../../../../shared/spinner/spinner.component'; import {SpinnerComponent} from '../../../../shared/spinner/spinner.component';
import {WorkbasketService} from '../../../../services/workbasket/workbasket.service'; import {WorkbasketService} from '../../../../services/workbasket/workbasket.service';
@ -8,6 +8,7 @@ import {HttpClient, HttpClientModule} from '@angular/common/http';
import {WorkbasketDefinitionService} from '../../../../services/workbasket/workbasketDefinition.service'; import {WorkbasketDefinitionService} from '../../../../services/workbasket/workbasketDefinition.service';
import {AlertService} from '../../../../services/alert/alert.service'; import {AlertService} from '../../../../services/alert/alert.service';
import {ClassificationService} from '../../../../services/classification/classification.service'; import {ClassificationService} from '../../../../services/classification/classification.service';
import {DomainService} from '../../../../services/domains/domain.service';
describe('ClassificationListComponent', () => { describe('ClassificationListComponent', () => {
let component: ClassificationListComponent; let component: ClassificationListComponent;
@ -15,11 +16,13 @@ describe('ClassificationListComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ ClassificationListComponent, ImportExportComponent, SpinnerComponent], declarations: [ClassificationListComponent, ImportExportComponent, SpinnerComponent],
imports: [HttpClientModule], imports: [HttpClientModule],
providers: [WorkbasketService, HttpClient, WorkbasketDefinitionService, AlertService, ClassificationService] providers: [
WorkbasketService, HttpClient, WorkbasketDefinitionService, AlertService, ClassificationService, DomainService
]
}) })
.compileComponents(); .compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {

View File

@ -1,4 +1,5 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {SelectionToImport} from '../../../enums/SelectionToImport';
@Component({ @Component({
selector: 'taskana-classification-list', selector: 'taskana-classification-list',
@ -7,6 +8,7 @@ import {Component, OnInit} from '@angular/core';
}) })
export class ClassificationListComponent implements OnInit { export class ClassificationListComponent implements OnInit {
selectionToImport = SelectionToImport.CLASSIFICATIONS;
requestInProgress = false; requestInProgress = false;
constructor() { constructor() {

View File

@ -0,0 +1,4 @@
export enum SelectionToImport {
WORKBASKETS,
CLASSIFICATIONS
}

View File

@ -1,6 +1,7 @@
<!-- TODO: fix position of import button -->
<input #selectedFile type="file" (change)="onSelectFile($event)" <input #selectedFile type="file" (change)="onSelectFile($event)"
style="position:absolute;display:none;"/> class="hide"/>
<button class="btn btn-default glyphicon glyphicon-upload" type="button" title="Import" style="top: -0.5px;" <button class="btn btn-default glyphicon glyphicon-upload" type="button" title="Import"
(click)="selectedFile.click()"></button> (click)="selectedFile.click()"></button>
<div class="dropdown" style="display: inline"> <div class="dropdown" style="display: inline">
@ -12,12 +13,12 @@
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li> <li>
<a class="dropdown-item" (click)="exportAll()"><label>All Domains</label></a> <a class="dropdown-item" (click)="export()"><label>All Domains</label></a>
</li> </li>
<div role="separator" class="divider"></div> <div role="separator" class="divider"></div>
<li *ngFor="let domain of (this.currentSelection === 'workbaskets' ? workbasketDomains : classificationDomains)"> <li *ngFor="let domain of domains">
<a class="dropdown-item" <a class="dropdown-item"
(click)="exportByDomain(domain)"><label>{{domain === '' ? 'Master' : domain}}</label></a> (click)="export(domain)"><label>{{domain === '' ? 'Master' : domain}}</label></a>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -0,0 +1,3 @@
.hide {
display: none;
}

View File

@ -1,32 +1,47 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { ImportExportComponent } from './import-export.component'; import {ImportExportComponent} from './import-export.component';
import {WorkbasketService} from '../../services/workbasket/workbasket.service'; import {WorkbasketService} from '../../services/workbasket/workbasket.service';
import {ClassificationService} from '../../services/classification/classification.service'; import {ClassificationService} from '../../services/classification/classification.service';
import {WorkbasketDefinitionService} from '../../services/workbasket/workbasketDefinition.service'; import {WorkbasketDefinitionService} from '../../services/workbasket/workbasketDefinition.service';
import {AlertService} from '../../services/alert/alert.service'; import {AlertService} from '../../services/alert/alert.service';
import {HttpClient, HttpClientModule} from '@angular/common/http'; import {HttpClientModule} from '@angular/common/http';
import {DomainService} from '../../services/domains/domain.service';
describe('ImportExportComponent', () => { describe('ImportExportComponent', () => {
let component: ImportExportComponent; let component: ImportExportComponent;
let fixture: ComponentFixture<ImportExportComponent>; let fixture: ComponentFixture<ImportExportComponent>;
let domainService;
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ ImportExportComponent], declarations: [ImportExportComponent],
imports: [HttpClientModule], imports: [HttpClientModule],
providers: [WorkbasketService, ClassificationService, WorkbasketDefinitionService, AlertService] providers: [WorkbasketService, ClassificationService, WorkbasketDefinitionService, AlertService, DomainService]
}) })
.compileComponents(); .compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(ImportExportComponent); fixture = TestBed.createComponent(ImportExportComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
domainService = TestBed.get(DomainService);
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
// TODO add tests for inport/export
/*
it('should update domains', () => {
let domains = [];
domainService.getDomains().subscribe(
result => domains = result
);
component.updateDomains();
expect(component.domains).toEqual(domains);
})
*/
}); });

View File

@ -1,9 +1,8 @@
import {Component, Input, OnInit} from '@angular/core'; import {Component, Input, OnInit} from '@angular/core';
import {HttpClient} from '@angular/common/http'; import {ClassificationService} from 'app/services/classification/classification.service';
import {ActivatedRoute, Router} from '@angular/router'; import {WorkbasketDefinitionService} from 'app/services/workbasket/workbasketDefinition.service';
import {WorkbasketService} from '../../services/workbasket/workbasket.service'; import {DomainService} from '../../services/domains/domain.service';
import {ClassificationService} from '../../services/classification/classification.service'; import {SelectionToImport} from '../enums/SelectionToImport';
import {WorkbasketDefinitionService} from '../../services/workbasket/workbasketDefinition.service';
@Component({ @Component({
selector: 'taskana-import-export-component', selector: 'taskana-import-export-component',
@ -12,11 +11,10 @@ import {WorkbasketDefinitionService} from '../../services/workbasket/workbasketD
}) })
export class ImportExportComponent implements OnInit { export class ImportExportComponent implements OnInit {
@Input() currentSelection: string; @Input() currentSelection: SelectionToImport;
workbasketDomains: string[]; domains: string[] = [];
classificationDomains: string[];
constructor(private workbasketService: WorkbasketService, private workbasketDefinitionService: WorkbasketDefinitionService, constructor(private domainService: DomainService, private workbasketDefinitionService: WorkbasketDefinitionService,
private classificationService: ClassificationService) { private classificationService: ClassificationService) {
} }
@ -24,18 +22,15 @@ export class ImportExportComponent implements OnInit {
} }
updateDomains() { updateDomains() {
this.workbasketService.getWorkbasketDomains().subscribe( this.domainService.getDomains().subscribe(
data => this.workbasketDomains = data data => this.domains = data
);
this.classificationService.getClassificationDomains().subscribe(
data => this.classificationDomains = data
); );
} }
onSelectFile(event) { onSelectFile(event) {
const file = event.srcElement.files[0]; const file = event.srcElement.files[0];
const reader = new FileReader(); const reader = new FileReader();
if (this.currentSelection === 'workbaskets') { if (this.currentSelection === SelectionToImport.WORKBASKETS) {
reader.onload = <Event>(e) => this.workbasketDefinitionService.importWorkbasketDefinitions(e.target.result); reader.onload = <Event>(e) => this.workbasketDefinitionService.importWorkbasketDefinitions(e.target.result);
} else { } else {
reader.onload = <Event>(e) => this.classificationService.importClassifications(e.target.result); reader.onload = <Event>(e) => this.classificationService.importClassifications(e.target.result);
@ -43,19 +38,11 @@ export class ImportExportComponent implements OnInit {
reader.readAsText(file); reader.readAsText(file);
} }
exportAll() { export(domain = '') {
if (this.currentSelection === 'workbaskets') { if (this.currentSelection === SelectionToImport.WORKBASKETS) {
this.workbasketDefinitionService.exportAllWorkbaskets(); this.workbasketDefinitionService.exportWorkbaskets(domain);
} else { } else {
this.classificationService.exportAllClassifications(); this.classificationService.exportClassifications(domain);
}
}
exportByDomain(domain: string) {
if (this.currentSelection === 'workbaskets') {
this.workbasketDefinitionService.exportWorkbasketsByDomain(domain);
} else {
this.classificationService.exportClassificationsByDomain(domain);
} }
} }
} }

View File

@ -1,6 +1,7 @@
<li id="wb-action-toolbar" class="list-group-item tab-align"> <li id="wb-action-toolbar" class="list-group-item tab-align">
<div class="row"> <div class="row">
<div class="col-xs-9"> <div class="col-xs-9">
<taskana-import-export-component [currentSelection]="selectionToImport"></taskana-import-export-component>
<button type="button" (click)="addWorkbasket()" data-toggle="tooltip" title="Add" class="btn btn-default"> <button type="button" (click)="addWorkbasket()" data-toggle="tooltip" title="Add" class="btn btn-default">
<span class="glyphicon glyphicon-plus green" aria-hidden="true"></span> <span class="glyphicon glyphicon-plus green" aria-hidden="true"></span>
</button> </button>

View File

@ -28,6 +28,7 @@ import { AlertService } from 'app/services/alert/alert.service';
import {ImportExportComponent} from '../../../../import-export/import-export.component'; import {ImportExportComponent} from '../../../../import-export/import-export.component';
import {ClassificationService} from '../../../../../services/classification/classification.service'; import {ClassificationService} from '../../../../../services/classification/classification.service';
import {WorkbasketDefinitionService} from '../../../../../services/workbasket/workbasketDefinition.service'; import {WorkbasketDefinitionService} from '../../../../../services/workbasket/workbasketDefinition.service';
import {DomainService} from '../../../../../services/domains/domain.service';
@Component({ @Component({
selector: 'taskana-dummy-detail', selector: 'taskana-dummy-detail',
@ -53,7 +54,7 @@ describe('WorkbasketListToolbarComponent', () => {
declarations: [WorkbasketListToolbarComponent, SortComponent, declarations: [WorkbasketListToolbarComponent, SortComponent,
FilterComponent, IconTypeComponent, DummyDetailComponent, MapValuesPipe, ImportExportComponent], FilterComponent, IconTypeComponent, DummyDetailComponent, MapValuesPipe, ImportExportComponent],
providers: [ErrorModalService, WorkbasketService, RequestInProgressService, AlertService, providers: [ErrorModalService, WorkbasketService, RequestInProgressService, AlertService,
ClassificationService, WorkbasketDefinitionService] ClassificationService, WorkbasketDefinitionService, DomainService]
}) })
.compileComponents(); .compileComponents();
})); }));

View File

@ -2,17 +2,18 @@ import { Component, OnInit, Input, Output, EventEmitter, AfterViewChecked } from
import { trigger, state, style, transition, animate, keyframes } from '@angular/animations'; import { trigger, state, style, transition, animate, keyframes } from '@angular/animations';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { SortingModel } from 'app/models/sorting'; import {SortingModel} from 'app/models/sorting';
import { FilterModel } from 'app/models/filter'; import {FilterModel} from 'app/models/filter';
import { Subscription } from 'rxjs/Subscription'; import {Subscription} from 'rxjs/Subscription';
import { WorkbasketSummary } from 'app/models/workbasket-summary'; import {WorkbasketSummary} from 'app/models/workbasket-summary';
import { ErrorModel } from 'app/models/modal-error'; import {ErrorModel} from 'app/models/modal-error';
import { AlertModel, AlertType } from 'app/models/alert'; import {AlertModel, AlertType} from 'app/models/alert';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import {ErrorModalService} from 'app/services/errorModal/error-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import {RequestInProgressService} from 'app/services/requestInProgress/request-in-progress.service';
import { WorkbasketService } from 'app/services/workbasket/workbasket.service'; import {WorkbasketService} from 'app/services/workbasket/workbasket.service';
import { AlertService } from 'app/services/alert/alert.service'; import {AlertService} from 'app/services/alert/alert.service';
import {SelectionToImport} from '../../../../enums/SelectionToImport';
@Component({ @Component({
selector: 'taskana-workbasket-list-toolbar', selector: 'taskana-workbasket-list-toolbar',
@ -42,6 +43,7 @@ export class WorkbasketListToolbarComponent implements OnInit {
@Output() performSorting = new EventEmitter<SortingModel>(); @Output() performSorting = new EventEmitter<SortingModel>();
@Output() performFilter = new EventEmitter<FilterModel>(); @Output() performFilter = new EventEmitter<FilterModel>();
workbasketServiceSubscription: Subscription; workbasketServiceSubscription: Subscription;
selectionToImport = SelectionToImport.WORKBASKETS;
toolbarState = false; toolbarState = false;
constructor( constructor(

View File

@ -5,11 +5,10 @@ import { Observable } from 'rxjs/Observable';
import { AngularSvgIconModule } from 'angular-svg-icon'; import { AngularSvgIconModule } from 'angular-svg-icon';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { HttpModule } from '@angular/http'; import { HttpModule } from '@angular/http';
import { Router, Routes } from '@angular/router'; import { Routes } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { WorkbasketSummary } from 'app/models/workbasket-summary'; import { WorkbasketSummary } from 'app/models/workbasket-summary';
import { Links } from 'app/models/links';
import { WorkbasketSummaryResource } from 'app/models/workbasket-summary-resource'; import { WorkbasketSummaryResource } from 'app/models/workbasket-summary-resource';
import { FilterModel } from 'app/models/filter'; import { FilterModel } from 'app/models/filter';
import { LinksWorkbasketSummary } from 'app/models/links-workbasket-summary'; import { LinksWorkbasketSummary } from 'app/models/links-workbasket-summary';
@ -31,6 +30,7 @@ import { RemoveNoneTypePipe } from 'app/pipes/removeNoneType/remove-none-type.pi
import { MapValuesPipe } from 'app/pipes/mapValues/map-values.pipe'; import { MapValuesPipe } from 'app/pipes/mapValues/map-values.pipe';
import { ClassificationService } from '../../../../services/classification/classification.service'; import { ClassificationService } from '../../../../services/classification/classification.service';
import { WorkbasketDefinitionService } from '../../../../services/workbasket/workbasketDefinition.service'; import { WorkbasketDefinitionService } from '../../../../services/workbasket/workbasketDefinition.service';
import { DomainService } from '../../../../services/domains/domain.service';
@Component({ @Component({
selector: 'taskana-dummy-detail', selector: 'taskana-dummy-detail',
@ -91,7 +91,7 @@ describe('WorkbasketListComponent', () => {
RouterTestingModule.withRoutes(routes) RouterTestingModule.withRoutes(routes)
], ],
providers: [WorkbasketService, ErrorModalService, RequestInProgressService, AlertService, providers: [WorkbasketService, ErrorModalService, RequestInProgressService, AlertService,
ClassificationService, WorkbasketDefinitionService, OrientationService] ClassificationService, WorkbasketDefinitionService, OrientationService, DomainService]
}) })
.compileComponents(); .compileComponents();

View File

@ -1,4 +1,4 @@
import { TestBed, async, inject, tick, fakeAsync } from '@angular/core/testing'; import { async, inject, TestBed } from '@angular/core/testing';
import { Router, Routes } from '@angular/router'; import { Router, Routes } from '@angular/router';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { AngularSvgIconModule } from 'angular-svg-icon'; import { AngularSvgIconModule } from 'angular-svg-icon';

View File

@ -2,127 +2,125 @@
/** /**
* Modules * Modules
*/ */
import { BrowserModule } from '@angular/platform-browser'; import {BrowserModule} from '@angular/platform-browser';
import { NgModule, } from '@angular/core'; import {NgModule} from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import { HttpClientModule } from '@angular/common/http'; import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module'; import {AppRoutingModule} from './app-routing.module';
import { AlertModule } from 'ngx-bootstrap'; import {AlertModule} from 'ngx-bootstrap';
import { AngularSvgIconModule } from 'angular-svg-icon'; import {AngularSvgIconModule} from 'angular-svg-icon';
import { TabsModule } from 'ngx-bootstrap/tabs'; import {TabsModule} from 'ngx-bootstrap/tabs';
import { TreeModule } from 'angular-tree-component'; import {TreeModule} from 'angular-tree-component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
/** /**
* Components * Components
*/ */
import { AppComponent } from './app.component'; import {AppComponent} from './app.component';
import { WorkbasketListComponent } from './administration/workbasket/master/list/workbasket-list.component'; import {WorkbasketListComponent} from './administration/workbasket/master/list/workbasket-list.component';
import { WorkbasketListToolbarComponent } from './administration/workbasket/master/list/workbasket-list-toolbar/workbasket-list-toolbar.component' import {WorkbasketListToolbarComponent} from './administration/workbasket/master/list/workbasket-list-toolbar/workbasket-list-toolbar.component'
import { WorkbasketDetailsComponent } from './administration/workbasket/details/workbasket-details.component'; import {WorkbasketDetailsComponent} from './administration/workbasket/details/workbasket-details.component';
import { WorkbasketInformationComponent } from './administration/workbasket/details/information/workbasket-information.component'; import {WorkbasketInformationComponent} from './administration/workbasket/details/information/workbasket-information.component';
import { DistributionTargetsComponent } from './administration/workbasket/details/distribution-targets/distribution-targets.component'; import {DistributionTargetsComponent} from './administration/workbasket/details/distribution-targets/distribution-targets.component';
import { DualListComponent } from './administration/workbasket/details/distribution-targets/dual-list/dual-list.component'; import {DualListComponent} from './administration/workbasket/details/distribution-targets/dual-list/dual-list.component';
import { AccessItemsComponent } from './administration/workbasket/details/access-items/access-items.component'; import {AccessItemsComponent} from './administration/workbasket/details/access-items/access-items.component';
import { NoAccessComponent } from './administration/workbasket/details/noAccess/no-access.component'; import {NoAccessComponent} from './administration/workbasket/details/noAccess/no-access.component';
import { SpinnerComponent } from './shared/spinner/spinner.component'; import {SpinnerComponent} from './shared/spinner/spinner.component';
import { FilterComponent } from './shared/filter/filter.component'; import {FilterComponent} from './shared/filter/filter.component';
import { IconTypeComponent } from './shared/type-icon/icon-type.component'; import {IconTypeComponent} from './shared/type-icon/icon-type.component';
import { AlertComponent } from './shared/alert/alert.component'; import {AlertComponent} from './shared/alert/alert.component';
import { SortComponent } from './shared/sort/sort.component'; import {SortComponent} from './shared/sort/sort.component';
import { GeneralMessageModalComponent } from './shared/general-message-modal/general-message-modal.component'; import {GeneralMessageModalComponent} from './shared/general-message-modal/general-message-modal.component';
import { PaginationComponent } from './administration/workbasket/master/list/pagination/pagination.component'; import {PaginationComponent} from './administration/workbasket/master/list/pagination/pagination.component';
import { ClassificationListComponent } from './administration/classification/master/list/classification-list.component'; import {ClassificationListComponent} from './administration/classification/master/list/classification-list.component';
import { ImportExportComponent } from './administration/import-export/import-export.component'; import {ImportExportComponent} from './administration/import-export/import-export.component';
// Shared // Shared
import { MasterAndDetailComponent } from './shared/masterAndDetail/master-and-detail.component'; import {MasterAndDetailComponent} from './shared/masterAndDetail/master-and-detail.component';
/** /**
* Services * Services
*/ */
import { WorkbasketService } from './services/workbasket/workbasket.service'; import {WorkbasketService} from './services/workbasket/workbasket.service';
import { MasterAndDetailService } from './services/masterAndDetail/master-and-detail.service'; import {MasterAndDetailService} from './services/masterAndDetail/master-and-detail.service';
import { HttpClientInterceptor } from './services/httpClientInterceptor/http-client-interceptor.service'; import {HttpClientInterceptor} from './services/httpClientInterceptor/http-client-interceptor.service';
import { PermissionService } from './services/permission/permission.service'; import {PermissionService} from './services/permission/permission.service';
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import {AlertService} from './services/alert/alert.service';
import { AlertService } from './services/alert/alert.service'; import {ErrorModalService} from './services/errorModal/error-modal.service';
import { ErrorModalService } from './services/errorModal/error-modal.service'; import {RequestInProgressService} from './services/requestInProgress/request-in-progress.service';
import { RequestInProgressService } from './services/requestInProgress/request-in-progress.service'; import {SavingWorkbasketService} from './services/saving-workbaskets/saving-workbaskets.service';
import { SavingWorkbasketService } from './services/saving-workbaskets/saving-workbaskets.service'; import {OrientationService} from './services/orientation/orientation.service';
import { OrientationService } from './services/orientation/orientation.service'; import {ClassificationService} from './services/classification/classification.service';
import { ClassificationService } from './services/classification/classification.service'; import {WorkbasketDefinitionService} from './services/workbasket/workbasketDefinition.service';
import { WorkbasketDefinitionService } from './services/workbasket/workbasketDefinition.service';
/** /**
* Pipes * Pipes
*/ */
import { MapValuesPipe } from './pipes/mapValues/map-values.pipe'; import {MapValuesPipe} from './pipes/mapValues/map-values.pipe';
import { RemoveNoneTypePipe } from './pipes/removeNoneType/remove-none-type.pipe'; import {RemoveNoneTypePipe} from './pipes/removeNoneType/remove-none-type.pipe';
import { SelectWorkBasketPipe } from './pipes/selectedWorkbasket/seleted-workbasket.pipe'; import {SelectWorkBasketPipe} from './pipes/selectedWorkbasket/seleted-workbasket.pipe';
import { SpreadNumberPipe } from './pipes/spreadNumber/spread-number'; import {SpreadNumberPipe} from './pipes/spreadNumber/spread-number';
import {DomainService} from './services/domains/domain.service';
const MODULES = [ const MODULES = [
BrowserModule, BrowserModule,
FormsModule, FormsModule,
TabsModule.forRoot(), TabsModule.forRoot(),
TreeModule, TreeModule,
AppRoutingModule, AppRoutingModule,
AlertModule.forRoot(), AlertModule.forRoot(),
AngularSvgIconModule, AngularSvgIconModule,
HttpClientModule, HttpClientModule,
BrowserAnimationsModule, BrowserAnimationsModule,
ReactiveFormsModule ReactiveFormsModule
]; ];
const DECLARATIONS = [ const DECLARATIONS = [
AppComponent, AppComponent,
WorkbasketListComponent, WorkbasketListComponent,
WorkbasketListToolbarComponent, WorkbasketListToolbarComponent,
AccessItemsComponent, AccessItemsComponent,
WorkbasketDetailsComponent, WorkbasketDetailsComponent,
MasterAndDetailComponent, MasterAndDetailComponent,
WorkbasketInformationComponent, WorkbasketInformationComponent,
NoAccessComponent, NoAccessComponent,
SpinnerComponent, SpinnerComponent,
FilterComponent, FilterComponent,
IconTypeComponent, IconTypeComponent,
AlertComponent, AlertComponent,
GeneralMessageModalComponent, GeneralMessageModalComponent,
DistributionTargetsComponent, DistributionTargetsComponent,
SortComponent, SortComponent,
DualListComponent, DualListComponent,
PaginationComponent, PaginationComponent,
ClassificationListComponent, ClassificationListComponent,
ImportExportComponent, ImportExportComponent,
MapValuesPipe, MapValuesPipe,
RemoveNoneTypePipe, RemoveNoneTypePipe,
SelectWorkBasketPipe, SelectWorkBasketPipe,
SpreadNumberPipe SpreadNumberPipe
]; ];
@NgModule({ @NgModule({
declarations: DECLARATIONS, declarations: DECLARATIONS,
imports: MODULES, imports: MODULES,
providers: [ providers: [
WorkbasketService, WorkbasketService,
MasterAndDetailService, MasterAndDetailService,
PermissionService, PermissionService,
ClassificationService, ClassificationService,
WorkbasketDefinitionService, WorkbasketDefinitionService,
{ DomainService,
provide: HTTP_INTERCEPTORS, {
useClass: HttpClientInterceptor, provide: HTTP_INTERCEPTORS,
multi: true useClass: HttpClientInterceptor,
}, multi: true
AlertService, },
ErrorModalService, AlertService,
RequestInProgressService, ErrorModalService,
SavingWorkbasketService, RequestInProgressService,
OrientationService SavingWorkbasketService,
], OrientationService
bootstrap: [AppComponent] ],
bootstrap: [AppComponent]
}) })
export class AppModule { } export class AppModule {
}
// tslint:enable:max-line-length // tslint:enable:max-line-length

View File

@ -1,16 +1,17 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http'; import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {environment} from '../../../environments/environment'; import {environment} from '../../../environments/environment';
import {DatePipe} from '@angular/common';
import {AlertService} from '../alert/alert.service'; import {AlertService} from '../alert/alert.service';
import {Classification} from '../../models/classification'; import {Classification} from '../../models/classification';
import {AlertModel, AlertType} from '../../models/alert'; import {AlertModel, AlertType} from '../../models/alert';
import {saveAs} from 'file-saver/FileSaver'; import {saveAs} from 'file-saver/FileSaver';
import {TaskanaDate} from '../../shared/util/taskana.date';
@Injectable() @Injectable()
export class ClassificationService { export class ClassificationService {
url = environment.taskanaRestUrl + '/v1/classificationdefinitions';
httpOptions = { httpOptions = {
headers: new HttpHeaders({ headers: new HttpHeaders({
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -22,42 +23,22 @@ export class ClassificationService {
} }
// GET // GET
getClassificationDomains(): Observable<string[]> { exportClassifications(domain: string) {
return this.httpClient.get<string[]>(environment.taskanaRestUrl + '/v1/classifications/domains', this.httpOptions); domain = (domain === '' ? '' : '?domain=' + domain);
} this.httpClient.get<Classification[]>(this.url + domain, this.httpOptions)
// GET
exportAllClassifications() {
this.httpClient.get<Classification[]>(environment.taskanaRestUrl + '/v1/classificationdefinitions', this.httpOptions)
.subscribe( .subscribe(
response => saveAs(new Blob([JSON.stringify(response)], {type: 'text/plain;charset=utf-8'}), this.generateName()) response => saveAs(new Blob([JSON.stringify(response)], {type: 'text/plain;charset=utf-8'}),
); 'Classifications_' + TaskanaDate.getDate() + '.json')
}
// GET
exportClassificationsByDomain(domain: string) {
this.httpClient.get<Classification[]>(environment.taskanaRestUrl + '/v1/classificationdefinitions?domain=' + domain, this.httpOptions)
.subscribe(
response => saveAs(new Blob([JSON.stringify(response)], {type: 'text/plain;charset=utf-8'}), this.generateName(domain))
); );
} }
// POST // POST
// TODO handle error // TODO handle error
importClassifications(classifications: any) { importClassifications(classifications: any) {
console.log('importing classifications'); this.httpClient.post(this.url + '/import',
this.httpClient.post(environment.taskanaRestUrl + '/v1/classificationdefinitions/import',
JSON.parse(classifications), this.httpOptions).subscribe( JSON.parse(classifications), this.httpOptions).subscribe(
classificationsUpdated => this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, 'Import was successful')), classificationsUpdated => this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, 'Import was successful')),
error => this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'Import was not successful')) error => this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'Import was not successful'))
); );
} }
private generateName(domain = ''): string {
const dateFormat = 'yyyy-MM-ddTHH:mm:ss';
const dateLocale = 'en-US';
const datePipe = new DatePipe(dateLocale);
const date = datePipe.transform(Date.now(), dateFormat) + 'Z';
return 'Classifications_' + date + '.json';
}
} }

View File

@ -0,0 +1,26 @@
import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {environment} from '../../../environments/environment';
@Injectable()
export class DomainService {
url = environment.taskanaRestUrl + '/v1/domains';
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Basic VEVBTUxFQURfMTpURUFNTEVBRF8x'
})
};
constructor(private httpClient: HttpClient) {
}
// TODO how to enable hateoas support?
// GET
getDomains(): Observable<string[]> {
return this.httpClient.get<string[]>(this.url, this.httpOptions);
}
}

View File

@ -1,17 +1,14 @@
import { Injectable } from '@angular/core'; import {Injectable} from '@angular/core';
import { HttpClientModule, HttpClient, HttpHeaders, HttpResponse, HttpErrorResponse } from '@angular/common/http'; import {HttpClient, HttpHeaders} from '@angular/common/http';
import { Observable } from 'rxjs/Observable'; import {Observable} from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject'; import {Subject} from 'rxjs/Subject';
import { map } from 'rxjs/operator/map'; import {environment} from 'app/../environments/environment';
import { environment } from 'app/../environments/environment'; import {Workbasket} from 'app/models/workbasket';
import {WorkbasketAccessItems} from 'app/models/workbasket-access-items';
import { WorkbasketSummary } from 'app//models/workbasket-summary'; import {WorkbasketSummaryResource} from 'app/models/workbasket-summary-resource';
import { Workbasket } from 'app/models/workbasket'; import {WorkbasketAccessItemsResource} from 'app/models/workbasket-access-items-resource';
import { WorkbasketAccessItems } from 'app/models/workbasket-access-items'; import {WorkbasketDistributionTargetsResource} from 'app/models/workbasket-distribution-targets-resource';
import { WorkbasketSummaryResource } from 'app/models/workbasket-summary-resource'; import {Direction} from 'app/models/sorting';
import { WorkbasketAccessItemsResource } from 'app/models/workbasket-access-items-resource';
import { WorkbasketDistributionTargetsResource } from 'app/models/workbasket-distribution-targets-resource';
import { Direction } from 'app/models/sorting';
@Injectable() @Injectable()
export class WorkbasketService { export class WorkbasketService {
@ -123,11 +120,6 @@ export class WorkbasketService {
return this.httpClient.put<WorkbasketDistributionTargetsResource>(url, distributionTargetsIds, this.httpOptions); return this.httpClient.put<WorkbasketDistributionTargetsResource>(url, distributionTargetsIds, this.httpOptions);
} }
// GET
getWorkbasketDomains() {
return this.httpClient.get<string[]>(environment.taskanaRestUrl + '/v1/workbaskets/domains', this.httpOptions);
}
// #endregion // #endregion
// #region "Service extras" // #region "Service extras"
selectWorkBasket(id: string) { selectWorkBasket(id: string) {

View File

@ -2,10 +2,10 @@ import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http'; import {HttpClient, HttpHeaders} from '@angular/common/http';
import {environment} from '../../../environments/environment'; import {environment} from '../../../environments/environment';
import {saveAs} from 'file-saver/FileSaver'; import {saveAs} from 'file-saver/FileSaver';
import {DatePipe} from '@angular/common';
import {AlertService} from '../alert/alert.service'; import {AlertService} from '../alert/alert.service';
import {WorkbasketDefinition} from '../../models/workbasket-definition'; import {WorkbasketDefinition} from '../../models/workbasket-definition';
import {AlertModel, AlertType} from '../../models/alert'; import {AlertModel, AlertType} from '../../models/alert';
import {TaskanaDate} from '../../shared/util/taskana.date';
@Injectable() @Injectable()
@ -24,18 +24,12 @@ export class WorkbasketDefinitionService {
} }
// GET // GET
exportAllWorkbaskets() { exportWorkbaskets(domain: string) {
this.httpClient.get<WorkbasketDefinition[]>(this.url, this.httpOptions).subscribe( domain = (domain === '' ? '' : '?domain=' + domain);
response => saveAs(new Blob([JSON.stringify(response)], {type: 'text/plain;charset=utf-8'}), this.generateName()) this.httpClient.get<WorkbasketDefinition[]>(this.url + domain, this.httpOptions).subscribe(
);
}
// GET
exportWorkbasketsByDomain(domain: string) {
this.httpClient.get<WorkbasketDefinition[]>(this.url + '?' + 'domain=' + domain, this.httpOptions).subscribe(
response => { response => {
saveAs(new Blob([JSON.stringify(response)], {type: 'text/plain;charset=utf-8'}), this.generateName(domain)); saveAs(new Blob([JSON.stringify(response)], {type: 'text/plain;charset=utf-8'}),
console.log(response); 'Workbaskets_' + TaskanaDate.getDate() + '.json');
} }
); );
} }
@ -43,20 +37,10 @@ export class WorkbasketDefinitionService {
// POST // POST
// TODO handle error // TODO handle error
importWorkbasketDefinitions(workbasketDefinitions: any) { importWorkbasketDefinitions(workbasketDefinitions: any) {
console.log('importing workbaskets');
this.httpClient.post(environment.taskanaRestUrl + '/v1/workbasketdefinitions/import', this.httpClient.post(environment.taskanaRestUrl + '/v1/workbasketdefinitions/import',
JSON.parse(workbasketDefinitions), this.httpOptions).subscribe( JSON.parse(workbasketDefinitions), this.httpOptions).subscribe(
workbasketsUpdated => this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, 'Import was successful')), workbasketsUpdated => this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, 'Import was successful')),
error => this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'Import was not successful')) error => this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'Import was not successful'))
); );
} }
private generateName(domain = ''): string {
const dateFormat = 'yyyy-MM-ddTHH:mm:ss';
const dateLocale = 'en-US';
const datePipe = new DatePipe(dateLocale);
const date = datePipe.transform(Date.now(), dateFormat) + 'Z';
return 'Workbaskets_' + date + '.json';
}
} }

View File

@ -0,0 +1,10 @@
import {DatePipe} from '@angular/common';
export class TaskanaDate {
public static getDate(): string {
const dateFormat = 'yyyy-MM-ddTHH:mm:ss';
const dateLocale = 'en-US';
const datePipe = new DatePipe(dateLocale);
return datePipe.transform(Date.now(), dateFormat) + 'Z';
}
}