TSK-682: refined workplace & taskdetailpage
This commit is contained in:
parent
66e25b4bd5
commit
079e7756e1
|
@ -3,7 +3,6 @@ package pro.taskana.rest.resource;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
|
||||
|
@ -37,8 +36,8 @@ public class TaskResource extends ResourceSupport {
|
|||
private boolean isRead;
|
||||
private boolean isTransferred;
|
||||
// All objects have to be serializable
|
||||
private Map<String, String> customAttributes = Collections.emptyMap();
|
||||
private Map<String, String> callbackInfo = Collections.emptyMap();
|
||||
private List<CustomAttribute> customAttributes = Collections.emptyList();
|
||||
private List<CustomAttribute> callbackInfo = Collections.emptyList();
|
||||
private List<AttachmentResource> attachments = new ArrayList<>();
|
||||
private String custom1;
|
||||
private String custom2;
|
||||
|
@ -225,19 +224,19 @@ public class TaskResource extends ResourceSupport {
|
|||
this.isTransferred = isTransferred;
|
||||
}
|
||||
|
||||
public Map<String, String> getCustomAttributes() {
|
||||
public List<CustomAttribute> getCustomAttributes() {
|
||||
return customAttributes;
|
||||
}
|
||||
|
||||
public void setCustomAttributes(Map<String, String> customAttributes) {
|
||||
public void setCustomAttributes(List<CustomAttribute> customAttributes) {
|
||||
this.customAttributes = customAttributes;
|
||||
}
|
||||
|
||||
public Map<String, String> getCallbackInfo() {
|
||||
public List<CustomAttribute> getCallbackInfo() {
|
||||
return callbackInfo;
|
||||
}
|
||||
|
||||
public void setCallbackInfo(Map<String, String> callbackInfo) {
|
||||
public void setCallbackInfo(List<CustomAttribute> callbackInfo) {
|
||||
this.callbackInfo = callbackInfo;
|
||||
}
|
||||
|
||||
|
@ -376,4 +375,33 @@ public class TaskResource extends ResourceSupport {
|
|||
public void setCustom16(String custom16) {
|
||||
this.custom16 = custom16;
|
||||
}
|
||||
|
||||
/**
|
||||
* A CustomAttribute is a user customized attribute which is saved as a Map and can be retreived from
|
||||
* either {@link pro.taskana.Task#getCustomAttributes()} or {@link pro.taskana.Task#getCallbackInfo()}.
|
||||
*/
|
||||
public static class CustomAttribute {
|
||||
|
||||
private final String key;
|
||||
private final String value;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public CustomAttribute() {
|
||||
this(null, null);
|
||||
//necessary for jackson.
|
||||
}
|
||||
|
||||
public CustomAttribute(String key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package pro.taskana.rest.resource.assembler;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -62,6 +64,12 @@ public class TaskResourceAssembler
|
|||
classificationAssembler.toResource(task.getClassificationSummary()));
|
||||
resource.setWorkbasketSummaryResource(workbasketAssembler.toResource(task.getWorkbasketSummary()));
|
||||
resource.setAttachments(attachmentAssembler.toResources(task.getAttachments()));
|
||||
resource.setCustomAttributes(task.getCustomAttributes().entrySet().stream()
|
||||
.map(e -> new TaskResource.CustomAttribute(e.getKey(), e.getValue()))
|
||||
.collect(Collectors.toList()));
|
||||
resource.setCallbackInfo(task.getCallbackInfo().entrySet().stream()
|
||||
.map(e -> new TaskResource.CustomAttribute(e.getKey(), e.getValue()))
|
||||
.collect(Collectors.toList()));
|
||||
try {
|
||||
if (task.getCustomAttribute("1") != null) {
|
||||
resource.setCustom1(task.getCustomAttribute("1"));
|
||||
|
@ -141,6 +149,12 @@ public class TaskResourceAssembler
|
|||
task.setClassificationSummary(classificationAssembler.toModel(resource.getClassificationSummaryResource()));
|
||||
task.setWorkbasketSummary(workbasketAssembler.toModel(resource.getWorkbasketSummaryResource()));
|
||||
task.setAttachments(attachmentAssembler.toModel(resource.getAttachments()));
|
||||
task.setCustomAttributes(resource.getCustomAttributes().stream()
|
||||
.filter(e -> Objects.nonNull(e.getKey()) && !e.getKey().isEmpty())
|
||||
.collect(Collectors.toMap(TaskResource.CustomAttribute::getKey, TaskResource.CustomAttribute::getValue)));
|
||||
task.setCallbackInfo(resource.getCallbackInfo().stream()
|
||||
.filter(e -> Objects.nonNull(e.getKey()) && !e.getKey().isEmpty())
|
||||
.collect(Collectors.toMap(TaskResource.CustomAttribute::getKey, TaskResource.CustomAttribute::getValue)));
|
||||
if (resource.getCustom1() != null) {
|
||||
task.setCustom1(resource.getCustom1());
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<button type="button" (click)="onClear()" class="btn btn-default" data-toggle="tooltip" title="Undo Changes">
|
||||
<span class="glyphicon glyphicon-repeat blue" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" (click)="removeDistributionTargets()" data-toggle="tooltip" title="Remove distribuition target" class="btn btn-default remove">
|
||||
<button type="button" (click)="removeDistributionTargets()" data-toggle="tooltip" title="Remove workbasket as distribuition target" class="btn btn-default remove">
|
||||
<span class="glyphicon glyphicon-remove-circle" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" (click)="copyWorkbasket()" data-toggle="tooltip" title="Copy" class="btn btn-default">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="dropdown">
|
||||
<div class="dropdown dropdown-fix">
|
||||
<button [disabled]="!enabled" class="btn btn-default" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<span class="glyphicon {{sort.sortDirection === 'asc'? 'glyphicon-sort-by-attributes-alt' : 'glyphicon-sort-by-attributes' }} blue"
|
||||
data-toggle="tooltip" title="{{sort.sortDirection === 'asc'? 'A-Z' : 'Z-A' }}"></span>
|
||||
|
@ -16,13 +16,15 @@
|
|||
</button>
|
||||
</div>
|
||||
<div role="separator" class="divider"></div>
|
||||
<li id="sort-by-{{sortingField.key}}" (click)="changeSortBy(sortingField.key)" *ngFor="let sortingField of sortingFields | mapValues">
|
||||
<a>
|
||||
<label>
|
||||
<span class="glyphicon {{sort.sortBy === sortingField.key? 'glyphicon-check': 'glyphicon-unchecked'}} blue" aria-hidden="true"></span>
|
||||
{{sortingField.value}}
|
||||
</label>
|
||||
</a>
|
||||
</li>
|
||||
<ul>
|
||||
<li id="sort-by-{{sortingField.key}}" (click)="changeSortBy(sortingField.key)" *ngFor="let sortingField of sortingFields | mapValues">
|
||||
<a>
|
||||
<label>
|
||||
<span class="glyphicon {{sort.sortBy === sortingField.key? 'glyphicon-check': 'glyphicon-unchecked'}} blue" aria-hidden="true"></span>
|
||||
{{sortingField.value}}
|
||||
</label>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
.dropdown-fix {
|
||||
display: inline-block;
|
||||
vertical-align: center;
|
||||
}
|
||||
|
||||
.sortby-dropdown {
|
||||
min-width: 200px;
|
||||
|
|
|
@ -22,8 +22,8 @@ export class Task {
|
|||
public priority: number,
|
||||
public classificationSummaryResource: Classification,
|
||||
public workbasketSummaryResource: Workbasket,
|
||||
public customAttributes: Object,
|
||||
public callbackInfo: Object,
|
||||
public customAttributes: Array<CustomAttribute> = [],
|
||||
public callbackInfo: Array<CustomAttribute> = [],
|
||||
public custom1: string,
|
||||
public custom2: string,
|
||||
public custom3: string,
|
||||
|
@ -47,20 +47,3 @@ export class CustomAttribute {
|
|||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export function convertToCustomAttributes(callbackInfo: boolean = false): CustomAttribute[] {
|
||||
return Object.keys(callbackInfo ? this.callbackInfo : this.customAttributes)
|
||||
.map(k => ({ key: k, value: (callbackInfo ? this.callbackInfo : this.customAttributes)[k] }));
|
||||
}
|
||||
|
||||
export function saveCustomAttributes(attributes: CustomAttribute[], callbackInfo: boolean = false): void {
|
||||
const att: Object = attributes.filter(attr => attr.key).reduce((acc, obj) => {
|
||||
acc[obj.key] = obj.value;
|
||||
return acc;
|
||||
}, {});
|
||||
if (callbackInfo) {
|
||||
this.callbackInfo = att;
|
||||
} else {
|
||||
this.customAttributes = att;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<ng-container *ngIf="task">
|
||||
<ng-container>
|
||||
<table class="table table-striped table-center">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { convertToCustomAttributes, CustomAttribute, Task } from 'app/workplace/models/task';
|
||||
import { CustomAttribute } from 'app/workplace/models/task';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-task-details-attributes',
|
||||
|
@ -8,20 +8,15 @@ import { convertToCustomAttributes, CustomAttribute, Task } from 'app/workplace/
|
|||
})
|
||||
export class TaskdetailsAttributeComponent implements OnInit {
|
||||
|
||||
@Input() task: Task;
|
||||
@Input() callbackInfo = false;
|
||||
attributes: CustomAttribute[] = [];
|
||||
@Input() attributes: CustomAttribute[] = [];
|
||||
@Output() attributesChange: EventEmitter<CustomAttribute[]> = new EventEmitter<CustomAttribute[]>();
|
||||
|
||||
@Output() notify: EventEmitter<CustomAttribute[]> = new EventEmitter<CustomAttribute[]>();
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.task) {
|
||||
this.attributes = convertToCustomAttributes.bind(this.task)(this.callbackInfo);
|
||||
this.notify.emit(this.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
addAttribute(): void {
|
||||
|
|
|
@ -2,49 +2,49 @@
|
|||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="task-custom1" class="control-label">Custom1</label>
|
||||
<input type="text" class="form-control" id="task-custom1" placeholder="No custom1 set"
|
||||
<input type="text" class="form-control" id="task-custom1" placeholder="Custom1"
|
||||
[(ngModel)]="task.custom1"
|
||||
name="task.custom1">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom2" class="control-label">Custom2</label>
|
||||
<input type="text" class="form-control" id="task-custom2" placeholder="No custom2 set"
|
||||
<input type="text" class="form-control" id="task-custom2" placeholder="Custom2"
|
||||
[(ngModel)]="task.custom2"
|
||||
name="task.custom2">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom3" class="control-label">Custom3</label>
|
||||
<input type="text" class="form-control" id="task-custom3" placeholder="No custom3 set"
|
||||
<input type="text" class="form-control" id="task-custom3" placeholder="Custom3"
|
||||
[(ngModel)]="task.custom3"
|
||||
name="task.custom3">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom4" class="control-label">Custom4</label>
|
||||
<input type="text" class="form-control" id="task-custom4" placeholder="No custom4 set"
|
||||
<input type="text" class="form-control" id="task-custom4" placeholder="Custom4"
|
||||
[(ngModel)]="task.custom4"
|
||||
name="task.custom4">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom5" class="control-label">Custom5</label>
|
||||
<input type="text" class="form-control" id="task-custom5" placeholder="No custom5 set"
|
||||
<input type="text" class="form-control" id="task-custom5" placeholder="Custom5"
|
||||
[(ngModel)]="task.custom5"
|
||||
name="task.custom5">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom6" class="control-label">Custom6</label>
|
||||
<input type="text" class="form-control" id="task-custom6" placeholder="No custom6 set"
|
||||
<input type="text" class="form-control" id="task-custom6" placeholder="Custom6"
|
||||
[(ngModel)]="task.custom6"
|
||||
name="task.custom6">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom7" class="control-label">Custom7</label>
|
||||
<input type="text" class="form-control" id="task-custom7" placeholder="No custom7 set"
|
||||
<input type="text" class="form-control" id="task-custom7" placeholder="Custom7"
|
||||
[(ngModel)]="task.custom7"
|
||||
name="task.custom7">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom8" class="control-label">Custom8</label>
|
||||
<input type="text" class="form-control" id="task-custom8" placeholder="No custom8 set"
|
||||
<input type="text" class="form-control" id="task-custom8" placeholder="Custom8"
|
||||
[(ngModel)]="task.custom8"
|
||||
name="task.custom8">
|
||||
</div>
|
||||
|
@ -52,49 +52,49 @@
|
|||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="task-custom9" class="control-label">Custom9</label>
|
||||
<input type="text" class="form-control" id="task-custom9" placeholder="No custom9 set"
|
||||
<input type="text" class="form-control" id="task-custom9" placeholder="Custom9"
|
||||
[(ngModel)]="task.custom9"
|
||||
name="task.custom9">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom10" class="control-label">Custom10</label>
|
||||
<input type="text" class="form-control" id="task-custom10" placeholder="No custom10 set"
|
||||
<input type="text" class="form-control" id="task-custom10" placeholder="Custom10"
|
||||
[(ngModel)]="task.custom10"
|
||||
name="task.custom10">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom11" class="control-label">Custom11</label>
|
||||
<input type="text" class="form-control" id="task-custom11" placeholder="No custom11 set"
|
||||
<input type="text" class="form-control" id="task-custom11" placeholder="Custom11"
|
||||
[(ngModel)]="task.custom11"
|
||||
name="task.custom11">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom12" class="control-label">Custom12</label>
|
||||
<input type="text" class="form-control" id="task-custom12" placeholder="No custom12 set"
|
||||
<input type="text" class="form-control" id="task-custom12" placeholder="Custom12"
|
||||
[(ngModel)]="task.custom12"
|
||||
name="task.custom12">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom13" class="control-label">Custom13</label>
|
||||
<input type="text" class="form-control" id="task-custom13" placeholder="No custom13 set"
|
||||
<input type="text" class="form-control" id="task-custom13" placeholder="Custom13"
|
||||
[(ngModel)]="task.custom13"
|
||||
name="task.custom13">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom14" class="control-label">Custom14</label>
|
||||
<input type="text" class="form-control" id="task-custom14" placeholder="No custom14 set"
|
||||
<input type="text" class="form-control" id="task-custom14" placeholder="Custom14"
|
||||
[(ngModel)]="task.custom14"
|
||||
name="task.custom14">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom15" class="control-label">Custom15</label>
|
||||
<input type="text" class="form-control" id="task-custom15" placeholder="No custom15 set"
|
||||
<input type="text" class="form-control" id="task-custom15" placeholder="Custom15"
|
||||
[(ngModel)]="task.custom15"
|
||||
name="task.custom15">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-custom16" class="control-label">Custom16</label>
|
||||
<input type="text" class="form-control" id="task-custom16" placeholder="No custom16 set"
|
||||
<input type="text" class="form-control" id="task-custom16" placeholder="Custom16"
|
||||
[(ngModel)]="task.custom16"
|
||||
name="task.custom16">
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { Task } from 'app/workplace/models/task';
|
||||
|
||||
@Component({
|
||||
|
@ -8,6 +8,7 @@ import { Task } from 'app/workplace/models/task';
|
|||
export class TaskdetailsCustomFieldsComponent implements OnInit {
|
||||
|
||||
@Input() task: Task;
|
||||
@Output() taskChange: EventEmitter<Task> = new EventEmitter<Task>();
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
|
|
@ -19,18 +19,18 @@
|
|||
[(ngModel)]="task.priority"
|
||||
name="task.priority">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-state" class="control-label">State</label>
|
||||
<input type="text" disabled class="form-control" id="task-state" placeholder="Task has no State"
|
||||
[(ngModel)]="task.state"
|
||||
name="task.state">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-note" class="control-label">Note</label>
|
||||
<input type="text" class="form-control" id="task-note" placeholder="Task has no Note"
|
||||
[(ngModel)]="task.note"
|
||||
name="task.note">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-state" class="control-label">State</label>
|
||||
<input type="text" disabled class="form-control" id="task-state" placeholder="Task has no State"
|
||||
[(ngModel)]="task.state"
|
||||
name="task.state">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="task-created" class="control-label">Creation Date</label>
|
||||
<input type="text" disabled class="form-control" id="task-created" [(ngModel)]="task.created"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { Task } from 'app/workplace/models/task';
|
||||
|
||||
@Component({
|
||||
|
@ -8,6 +8,7 @@ import { Task } from 'app/workplace/models/task';
|
|||
export class TaskdetailsGeneralFieldsComponent implements OnInit {
|
||||
|
||||
@Input() task: Task;
|
||||
@Output() taskChange: EventEmitter<Task> = new EventEmitter<Task>();
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
|
|
@ -30,15 +30,18 @@
|
|||
</ul>
|
||||
<div class="panel panel-default" *ngIf="task && !requestInProgress">
|
||||
<div class="panel-heading">
|
||||
<div class="pull-right">
|
||||
<div class="pull-right btn-group">
|
||||
<button type="button" (click)="updateTask()" class="btn btn-default btn-primary" data-toggle="tooltip" title="Save">
|
||||
<span class="glyphicon glyphicon-floppy-save" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" title="Open task to work on it" class="btn btn-default" aria-label="Left Align"
|
||||
[disabled]="workOnTaskDisabled()" (click)="openTask(task.taskId)">
|
||||
<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" title="Update Task" class="btn btn-default btn-primary" (click)="updateTask()">
|
||||
<span class="glyphicon glyphicon-saved" aria-hidden="true"></span>
|
||||
<button type="button" (click)="resetTask()" class="btn btn-default" data-toggle="tooltip" title="Undo Changes">
|
||||
<span class="glyphicon glyphicon-repeat blue" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" title="Delete Task" class="btn btn-default btn-danger" (click)="deleteTask()">
|
||||
<button type="button" title="Delete Task" class="btn btn-default remove" (click)="deleteTask()">
|
||||
<span class="glyphicon glyphicon-remove"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -56,12 +59,10 @@
|
|||
<taskana-task-details-custom-fields [task]="task"></taskana-task-details-custom-fields>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" [ngClass]="{'active':tabSelected === 'custom-attributes'}">
|
||||
<taskana-task-details-attributes [task]="task"
|
||||
(notify)="linkAttributes($event)"></taskana-task-details-attributes>
|
||||
<taskana-task-details-attributes [attributes]="task.customAttributes"></taskana-task-details-attributes>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" [ngClass]="{'active':tabSelected === 'callback-info'}">
|
||||
<taskana-task-details-attributes [task]="task" [callbackInfo]="true"
|
||||
(notify)="linkAttributes($event, true)"></taskana-task-details-attributes>
|
||||
<taskana-task-details-attributes [attributes]="task.callbackInfo" [callbackInfo]="true"></taskana-task-details-attributes>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -5,9 +5,12 @@ import { ActivatedRoute, Router } from '@angular/router';
|
|||
import { TaskService } from 'app/workplace/services/task.service';
|
||||
import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service';
|
||||
|
||||
import {convertToCustomAttributes, saveCustomAttributes, CustomAttribute, Task} from 'app/workplace/models/task';
|
||||
import {ErrorModel} from '../../models/modal-error';
|
||||
import {ErrorModalService} from '../../services/errorModal/error-modal.service';
|
||||
import { Task } from 'app/workplace/models/task';
|
||||
import { ErrorModel } from '../../models/modal-error';
|
||||
import { ErrorModalService } from '../../services/errorModal/error-modal.service';
|
||||
import { RequestInProgressService } from '../../services/requestInProgress/request-in-progress.service';
|
||||
import { AlertService } from '../../services/alert/alert.service';
|
||||
import { AlertModel, AlertType } from '../../models/alert';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-task-details',
|
||||
|
@ -16,8 +19,7 @@ import {ErrorModalService} from '../../services/errorModal/error-modal.service';
|
|||
})
|
||||
export class TaskdetailsComponent implements OnInit, OnDestroy {
|
||||
task: Task = null;
|
||||
customAttributes: CustomAttribute[] = [];
|
||||
callbackInfo: CustomAttribute[] = [];
|
||||
taskClone: Task = null;
|
||||
requestInProgress = false;
|
||||
tabSelected = 'general';
|
||||
|
||||
|
@ -28,6 +30,8 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
|
|||
private taskService: TaskService,
|
||||
private router: Router,
|
||||
private removeConfirmationService: RemoveConfirmationService,
|
||||
private requestInProgressService: RequestInProgressService,
|
||||
private alertService: AlertService,
|
||||
private errorModalService: ErrorModalService) {
|
||||
}
|
||||
|
||||
|
@ -38,11 +42,19 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
resetTask(): void {
|
||||
this.task = { ...this.taskClone };
|
||||
this.task.customAttributes = this.taskClone.customAttributes.slice(0);
|
||||
this.task.callbackInfo = this.taskClone.callbackInfo.slice(0);
|
||||
this.alertService.triggerAlert(new AlertModel(AlertType.INFO, 'Reset edited fields'));
|
||||
}
|
||||
|
||||
getTask(id: string): void {
|
||||
this.requestInProgress = true;
|
||||
this.taskService.getTask(id).subscribe(task => {
|
||||
this.requestInProgress = false;
|
||||
this.task = task;
|
||||
this.cloneTask();
|
||||
this.taskService.selectTask(task);
|
||||
}, err => {
|
||||
this.errorModalService.triggerError(
|
||||
|
@ -51,14 +63,14 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
updateTask() {
|
||||
this.requestInProgress = true;
|
||||
saveCustomAttributes.bind(this.task)(this.customAttributes);
|
||||
saveCustomAttributes.bind(this.task)(this.callbackInfo, true);
|
||||
this.requestInProgressService.setRequestInProgress(true);
|
||||
this.taskService.updateTask(this.task).subscribe(task => {
|
||||
this.requestInProgress = false;
|
||||
this.requestInProgressService.setRequestInProgress(false);
|
||||
this.task = task;
|
||||
this.cloneTask();
|
||||
this.taskService.publishUpdatedTask(task);
|
||||
});
|
||||
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, 'Update successful!'))
|
||||
}, err => {this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'Update not successful!'))});
|
||||
}
|
||||
|
||||
openTask(taskId: string) {
|
||||
|
@ -79,7 +91,6 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
|
|||
this.taskService.deleteTask(this.task).subscribe();
|
||||
this.taskService.publishDeletedTask(this.task);
|
||||
this.task = null;
|
||||
this.customAttributes = [];
|
||||
this.router.navigate([`/workplace/tasks`]);
|
||||
}
|
||||
|
||||
|
@ -93,17 +104,15 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
|
|||
this.router.navigate(['./'], { relativeTo: this.route.parent });
|
||||
}
|
||||
|
||||
linkAttributes(attr: CustomAttribute[], callbackInfo: boolean = false): void {
|
||||
if (callbackInfo) {
|
||||
this.callbackInfo = attr;
|
||||
} else {
|
||||
this.customAttributes = attr;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.routeSubscription) {
|
||||
this.routeSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
private cloneTask() {
|
||||
this.taskClone = { ...this.task };
|
||||
this.taskClone.customAttributes = this.task.customAttributes.slice(0);
|
||||
this.taskClone.callbackInfo = this.task.callbackInfo.slice(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
|
||||
<div class="pull-right margin-right">
|
||||
<taskana-sort
|
||||
[enabled]="tasks.length > 0"
|
||||
[enabled]="currentBasket"
|
||||
[sortingFields]="sortingFields"
|
||||
(performSorting)="sorting($event)"></taskana-sort>
|
||||
<button [disabled]="tasks.length === 0" class="btn btn-default collapsed" type="button"
|
||||
<button [disabled]="!currentBasket" class="btn btn-default collapsed" type="button"
|
||||
id="collapsedMenufilterWb" aria-expanded="false"
|
||||
(click)="toolbarState=!toolbarState">
|
||||
<span class="glyphicon glyphicon-filter blue"></span>
|
||||
|
|
|
@ -16,7 +16,6 @@ import { expandDown } from 'app/shared/animations/expand.animation';
|
|||
})
|
||||
export class TaskListToolbarComponent implements OnInit {
|
||||
|
||||
@Output() tasksChanged = new EventEmitter<Task[]>();
|
||||
@Output() basketChanged = new EventEmitter<Workbasket>();
|
||||
@Output() performSorting = new EventEmitter<SortingModel>();
|
||||
@Output() performFilter = new EventEmitter<FilterModel>();
|
||||
|
@ -45,6 +44,14 @@ export class TaskListToolbarComponent implements OnInit {
|
|||
this.workbasketNames.push(workbasket.name);
|
||||
});
|
||||
});
|
||||
this.taskService.getSelectedTask().subscribe(t => {
|
||||
if (!this.result) {
|
||||
this.result = t.workbasketSummaryResource.name;
|
||||
this.resultId = t.workbasketSummaryResource.workbasketId;
|
||||
this.currentBasket = t.workbasketSummaryResource;
|
||||
this.workbasketSelected = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
searchBasket() {
|
||||
|
@ -57,31 +64,14 @@ export class TaskListToolbarComponent implements OnInit {
|
|||
}
|
||||
});
|
||||
|
||||
if (this.resultId.length > 0) {
|
||||
this.getTasks(this.resultId);
|
||||
} else {
|
||||
this.tasks = [];
|
||||
this.currentBasket = null;
|
||||
this.tasksChanged.emit(this.tasks);
|
||||
if (!this.resultId) {
|
||||
this.currentBasket = undefined;
|
||||
}
|
||||
this.basketChanged.emit(this.currentBasket);
|
||||
}
|
||||
this.resultId = '';
|
||||
}
|
||||
|
||||
getTasks(workbasketId: string) {
|
||||
this.taskService.findTasksWithWorkbasket(workbasketId, undefined, undefined,
|
||||
undefined, undefined, undefined, undefined).subscribe(
|
||||
tasks => {
|
||||
this.tasks.length = 0;
|
||||
if (!tasks || tasks._embedded === undefined) {
|
||||
return;
|
||||
}
|
||||
this.tasks = tasks._embedded.tasks;
|
||||
this.tasksChanged.emit(this.tasks);
|
||||
});
|
||||
}
|
||||
|
||||
sorting(sort: SortingModel) {
|
||||
this.performSorting.emit(sort);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="task-list-full-height">
|
||||
<taskana-tasklist-toolbar (tasksChanged)="loadTasks($event)" (basketChanged)="loadBasketID($event)"
|
||||
<taskana-tasklist-toolbar (basketChanged)="loadBasketID($event)"
|
||||
(performSorting)="performSorting($event)"
|
||||
(performFilter)="performFilter($event)">
|
||||
</taskana-tasklist-toolbar>
|
||||
|
|
|
@ -14,7 +14,7 @@ import {FilterModel} from 'app/models/filter';
|
|||
})
|
||||
export class TasklistComponent implements OnInit, OnDestroy {
|
||||
|
||||
@Input() tasks: Task[];
|
||||
tasks: Task[];
|
||||
|
||||
currentBasket: Workbasket;
|
||||
selectedId = '';
|
||||
|
@ -66,17 +66,14 @@ export class TasklistComponent implements OnInit, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
loadTasks(tasks: Task[]) {
|
||||
this.tasks = tasks;
|
||||
selectTask(taskId: string) {
|
||||
this.selectedId = taskId;
|
||||
this.router.navigate([{ outlets: { detail: `taskdetail/${this.selectedId}` } }], { relativeTo: this.route });
|
||||
}
|
||||
|
||||
loadBasketID(workbasket: Workbasket) {
|
||||
this.currentBasket = workbasket;
|
||||
}
|
||||
|
||||
selectTask(taskId: string) {
|
||||
this.selectedId = taskId;
|
||||
this.router.navigate([{outlets: {detail: `taskdetail/${this.selectedId}`}}], {relativeTo: this.route});
|
||||
this.getTasks();
|
||||
}
|
||||
|
||||
performSorting(sort: SortingModel) {
|
||||
|
@ -96,7 +93,7 @@ export class TasklistComponent implements OnInit, OnDestroy {
|
|||
this.filterBy.filterParams.state)
|
||||
.subscribe(tasks => {
|
||||
this.requestInProgress = false;
|
||||
this.tasks = tasks._embedded ? tasks._embedded.tasks : this.tasks;
|
||||
this.tasks = tasks._embedded ? tasks._embedded.tasks : [];
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -342,43 +342,7 @@ li.list-group-item:hover {
|
|||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
.nav.nav-tabs {
|
||||
& > li {
|
||||
& > a {
|
||||
min-height: 52px;
|
||||
padding-top: 15px;
|
||||
border-radius: 0;
|
||||
margin-right: 0;
|
||||
&.has-changes {
|
||||
border-bottom: solid #f0ad4e;
|
||||
}
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:first-child > a {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
|
||||
& > li.active > a {
|
||||
border-top: 3px solid #479ea9;
|
||||
padding-top: 13px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
& > p {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
& > li.disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
& > li.disabled > a {
|
||||
pointer-events: none;
|
||||
}
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn.rounded {
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
.nav.nav-tabs {
|
||||
.nav.nav-tabs {
|
||||
& > li {
|
||||
& > a {
|
||||
min-height: 52px;
|
||||
padding-top: 15px;
|
||||
border-radius: 0px;
|
||||
border-radius: 0;
|
||||
margin-right: 0;
|
||||
&.has-changes{
|
||||
border-bottom: solid #f0ad4e;
|
||||
}
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
&:first-child > a{
|
||||
border-left: none;
|
||||
}
|
||||
|
@ -20,7 +21,7 @@
|
|||
background-color: #f5f5f5;
|
||||
}
|
||||
& > p{
|
||||
margin: 0px;
|
||||
margin: 0;
|
||||
}
|
||||
& > li.disabled {
|
||||
cursor: not-allowed;
|
||||
|
|
Loading…
Reference in New Issue