bug/829 Fix unable to edit twice a task due to wrong modification date format

This commit is contained in:
Martin Rojas Miguel Angel 2019-03-12 15:50:11 +01:00 committed by Holger Hagen
parent acae3e633b
commit 999ccfde3d
5 changed files with 73 additions and 55 deletions

View File

@ -48,7 +48,7 @@ public class SampleDataGenerator {
private static final String RELATIVE_DATE_REGEX = "RELATIVE_DATE\\((-?\\d+)\\)"; private static final String RELATIVE_DATE_REGEX = "RELATIVE_DATE\\((-?\\d+)\\)";
private static final Pattern RELATIVE_DATE_PATTERN = Pattern.compile(RELATIVE_DATE_REGEX); private static final Pattern RELATIVE_DATE_PATTERN = Pattern.compile(RELATIVE_DATE_REGEX);
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
private DataSource dataSource; private DataSource dataSource;
private ScriptRunner runner; private ScriptRunner runner;

View File

@ -331,7 +331,7 @@ public class TaskControllerIntTest {
String created = jsonNode.get("created").asText(); String created = jsonNode.get("created").asText();
assertFalse(response.contains("\"attachments\":[]")); assertFalse(response.contains("\"attachments\":[]"));
assertTrue( assertTrue(
created.matches("\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d([+-][0-2]\\d:[0-5]\\d|Z)")); created.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z"));
} }
@Test @Test

View File

@ -60,12 +60,7 @@ export class TaskService {
} }
getTask(id: string): Observable<Task> { getTask(id: string): Observable<Task> {
return this.httpClient.get<Task>(`${this.url}/${id}`) return this.httpClient.get<Task>(`${this.url}/${id}`);
.pipe(map(
(response: Task) => {
response = this.applyTaskDatesTimeZone(response);
return response;
}));
} }
completeTask(id: string): Observable<Task> { completeTask(id: string): Observable<Task> {
@ -93,16 +88,6 @@ export class TaskService {
return this.httpClient.post<Task>(this.url, task); return this.httpClient.post<Task>(this.url, task);
} }
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 convertTasksDatesToGMT(task: Task): Task { private convertTasksDatesToGMT(task: Task): Task {
if (task.created) { task.created = new Date(task.created).toISOString(); } if (task.created) { task.created = new Date(task.created).toISOString(); }
if (task.claimed) { task.claimed = new Date(task.claimed).toISOString(); } if (task.claimed) { task.claimed = new Date(task.claimed).toISOString(); }

View File

@ -44,7 +44,7 @@
<span class="float-right pull-right material-icons md-20 blue">{{accordion2State? <span class="float-right pull-right material-icons md-20 blue">{{accordion2State?
'expand_more':'expand_less'}}</span> 'expand_more':'expand_less'}}</span>
</button> </button>
<taskana-general-fields-extension [task]="task"></taskana-general-fields-extension> <taskana-general-fields-extension [task]="taskClone"></taskana-general-fields-extension>
</accordion-group> </accordion-group>
<accordion-group panelClass="customClass" (isOpenChange)="accordion3State = $event"> <accordion-group panelClass="customClass" (isOpenChange)="accordion3State = $event">
<button class="btn btn-block clearfix" accordion-heading> <button class="btn btn-block clearfix" accordion-heading>

View File

@ -1,21 +1,21 @@
import { Component, OnDestroy, OnInit } from '@angular/core'; import {Component, OnDestroy, OnInit} from '@angular/core';
import { Subscription } from 'rxjs'; import {Subscription} from 'rxjs';
import { ActivatedRoute, Router } from '@angular/router'; import {ActivatedRoute, Router} from '@angular/router';
import { TaskService } from 'app/workplace/services/task.service'; import {TaskService} from 'app/workplace/services/task.service';
import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service'; import {RemoveConfirmationService} from 'app/services/remove-confirmation/remove-confirmation.service';
import { Task } from 'app/workplace/models/task'; import {Task} from 'app/workplace/models/task';
import { MessageModal } from 'app/models/message-modal'; import {MessageModal} from 'app/models/message-modal';
import { GeneralModalService } from 'app/services/general-modal/general-modal.service'; import {GeneralModalService} from 'app/services/general-modal/general-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import {RequestInProgressService} from 'app/services/requestInProgress/request-in-progress.service';
import { AlertService } from 'app/services/alert/alert.service'; import {AlertService} from 'app/services/alert/alert.service';
import { AlertModel, AlertType } from 'app/models/alert'; import {AlertModel, AlertType} from 'app/models/alert';
import { TaskanaDate } from 'app/shared/util/taskana.date'; import {TaskanaDate} from 'app/shared/util/taskana.date';
import { ObjectReference } from 'app/workplace/models/object-reference'; import {ObjectReference} from 'app/workplace/models/object-reference';
import { Workbasket } from 'app/models/workbasket'; import {Workbasket} from 'app/models/workbasket';
import { WorkplaceService } from 'app/workplace/services/workplace.service'; import {WorkplaceService} from 'app/workplace/services/workplace.service';
import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-detail.service'; import {MasterAndDetailService} from 'app/services/masterAndDetail/master-and-detail.service';
@Component({ @Component({
selector: 'taskana-task-details', selector: 'taskana-task-details',
@ -37,14 +37,14 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
private deleteTaskSubscription: Subscription; private deleteTaskSubscription: Subscription;
constructor(private route: ActivatedRoute, constructor(private route: ActivatedRoute,
private taskService: TaskService, private taskService: TaskService,
private workplaceService: WorkplaceService, private workplaceService: WorkplaceService,
private router: Router, private router: Router,
private removeConfirmationService: RemoveConfirmationService, private removeConfirmationService: RemoveConfirmationService,
private requestInProgressService: RequestInProgressService, private requestInProgressService: RequestInProgressService,
private alertService: AlertService, private alertService: AlertService,
private generalModalService: GeneralModalService, private generalModalService: GeneralModalService,
private masterAndDetailService: MasterAndDetailService) { private masterAndDetailService: MasterAndDetailService) {
} }
ngOnInit() { ngOnInit() {
@ -66,10 +66,10 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
} }
resetTask(): void { resetTask(): void {
this.task = { ...this.taskClone }; this.task = {...this.taskClone};
this.task.customAttributes = this.taskClone.customAttributes.slice(0); this.task.customAttributes = this.taskClone.customAttributes.slice(0);
this.task.callbackInfo = this.taskClone.callbackInfo.slice(0); this.task.callbackInfo = this.taskClone.callbackInfo.slice(0);
this.task.primaryObjRef = { ...this.taskClone.primaryObjRef }; this.task.primaryObjRef = {...this.taskClone.primaryObjRef};
this.alertService.triggerAlert(new AlertModel(AlertType.INFO, 'Reset edited fields')); this.alertService.triggerAlert(new AlertModel(AlertType.INFO, 'Reset edited fields'));
} }
@ -97,7 +97,7 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
openTask() { openTask() {
this.router.navigate([{ outlets: { detail: `task/${this.currentId}` } }], { relativeTo: this.route.parent }); this.router.navigate([{outlets: {detail: `task/${this.currentId}`}}], {relativeTo: this.route.parent});
} }
workOnTaskDisabled(): boolean { workOnTaskDisabled(): boolean {
@ -128,7 +128,30 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
backClicked(): void { backClicked(): void {
this.task = undefined; this.task = undefined;
this.taskService.selectTask(this.task); this.taskService.selectTask(this.task);
this.router.navigate(['./'], { relativeTo: this.route.parent }); 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() { private onSave() {
@ -158,7 +181,7 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
this.task = task; this.task = task;
this.taskService.selectTask(this.task); this.taskService.selectTask(this.task);
this.taskService.publishUpdatedTask(task); this.taskService.publishUpdatedTask(task);
this.router.navigate(['../' + task.taskId], { relativeTo: this.route }); this.router.navigate(['../' + task.taskId], {relativeTo: this.route});
}, err => { }, err => {
this.requestInProgressService.setRequestInProgress(false); this.requestInProgressService.setRequestInProgress(false);
this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'There was an error while creating a new task.')) this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'There was an error while creating a new task.'))
@ -172,16 +195,26 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
} }
private cloneTask() { private cloneTask() {
this.taskClone = { ...this.task }; this.taskClone = {...this.task};
this.taskClone.customAttributes = this.task.customAttributes.slice(0); this.taskClone.customAttributes = this.task.customAttributes.slice(0);
this.taskClone.callbackInfo = this.task.callbackInfo.slice(0); this.taskClone.callbackInfo = this.task.callbackInfo.slice(0);
this.taskClone.primaryObjRef = { ...this.task.primaryObjRef }; this.taskClone.primaryObjRef = {...this.task.primaryObjRef};
this.taskClone = this.applyTaskDatesTimeZone(this.taskClone);
} }
ngOnDestroy(): void { ngOnDestroy(): void {
if (this.routeSubscription) { this.routeSubscription.unsubscribe(); } if (this.routeSubscription) {
if (this.workbasketSubscription) { this.workbasketSubscription.unsubscribe(); } this.routeSubscription.unsubscribe();
if (this.masterAndDetailSubscription) { this.masterAndDetailSubscription.unsubscribe(); } }
if (this.deleteTaskSubscription) { this.deleteTaskSubscription.unsubscribe(); } if (this.workbasketSubscription) {
this.workbasketSubscription.unsubscribe();
}
if (this.masterAndDetailSubscription) {
this.masterAndDetailSubscription.unsubscribe();
}
if (this.deleteTaskSubscription) {
this.deleteTaskSubscription.unsubscribe();
}
} }
} }