task/831 Reimplement locale and date solution for all date outputs
This commit is contained in:
parent
d16b4b51ab
commit
cc8e47b99a
|
@ -17,7 +17,7 @@ module.exports = function (config) {
|
|||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
//seed: 80185, // Specify if you need to re-run the same seed
|
||||
// seed: '56124', // Specify if you need to re-run the same seed
|
||||
},
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div *ngIf="reportData" class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>{{reportData.meta.name}} ({{reportData.meta.date | date : 'dd.MM.yyyy HH:mm:ss'}})</h4>
|
||||
<h4>{{reportData.meta.name}} ({{reportData.meta.date | dateTimeZone}})</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
|
@ -13,4 +13,4 @@
|
|||
</div>
|
||||
<taskana-report [type]="reportType" [reportData]="reportData"></taskana-report>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,14 +14,7 @@ export class RestConnectorService {
|
|||
}
|
||||
|
||||
getTaskStatusReport(): Observable<ReportData> {
|
||||
return this.httpClient.get<ReportData>(environment.taskanaRestUrl + '/v1/monitor/tasks-status-report?states=READY,CLAIMED,COMPLETED')
|
||||
.pipe(map(
|
||||
(response: ReportData) => {
|
||||
if (response.meta.date) {
|
||||
response.meta.date = TaskanaDate.applyTimeZone(response.meta.date);
|
||||
}
|
||||
return response;
|
||||
}));
|
||||
return this.httpClient.get<ReportData>(environment.taskanaRestUrl + '/v1/monitor/tasks-status-report?states=READY,CLAIMED,COMPLETED');
|
||||
}
|
||||
|
||||
getWorkbasketStatistics(): Observable<ReportData> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div *ngIf= "reportData" class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>{{reportData.meta.name}} ({{reportData.meta.date | date : 'dd.MM.yyyy HH:mm:ss'}})</h4>
|
||||
<h4>{{reportData.meta.name}} ({{reportData.meta.date | dateTimeZone}})</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div style="display: block" class =" col-xs-12 col-md-7 col-md-offset-2">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div *ngIf="reportData" class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>{{reportData.meta.name}} ({{reportData.meta.date | date : 'dd.MM.yyyy HH:mm:ss'}})</h4>
|
||||
<h4>{{reportData.meta.name}} ({{reportData.meta.date | dateTimeZone}})</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<div class="input-icon-wrap">
|
||||
<div class="input-group">
|
||||
|
||||
<input type="text"
|
||||
placeholder="{{placeholder}}"
|
||||
class="form-control input-with-icon"
|
||||
|
@ -7,6 +8,7 @@
|
|||
(bsValueChange)="dateChange($event)"
|
||||
[bsValue]="valueDate"
|
||||
name="{{name}}"
|
||||
id="{{id}}">
|
||||
<span class="input-icon"><span class="material-icons md-24 black">date_range</span></span>
|
||||
id="{{id}}"
|
||||
#datePickerElement="bsDatepicker">
|
||||
<span class="input-icon-addon material-icons md-24 dark-green" (click)="datePickerElement.toggle()">date_range</span>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
.input-icon-wrap {
|
||||
.input-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
height: 35px;
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
|
||||
.input-with-icon {
|
||||
|
@ -12,7 +12,6 @@
|
|||
height: 33px;
|
||||
}
|
||||
|
||||
.input-icon span {
|
||||
padding-top: 5px;
|
||||
padding-right: 6px;
|
||||
.input-icon-addon {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import { DateTimeZonePipe } from './date-time-zone.pipe';
|
||||
|
||||
describe('DateTimeZonePipe', () => {
|
||||
it('create an instance', () => {
|
||||
const pipe = new DateTimeZonePipe();
|
||||
expect(pipe).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
import {Pipe, PipeTransform} from '@angular/core';
|
||||
import {TaskanaDate} from '../../util/taskana.date';
|
||||
|
||||
@Pipe({
|
||||
name: 'dateTimeZone'
|
||||
})
|
||||
export class DateTimeZonePipe implements PipeTransform {
|
||||
|
||||
private datesMap = new Map<string, string>();
|
||||
|
||||
transform(value: any, args?: any): any {
|
||||
|
||||
let date = this.datesMap.get(value);
|
||||
if (!date) {
|
||||
date = TaskanaDate.getDateToDisplay(value);
|
||||
this.datesMap.set(value, date);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
}
|
|
@ -1,48 +1,50 @@
|
|||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { AngularSvgIconModule } from 'angular-svg-icon';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TreeModule } from 'angular-tree-component';
|
||||
import { AlertModule, TypeaheadModule, BsDatepickerModule } from 'ngx-bootstrap';
|
||||
import { AccordionModule } from 'ngx-bootstrap/accordion';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {NgModule} from '@angular/core';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {HttpClientModule, HTTP_INTERCEPTORS} from '@angular/common/http';
|
||||
import {AngularSvgIconModule} from 'angular-svg-icon';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {TreeModule} from 'angular-tree-component';
|
||||
import {AlertModule, TypeaheadModule, BsDatepickerModule} from 'ngx-bootstrap';
|
||||
import {AccordionModule} from 'ngx-bootstrap/accordion';
|
||||
|
||||
/**
|
||||
* Components
|
||||
*/
|
||||
import { GeneralMessageModalComponent } from 'app/shared/general-message-modal/general-message-modal.component';
|
||||
import { SpinnerComponent } from 'app/shared/spinner/spinner.component';
|
||||
import { AlertComponent } from 'app/shared/alert/alert.component';
|
||||
import { MasterAndDetailComponent } from 'app/shared/master-and-detail/master-and-detail.component';
|
||||
import { TaskanaTreeComponent } from 'app/shared/tree/tree.component';
|
||||
import { TypeAheadComponent } from 'app/shared/type-ahead/type-ahead.component';
|
||||
import { SortComponent } from './sort/sort.component';
|
||||
import { RemoveConfirmationComponent } from 'app/shared/remove-confirmation/remove-confirmation.component';
|
||||
import { FilterComponent } from 'app/shared/filter/filter.component';
|
||||
import { IconTypeComponent } from 'app/administration/components/type-icon/icon-type.component';
|
||||
import { FieldErrorDisplayComponent } from 'app/shared/field-error-display/field-error-display.component';
|
||||
import { PaginationComponent } from './pagination/pagination.component';
|
||||
import { NumberPickerComponent } from './number-picker/number-picker.component';
|
||||
import { ProgressBarComponent } from './progress-bar/progress-bar.component';
|
||||
import { DatePickerComponent } from './date-picker/date-picker.component';
|
||||
import {GeneralMessageModalComponent} from 'app/shared/general-message-modal/general-message-modal.component';
|
||||
import {SpinnerComponent} from 'app/shared/spinner/spinner.component';
|
||||
import {AlertComponent} from 'app/shared/alert/alert.component';
|
||||
import {MasterAndDetailComponent} from 'app/shared/master-and-detail/master-and-detail.component';
|
||||
import {TaskanaTreeComponent} from 'app/shared/tree/tree.component';
|
||||
import {TypeAheadComponent} from 'app/shared/type-ahead/type-ahead.component';
|
||||
import {SortComponent} from './sort/sort.component';
|
||||
import {RemoveConfirmationComponent} from 'app/shared/remove-confirmation/remove-confirmation.component';
|
||||
import {FilterComponent} from 'app/shared/filter/filter.component';
|
||||
import {IconTypeComponent} from 'app/administration/components/type-icon/icon-type.component';
|
||||
import {FieldErrorDisplayComponent} from 'app/shared/field-error-display/field-error-display.component';
|
||||
import {PaginationComponent} from './pagination/pagination.component';
|
||||
import {NumberPickerComponent} from './number-picker/number-picker.component';
|
||||
import {ProgressBarComponent} from './progress-bar/progress-bar.component';
|
||||
import {DatePickerComponent} from './date-picker/date-picker.component';
|
||||
|
||||
/**
|
||||
* Pipes
|
||||
*/
|
||||
import { MapValuesPipe } from './pipes/mapValues/map-values.pipe';
|
||||
import { RemoveNoneTypePipe } from './pipes/removeNoneType/remove-none-type.pipe';
|
||||
import { SelectWorkBasketPipe } from './pipes/selectedWorkbasket/seleted-workbasket.pipe';
|
||||
import { SpreadNumberPipe } from './pipes/spreadNumber/spread-number';
|
||||
import { OrderBy } from './pipes/orderBy/orderBy';
|
||||
import { MapToIterable } from './pipes/mapToIterable/mapToIterable';
|
||||
import { NumberToArray } from './pipes/numberToArray/numberToArray';
|
||||
import {MapValuesPipe} from './pipes/mapValues/map-values.pipe';
|
||||
import {RemoveNoneTypePipe} from './pipes/removeNoneType/remove-none-type.pipe';
|
||||
import {SelectWorkBasketPipe} from './pipes/selectedWorkbasket/seleted-workbasket.pipe';
|
||||
import {SpreadNumberPipe} from './pipes/spreadNumber/spread-number';
|
||||
import {OrderBy} from './pipes/orderBy/orderBy';
|
||||
import {MapToIterable} from './pipes/mapToIterable/mapToIterable';
|
||||
import {NumberToArray} from './pipes/numberToArray/numberToArray';
|
||||
import {DateTimeZonePipe} from './pipes/date-time-zone/date-time-zone.pipe';
|
||||
|
||||
|
||||
/**
|
||||
* Services
|
||||
*/
|
||||
import { HttpClientInterceptor } from './services/httpClientInterceptor/http-client-interceptor.service';
|
||||
import { AccessIdsService } from './services/access-ids/access-ids.service';
|
||||
import {HttpClientInterceptor} from './services/httpClientInterceptor/http-client-interceptor.service';
|
||||
import {AccessIdsService} from './services/access-ids/access-ids.service';
|
||||
|
||||
const MODULES = [
|
||||
CommonModule,
|
||||
|
@ -68,6 +70,7 @@ const DECLARATIONS = [
|
|||
RemoveNoneTypePipe,
|
||||
SelectWorkBasketPipe,
|
||||
SpreadNumberPipe,
|
||||
DateTimeZonePipe,
|
||||
NumberToArray,
|
||||
OrderBy,
|
||||
MapToIterable,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { DatePipe } from '@angular/common';
|
||||
|
||||
export class TaskanaDate {
|
||||
public static dateFormat = 'yyyy-MM-ddTHH:mm:ss.sss';
|
||||
public static getDate(): string {
|
||||
const dateFormat = 'yyyy-MM-ddTHH:mm:ss.sss';
|
||||
const dateLocale = 'en-US';
|
||||
const datePipe = new DatePipe(dateLocale);
|
||||
|
||||
return datePipe.transform(Date.now(), dateFormat) + 'Z';
|
||||
return datePipe.transform(Date.now(), this.dateFormat) + 'Z';
|
||||
}
|
||||
|
||||
public static convertSimpleDate(date: Date): string {
|
||||
|
@ -20,7 +20,7 @@ export class TaskanaDate {
|
|||
return this.applyTimeZone(date);
|
||||
}
|
||||
|
||||
public static applyTimeZone(date: string): string | null {
|
||||
private static applyTimeZone(date: string): string | null {
|
||||
const dateFormat = 'yyyy-MM-dd HH:mm:ss';
|
||||
const dateLocale = 'en-US';
|
||||
const datePipe = new DatePipe(dateLocale);
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
<div class="col-md-6">
|
||||
<div *ngIf="task.taskId" class="form-group">
|
||||
<label for="task-modified" class="control-label">Modification date</label>
|
||||
<input type="text" disabled class="form-control" id="task-modified" placeholder="Modified" [(ngModel)]="task.modified"
|
||||
<input type="text" disabled class="form-control" id="task-modified" placeholder="Modified" [value]="task.modified | dateTimeZone"
|
||||
name="task.modified">
|
||||
</div>
|
||||
<div *ngIf="task.taskId" class="form-group">
|
||||
<label for="task-completed" class="control-label">Completion date</label>
|
||||
<input type="text" disabled class="form-control" id="task-completed" placeholder="Complete date" [(ngModel)]="task.completed"
|
||||
<input type="text" disabled class="form-control" id="task-completed" placeholder="Complete date" [value]="task.completed | dateTimeZone"
|
||||
name="task.completed">
|
||||
</div>
|
||||
<div *ngIf="task.taskId" class="form-group">
|
||||
|
@ -23,17 +23,17 @@
|
|||
<div class="col-md-6">
|
||||
<div *ngIf="task.taskId" class="form-group">
|
||||
<label for="task-claimed" class="control-label">Claim date</label>
|
||||
<input type="text" disabled class="form-control" id="task-claimed" placeholder="Claimed date" [(ngModel)]="task.claimed"
|
||||
<input type="text" disabled class="form-control" id="task-claimed" placeholder="Claimed date" [value]="task.claimed | dateTimeZone"
|
||||
name="task.claimed">
|
||||
</div>
|
||||
<div *ngIf="task.taskId" class="form-group">
|
||||
<label for="task-planned" class="control-label">Planned date</label>
|
||||
<input type="text" disabled class="form-control" id="task-planned" placeholder="Planned date" [(ngModel)]="task.planned"
|
||||
<input type="text" disabled class="form-control" id="task-planned" placeholder="Planned date" [value]="task.planned | dateTimeZone"
|
||||
name="task.planned">
|
||||
</div>
|
||||
<div *ngIf="task.taskId" class="form-group">
|
||||
<label for="task-created" class="control-label">Creation date</label>
|
||||
<input type="text" disabled class="form-control" id="task-created" placeholder="Created" [(ngModel)]="task.created"
|
||||
<input type="text" disabled class="form-control" id="task-created" placeholder="Created" [value]="task.created | dateTimeZone"
|
||||
name="task.created">
|
||||
</div>
|
||||
<div *ngIf="task.taskId" class="form-group">
|
||||
|
@ -42,4 +42,4 @@
|
|||
name="task.transferred">
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
|
|
@ -131,29 +131,6 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
|
|||
this.router.navigate(['./'], {relativeTo: this.route.parent});
|
||||
}
|
||||
|
||||
|
||||
private applyTaskDatesTimeZone(task: Task): Task {
|
||||
if (task.due) {
|
||||
task.due = TaskanaDate.applyTimeZone(task.due);
|
||||
}
|
||||
if (task.modified) {
|
||||
task.modified = TaskanaDate.applyTimeZone(task.modified);
|
||||
}
|
||||
if (task.completed) {
|
||||
task.completed = TaskanaDate.applyTimeZone(task.completed);
|
||||
}
|
||||
if (task.planned) {
|
||||
task.planned = TaskanaDate.applyTimeZone(task.planned);
|
||||
}
|
||||
if (task.claimed) {
|
||||
task.claimed = TaskanaDate.applyTimeZone(task.claimed);
|
||||
}
|
||||
if (task.created) {
|
||||
task.created = TaskanaDate.applyTimeZone(task.created);
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
private onSave() {
|
||||
this.currentId === 'new-task' ? this.createTask() : this.updateTask();
|
||||
}
|
||||
|
@ -199,8 +176,6 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
|
|||
this.taskClone.customAttributes = this.task.customAttributes.slice(0);
|
||||
this.taskClone.callbackInfo = this.task.callbackInfo.slice(0);
|
||||
this.taskClone.primaryObjRef = {...this.task.primaryObjRef};
|
||||
this.taskClone = this.applyTaskDatesTimeZone(this.taskClone);
|
||||
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<dd data-toggle="tooltip" title="{{task.state}}">{{task.state}}</dd>
|
||||
</dl>
|
||||
<dl class="pull-right padding-right">
|
||||
<i data-toggle="tooltip" title="{{task.due}}">Due: {{displayDate(task.due)}}</i>
|
||||
<i data-toggle="tooltip" title="{{task.due}}">Due: {{task.due | dateTimeZone}}</i>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
@ -33,4 +33,4 @@
|
|||
<h3 class="grey">Select a workbasket</h3>
|
||||
<svg-icon class="img-responsive empty-icon workbasket-icon" src="./assets/icons/wb-empty.svg"></svg-icon>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
|
|
|
@ -8,6 +8,8 @@ import { Routes } from '@angular/router';
|
|||
import { Component, ChangeDetectorRef } from '@angular/core';
|
||||
import { WorkplaceService } from 'app/workplace/services/workplace.service';
|
||||
import { SvgIconComponent, SvgIconRegistryService } from 'angular-svg-icon';
|
||||
import {DateTimeZonePipe} from '../../../shared/pipes/date-time-zone/date-time-zone.pipe';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-dummy-detail',
|
||||
|
@ -30,7 +32,12 @@ describe('TaskListComponent', () => {
|
|||
FormsModule,
|
||||
RouterTestingModule.withRoutes(routes),
|
||||
HttpClientModule],
|
||||
declarations: [TaskListComponent, DummyDetailComponent, SvgIconComponent],
|
||||
declarations: [
|
||||
TaskListComponent,
|
||||
DummyDetailComponent,
|
||||
SvgIconComponent,
|
||||
DateTimeZonePipe
|
||||
],
|
||||
providers: [
|
||||
WorkplaceService,
|
||||
ChangeDetectorRef,
|
||||
|
|
|
@ -2,20 +2,17 @@ import {
|
|||
Component, OnInit, Input, ChangeDetectionStrategy, Output,
|
||||
EventEmitter, SimpleChanges, OnChanges, ChangeDetectorRef
|
||||
} from '@angular/core';
|
||||
import { Task } from 'app/workplace/models/task';
|
||||
import { TaskanaDate } from 'app/shared/util/taskana.date';
|
||||
import { WorkplaceService } from 'app/workplace/services/workplace.service';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import {Task} from 'app/workplace/models/task';
|
||||
import {TaskanaDate} from 'app/shared/util/taskana.date';
|
||||
import {WorkplaceService} from 'app/workplace/services/workplace.service';
|
||||
import {Router, ActivatedRoute} from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-task-list',
|
||||
templateUrl: './task-list.component.html',
|
||||
styleUrls: ['./task-list.component.scss'],
|
||||
// This is used to avoid angular detect changes automatically since displayDate is bein executed on every onChange.
|
||||
// this cause a low performance in the screen.
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class TaskListComponent implements OnInit, OnChanges {
|
||||
export class TaskListComponent implements OnInit {
|
||||
|
||||
@Input()
|
||||
tasks: Array<Task>;
|
||||
|
@ -25,28 +22,18 @@ export class TaskListComponent implements OnInit, OnChanges {
|
|||
selectedIdChange = new EventEmitter<string>();
|
||||
|
||||
constructor(private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private workplaceService: WorkplaceService,
|
||||
private changeDetector: ChangeDetectorRef) { }
|
||||
|
||||
ngOnInit() {
|
||||
private route: ActivatedRoute,
|
||||
private workplaceService: WorkplaceService) {
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes.tasks || changes.selectedId) {
|
||||
this.changeDetector.detectChanges();
|
||||
}
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
selectTask(taskId: string) {
|
||||
this.workplaceService.selectObjectReference(undefined);
|
||||
this.selectedId = taskId;
|
||||
this.selectedIdChange.emit(taskId);
|
||||
this.router.navigate([{ outlets: { detail: `taskdetail/${this.selectedId}` } }], { relativeTo: this.route });
|
||||
}
|
||||
|
||||
displayDate(date: string): string {
|
||||
return TaskanaDate.getDateToDisplay(date);
|
||||
this.router.navigate([{outlets: {detail: `taskdetail/${this.selectedId}`}}], {relativeTo: this.route});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -88,6 +88,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
.dark-green{
|
||||
color: $dark-green;
|
||||
& svg {
|
||||
fill: $dark-green;
|
||||
}
|
||||
}
|
||||
|
||||
.grey {
|
||||
color:$grey;
|
||||
& svg {
|
||||
|
@ -320,8 +327,8 @@ taskana-task-details, taskana-classification-details, taskana-access-items-manag
|
|||
}
|
||||
|
||||
taskana-task-query {
|
||||
& .panel{
|
||||
&> .panel-body {
|
||||
& .panel{
|
||||
&> .panel-body {
|
||||
height: calc(100vh - 105px);
|
||||
max-height: calc(100vh - 105px);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue