TSK-1315: Added maxlength validation in workbasket

Also small fixes and formating
This commit is contained in:
Tristan Eisermann 2020-07-22 17:48:20 +02:00 committed by Tristan2357
parent 33845db647
commit 78ba08fd77
5 changed files with 214 additions and 145 deletions

View File

@ -101,11 +101,13 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
onSubmit() { onSubmit() {
this.formsValidatorService.formSubmitAttempt = true; this.formsValidatorService.formSubmitAttempt = true;
this.formsValidatorService.validateFormInformation(this.classificationForm, this.toggleValidationMap).then(value => { this.formsValidatorService
if (value) { .validateFormInformation(this.classificationForm, this.toggleValidationMap)
this.onSave(); .then((value) => {
} if (value) {
}); this.onSave();
}
});
} }
onRestore() { onRestore() {
@ -244,7 +246,10 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
} }
if (model.value.length >= max && !event.altKey && !event.ctrlKey) { if (model.value.length >= max && !event.altKey && !event.ctrlKey) {
this.tooLongMap.set(model.name, true); this.tooLongMap.set(model.name, true);
this.timeout.set(model.name, timer(3000).subscribe(() => this.tooLongMap.set(model.name, false))); this.timeout.set(
model.name,
timer(3000).subscribe(() => this.tooLongMap.set(model.name, false))
);
} }
} }
} }

View File

@ -1,130 +1,168 @@
<taskana-shared-spinner [isRunning]="requestInProgress" class="floating"></taskana-shared-spinner> <taskana-shared-spinner [isRunning]="requestInProgress" class="floating"></taskana-shared-spinner>
<div *ngIf="workbasket" id="wb-information" class="panel panel-default"> <div *ngIf="workbasket" id="wb-information" class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<div class="pull-right btn-group"> <div class="pull-right btn-group">
<button type="button" (click)="onSubmit()" data-toggle="tooltip" title="Save" class="btn btn-default btn-primary"> <button type="button" (click)="onSubmit()" data-toggle="tooltip" title="Save"
<span class="material-icons md-20">save</span> class="btn btn-default btn-primary">
</button> <span class="material-icons md-20">save</span>
<button type="button" (click)="onUndo()" data-toggle="tooltip" title="Undo Changes" class="btn btn-default"> </button>
<span class="material-icons md-20 blue">undo</span> <button type="button" (click)="onUndo()" data-toggle="tooltip" title="Undo Changes"
</button> class="btn btn-default">
<button type="button" (click)="removeDistributionTargets()" data-toggle="tooltip" title="Remove workbasket as distribution target" <span class="material-icons md-20 blue">undo</span>
class="btn btn-default"> </button>
<span class="material-icons md-20 red">remove_circle_outline</span> <button type="button" (click)="removeDistributionTargets()" data-toggle="tooltip"
</button> title="Remove workbasket as distribution target"
<button type="button" (click)="copyWorkbasket()" data-toggle="tooltip" title="Copy" class="btn btn-default"> class="btn btn-default">
<span class="material-icons md-20 green-blue">content_copy</span> <span class="material-icons md-20 red">remove_circle_outline</span>
</button> </button>
<button type="button" (click)="removeWorkbasket()" data-toggle="tooltip" title="Remove" class="btn btn-default"> <button type="button" (click)="copyWorkbasket()" data-toggle="tooltip" title="Copy"
<span class="material-icons md-20 red">delete</span> class="btn btn-default">
</button> <span class="material-icons md-20 green-blue">content_copy</span>
</button>
<button type="button" (click)="removeWorkbasket()" data-toggle="tooltip" title="Remove"
class="btn btn-default">
<span class="material-icons md-20 red">delete</span>
</button>
</div>
<h4 class="panel-header">{{workbasket.name}}&nbsp;
<span *ngIf="!workbasket.workbasketId" class="badge warning"> {{badgeMessage}}</span>
</h4>
</div>
<div class="panel-body">
<form #WorkbasketForm="ngForm">
<div class="col-md-6">
<!-- KEY -->
<div class="form-group required">
<label for="wb-key" class="control-label">Key</label>
<input type="text" required maxlength="64" #key="ngModel" class="form-control" id="wb-key"
placeholder="Key"
[(ngModel)]="workbasket.key" name="workbasket.key" (keypress)="onKeyPressed(key, 64)">
<div *ngIf="tooLongMap.get(key.name)" class="error">{{lengthError}}</div>
<taskana-shared-field-error-display [displayError]="!isFieldValid('workbasket.key')"
[validationTrigger]="this.toogleValidationMap.get('workbasket.key')"
errorMessage="* Key is required">
</taskana-shared-field-error-display>
</div> </div>
<h4 class="panel-header">{{workbasket.name}}&nbsp;
<span *ngIf="!workbasket.workbasketId" class="badge warning"> {{badgeMessage}}</span>
</h4>
</div>
<div class="panel-body"> <!-- NAME -->
<form #WorkbasketForm="ngForm"> <div class="form-group required">
<div class="col-md-6"> <label for="wb-name" class="control-label">Name</label>
<!-- KEY --> <input type="text" required maxlength="255" #name="ngModel" class="form-control" id="wb-name"
<div class="form-group required"> placeholder="Name"
<label for="wb-key" class="control-label">Key</label> [(ngModel)]="workbasket.name" name="workbasket.name" (keypress)="onKeyPressed(name, 255)">
<input type="text" required #key="ngModel" class="form-control" id="wb-key" placeholder="Key" <div *ngIf="tooLongMap.get(name.name)" class="error">{{lengthError}}</div>
[(ngModel)]="workbasket.key" name="workbasket.key"> <taskana-shared-field-error-display [displayError]="!isFieldValid('workbasket.name')"
<taskana-shared-field-error-display [displayError]="!isFieldValid('workbasket.key')" [validationTrigger]="this.toogleValidationMap.get('workbasket.key')" [validationTrigger]="this.toogleValidationMap.get('workbasket.name')"
errorMessage="* Key is required"> errorMessage="* Name is required">
</taskana-shared-field-error-display> </taskana-shared-field-error-display>
</div> </div>
<!-- NAME --> <!-- OWNER -->
<div class="form-group required"> <div class="input-group form-group col-xs-12 required">
<label for="wb-name" class="control-label">Name</label> <label for="wb-owner" class="control-label ">Owner</label>
<input type="text" required #name="ngModel" class="form-control" id="wb-name" placeholder="Name" <taskana-shared-type-ahead *ngIf="lookupField else ownerInput" required maxlength="128" #owner="ngModel"
[(ngModel)]="workbasket.name" name="workbasket.name"> name="workbasket.owner"
<taskana-shared-field-error-display [displayError]="!isFieldValid('workbasket.name')" [validationTrigger]="this.toogleValidationMap.get('workbasket.name')" [(ngModel)]="workbasket.owner"
errorMessage="* Name is required"> placeHolderMessage="* Owner is required"
</taskana-shared-field-error-display> [validationValue]="this.toogleValidationMap.get('workbasket.owner')"
</div> [displayError]="!isFieldValid('workbasket.owner')"
width="100%" (keypress)="onKeyPressed(owner, 128)">
<div *ngIf="tooLongMap.get(owner.name)" class="error">{{lengthError}}</div>
</taskana-shared-type-ahead>
<ng-template #ownerInput>
<input type="text" required maxlength="128" #owner="ngModel" class="form-control" id="wb-owner"
placeholder="Owner"
[(ngModel)]="workbasket.owner" name="workbasket.owner" (keypress)="onKeyPressed(owner, 128)">
<div *ngIf="tooLongMap.get(owner.name)" class="error">{{lengthError}}</div>
<taskana-shared-field-error-display [displayError]="!isFieldValid('workbasket.owner')"
[validationTrigger]="this.toogleValidationMap.get('workbasket.owner')"
errorMessage="* Owner is required">
</taskana-shared-field-error-display>
</ng-template>
</div>
<!-- OWNER --> <!-- DOMAIN -->
<div class="input-group form-group col-xs-12 required"> <div class="form-group ">
<label for="wb-owner" class="control-label ">Owner</label> <label for="wb-domain" class="control-label">Domain</label>
<taskana-shared-type-ahead *ngIf="lookupField else ownerInput" required #owner="ngModel" name="workbasket.owner" <input type="text" #domain="ngModel" class="form-control" disabled id="wb-domain"
[(ngModel)]="workbasket.owner" placeHolderMessage="* Owner is required" [validationValue]="this.toogleValidationMap.get('workbasket.owner')" placeholder="Domain"
[displayError]="!isFieldValid('workbasket.owner')" width="100%"></taskana-shared-type-ahead> [(ngModel)]="workbasket.domain" name="workbasket.domain">
<ng-template #ownerInput> </div>
<input type="text" required #owner="ngModel" class="form-control" id="wb-owner" placeholder="Owner"
[(ngModel)]="workbasket.owner" name="workbasket.owner">
<taskana-shared-field-error-display [displayError]="!isFieldValid('workbasket.owner')"
[validationTrigger]="this.toogleValidationMap.get('workbasket.owner')" errorMessage="* Owner is required">
</taskana-shared-field-error-display>
</ng-template>
</div>
<!-- DOMAIN --> <!-- TYPE & DESCRIPTION-->
<div class="form-group "> <div class="row">
<label for="wb-domain" class="control-label">Domain</label> <div class="form-group col-xs-4">
<input type="text" #domain="ngModel" class="form-control" disabled id="wb-domain" placeholder="Domain" <label class="control-label">Type</label>
[(ngModel)]="workbasket.domain" name="workbasket.domain"> <div class="dropdown">
</div> <button class="btn btn-default" type="button" id="dropdownMenu24"
data-toggle="dropdown"
<!-- TYPE & DESCRIPTION--> aria-haspopup="true" aria-expanded="true">
<div class="row"> <taskana-administration-icon-type
<div class="form-group col-xs-4"> [type]='workbasket.type'></taskana-administration-icon-type>
<label class="control-label">Type</label> {{allTypes.get(workbasket.type)}}
<div class="dropdown"> <span class="caret"></span>
<button class="btn btn-default" type="button" id="dropdownMenu24" data-toggle="dropdown" </button>
aria-haspopup="true" aria-expanded="true"> <ul class="dropdown-menu dropdown-menu" aria-labelledby="dropdownMenu">
<taskana-administration-icon-type [type]='workbasket.type'></taskana-administration-icon-type> <li>
{{allTypes.get(workbasket.type)}} <a *ngFor="let type of allTypes | mapValues | removeEmptyType"
<span class="caret"></span> (click)="selectType(type.key)">
</button> <taskana-administration-icon-type [type]='type.key'
<ul class="dropdown-menu dropdown-menu" aria-labelledby="dropdownMenu"> [text]="type.value"></taskana-administration-icon-type>
<li> </a>
<a *ngFor="let type of allTypes | mapValues | removeEmptyType" (click)="selectType(type.key)"> </li>
<taskana-administration-icon-type [type]='type.key' [text]="type.value"></taskana-administration-icon-type> </ul>
</a>
</li>
</ul>
</div>
</div>
<div class="form-group col-xs-8">
<label for="wb-description" class="control-label">Description</label>
<textarea class="form-control" rows="7" id="wb-description" placeholder="Description"
[(ngModel)]="workbasket.description" name="workbasket.description"></textarea>
</div>
</div>
</div> </div>
<div class="col-md-6"> </div>
<div class="form-group"> <div class="form-group col-xs-8">
<label for="wb-org-level-1" class="control-label">OrgLevel 1</label> <label for="wb-description" class="control-label">Description</label>
<input type="text" class="form-control" id="wb-org-level-1" placeholder="OrgLevel 1" [(ngModel)]="workbasket.orgLevel1" <textarea #description="ngModel" maxlength="255" class="form-control" rows="7" id="wb-description" placeholder="Description"
name="workbasket.orgLevel1"> [(ngModel)]="workbasket.description" name="workbasket.description"
</div> (keypress)="onKeyPressed(description, 255)"></textarea>
<div class="form-group"> <div *ngIf="tooLongMap.get(description.name)" class="error">{{lengthError}}</div>
<label for="wb-org-level-2" class="control-label">OrgLevel 2</label> </div>
<input type="text" class="form-control" id="wb-org-level-2" placeholder="OrgLevel 2" [(ngModel)]="workbasket.orgLevel2" </div>
name="workbasket.orgLevel2"> </div>
</div> <div class="col-md-6">
<div class="form-group" style="padding-top: 18px;"> <div class="form-group">
<label for="wb-org-level-3" class="control-label">OrgLevel 3</label> <label for="wb-org-level-1" class="control-label">OrgLevel 1</label>
<input type="text" class="form-control" id="wb-org-level-3" placeholder="OrgLevel 3" [(ngModel)]="workbasket.orgLevel3" <input type="text" class="form-control" id="wb-org-level-1" placeholder="OrgLevel 1"
name="workbasket.orgLevel3"> [(ngModel)]="workbasket.orgLevel1"
</div> name="workbasket.orgLevel1" maxlength="255" #orgLevel1="ngModel" (keypress)="onKeyPressed(orgLevel1, 255)">
<div class="form-group"> <div *ngIf="tooLongMap.get(orgLevel1.name)" class="error">{{lengthError}}</div>
<label for="wb-org-level-4" class="control-label">OrgLevel 4</label> </div>
<input type="text" class="form-control" id="wb-org-level-4" placeholder="OrgLevel 4" [(ngModel)]="workbasket.orgLevel4" <div class="form-group">
name="workbasket.orgLevel4"> <label for="wb-org-level-2" class="control-label">OrgLevel 2</label>
</div> <input type="text" class="form-control" id="wb-org-level-2" placeholder="OrgLevel 2"
<ng-container *ngFor="let customField of customFields$ | async; let index = index"> [(ngModel)]="workbasket.orgLevel2"
<div *ngIf="customField.visible" class="form-group"> name="workbasket.orgLevel2" maxlength="255" #orgLevel2="ngModel" (keypress)="onKeyPressed(orgLevel2, 255)">
<label for='wb-custom-{{index+1}}' class="control-label">{{customField.field}}</label> <div *ngIf="tooLongMap.get(orgLevel2.name)" class="error">{{lengthError}}</div>
<input type="text" class="form-control" id="wb-custom-{{index+1}}" [placeholder]="customField.field" </div>
[(ngModel)]="workbasket[getWorkbasketCustomProperty(index + 1)]" name="workbasket[{{getWorkbasketCustomProperty(index + 1)}}]"> <div class="form-group" style="padding-top: 18px;">
</div> <label for="wb-org-level-3" class="control-label">OrgLevel 3</label>
</ng-container> <input type="text" class="form-control" id="wb-org-level-3" placeholder="OrgLevel 3"
</div> [(ngModel)]="workbasket.orgLevel3"
</form> name="workbasket.orgLevel3" maxlength="255" #orgLevel3="ngModel" (keypress)="onKeyPressed(orgLevel3, 255)">
</div> <div *ngIf="tooLongMap.get(orgLevel3.name)" class="error">{{lengthError}}</div>
</div>
<div class="form-group">
<label for="wb-org-level-4" class="control-label">OrgLevel 4</label>
<input type="text" class="form-control" id="wb-org-level-4" placeholder="OrgLevel 4"
[(ngModel)]="workbasket.orgLevel4"
name="workbasket.orgLevel4" maxlength="255" #orgLevel4="ngModel" (keypress)="onKeyPressed(orgLevel4, 255)">
<div *ngIf="tooLongMap.get(orgLevel4.name)" class="error">{{lengthError}}</div>
</div>
<ng-container *ngFor="let customField of customFields$ | async; let index = index">
<div *ngIf="customField.visible" class="form-group">
<label for='wb-custom-{{index+1}}' class="control-label">{{customField.field}}</label>
<input type="text" class="form-control" id="wb-custom-{{index+1}}"
[placeholder]="customField.field"
[(ngModel)]="workbasket[getWorkbasketCustomProperty(index + 1)]"
name="workbasket[{{getWorkbasketCustomProperty(index + 1)}}]" maxlength="255" #custom="ngModel" (keypress)="onKeyPressed(custom, 255)">
<div *ngIf="tooLongMap.get(custom.name)" class="error">{{lengthError}}</div>
</div>
</ng-container>
</div>
</form>
</div>
</div> </div>

View File

@ -1,7 +1,7 @@
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core'; import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { Observable, Subject, Subscription } from 'rxjs'; import { Observable, Subject, Subscription, timer } from 'rxjs';
import { NgForm } from '@angular/forms'; import { NgForm, NgModel } from '@angular/forms';
import { Select, Store } from '@ngxs/store'; import { Select, Store } from '@ngxs/store';
import { ICONTYPES } from 'app/shared/models/icon-types'; import { ICONTYPES } from 'app/shared/models/icon-types';
@ -53,6 +53,9 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
customFields$: Observable<CustomField[]>; customFields$: Observable<CustomField[]>;
destroy$ = new Subject<void>(); destroy$ = new Subject<void>();
readonly lengthError = 'You have reached the maximum length';
tooLongMap = new Map<string, boolean>();
private timeout = new Map<string, Subscription>();
constructor( constructor(
private workbasketService: WorkbasketService, private workbasketService: WorkbasketService,
@ -187,4 +190,18 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
this.destroy$.next(); this.destroy$.next();
this.destroy$.complete(); this.destroy$.complete();
} }
onKeyPressed(model: NgModel, max: Number): void {
if (this.timeout.has(model.name)) {
this.timeout.get(model.name).unsubscribe();
}
console.log(model.name);
if (model.value.length >= max) {
this.tooLongMap.set(model.name, true);
this.timeout.set(
model.name,
timer(3000).subscribe(() => this.tooLongMap.set(model.name, false))
);
}
}
} }

View File

@ -2,7 +2,7 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Task } from 'app/workplace/models/task'; import { Task } from 'app/workplace/models/task';
@Component({ @Component({
selector: 'taskana-general-fields-extension', selector: 'taskana-task-details-general-fields-extension',
templateUrl: './general-fields-extension.component.html', templateUrl: './general-fields-extension.component.html',
styleUrls: ['./general-fields-extension.component.scss'] styleUrls: ['./general-fields-extension.component.scss']
}) })

View File

@ -1,5 +1,6 @@
<taskana-shared-spinner [isRunning]="requestInProgress"></taskana-shared-spinner> <taskana-shared-spinner [isRunning]="requestInProgress"></taskana-shared-spinner>
<div class="panel panel-default" *ngIf="task && !requestInProgress"> <div class="panel panel-default" *ngIf="task && !requestInProgress">
<!--Buttonbar-->
<div class="panel-heading"> <div class="panel-heading">
<div *ngIf="showDetail" class="pull-left btn-group align-header"> <div *ngIf="showDetail" class="pull-left btn-group align-header">
<button (click)="backClicked()" class="btn btn-default no-style blue visible-xs visible-sm hidden"> <button (click)="backClicked()" class="btn btn-default no-style blue visible-xs visible-sm hidden">
@ -8,12 +9,12 @@
</div> </div>
<div class="pull-right btn-group"> <div class="pull-right btn-group">
<button type="button" (click)="toggleFormValidation = !toggleFormValidation" class="btn btn-default btn-primary" <button type="button" (click)="toggleFormValidation = !toggleFormValidation" class="btn btn-default btn-primary"
data-toggle="tooltip" title="Save"> data-toggle="tooltip" title="Save">
<span class="material-icons md-20 white">save</span> <span class="material-icons md-20 white">save</span>
</button> </button>
<ng-container *ngIf="currentId != 'new-task'"> <ng-container *ngIf="currentId != 'new-task'">
<button type="button" title="Open task to work on it" class="btn btn-default" aria-label="Left Align" <button type="button" title="Open task to work on it" class="btn btn-default" aria-label="Left Align"
[disabled]="workOnTaskDisabled()" (click)="openTask()"> [disabled]="workOnTaskDisabled()" (click)="openTask()">
<span class="material-icons md-20 blue">open_in_new</span> <span class="material-icons md-20 blue">open_in_new</span>
</button> </button>
<button type="button" (click)="resetTask()" class="btn btn-default" data-toggle="tooltip" title="Undo Changes"> <button type="button" (click)="resetTask()" class="btn btn-default" data-toggle="tooltip" title="Undo Changes">
@ -28,47 +29,55 @@
<span *ngIf="!task.taskId" class="badge warning"> {{'Creating Task'}}</span> <span *ngIf="!task.taskId" class="badge warning"> {{'Creating Task'}}</span>
</h4> </h4>
</div> </div>
<!--Accordion Fields for Sectioned View of Data-->
<div class="panel-body"> <div class="panel-body">
<accordion *ngIf="task && !requestInProgress"> <accordion *ngIf="task && !requestInProgress">
<!--Information-->
<accordion-group panelClass="customClass" isOpen="true" (isOpenChange)="accordion1State = $event"> <accordion-group panelClass="customClass" isOpen="true" (isOpenChange)="accordion1State = $event">
<button class="btn btn-block clearfix" accordion-heading> <button class="btn btn-block clearfix" accordion-heading>
<div class="pull-left float-left">1 - Information</div> <div class="pull-left float-left">1 - Information</div>
<span class="float-right pull-right material-icons md-20 blue">{{accordion1State? <span class="float-right pull-right material-icons md-20 blue">{{accordion1State ?
'expand_more':'expand_less'}}</span> 'expand_more' : 'expand_less'}}</span>
</button> </button>
<taskana-task-details-general-fields [task]="task" [saveToggleTriggered]="toggleFormValidation" (formValid)="onSubmit()"></taskana-task-details-general-fields> <taskana-task-details-general-fields [task]="task" [saveToggleTriggered]="toggleFormValidation"
(formValid)="onSubmit()"></taskana-task-details-general-fields>
</accordion-group> </accordion-group>
<!--Status Details-->
<accordion-group panelClass="customClass" (isOpenChange)="accordion2State = $event"> <accordion-group panelClass="customClass" (isOpenChange)="accordion2State = $event">
<button class="btn btn-block clearfix" accordion-heading> <button class="btn btn-block clearfix" accordion-heading>
<div class="pull-left float-left">2 - Status details</div> <div class="pull-left float-left">2 - Status details</div>
<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]="taskClone"></taskana-general-fields-extension> <taskana-task-details-general-fields-extension [task]="task"></taskana-task-details-general-fields-extension>
</accordion-group> </accordion-group>
<!--Custom Fields-->
<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>
<div class="pull-left float-left">3 - Custom fields</div> <div class="pull-left float-left">3 - Custom fields</div>
<span class="float-right pull-right material-icons md-20 blue">{{accordion3State? <span class="float-right pull-right material-icons md-20 blue">{{accordion3State ?
'expand_more':'expand_less'}}</span> 'expand_more' : 'expand_less'}}</span>
</button> </button>
<taskana-task-details-custom-fields [task]="task"></taskana-task-details-custom-fields> <taskana-task-details-custom-fields [task]="task"></taskana-task-details-custom-fields>
</accordion-group> </accordion-group>
<!--Custom Attributes-->
<accordion-group panelClass="customClass" (isOpenChange)="accordion4State = $event"> <accordion-group panelClass="customClass" (isOpenChange)="accordion4State = $event">
<button class="btn btn-block clearfix" accordion-heading> <button class="btn btn-block clearfix" accordion-heading>
<div class="pull-left float-left">4 - Custom attributes</div> <div class="pull-left float-left">4 - Custom attributes</div>
<span class="float-right pull-right material-icons md-20 blue">{{accordion4State? <span class="float-right pull-right material-icons md-20 blue">{{accordion4State ?
'expand_more':'expand_less'}}</span> 'expand_more' : 'expand_less'}}</span>
</button> </button>
<taskana-task-details-attributes [attributes]="task.customAttributes"></taskana-task-details-attributes> <taskana-task-details-attributes [attributes]="task.customAttributes"></taskana-task-details-attributes>
</accordion-group> </accordion-group>
<!--Callback Information-->
<accordion-group panelClass="customClass" (isOpenChange)="accordion5State = $event"> <accordion-group panelClass="customClass" (isOpenChange)="accordion5State = $event">
<button class="btn btn-block clearfix" accordion-heading> <button class="btn btn-block clearfix" accordion-heading>
<div class="pull-left float-left">5 - Callback information</div> <div class="pull-left float-left">5 - Callback information</div>
<span class="float-right pull-right material-icons md-20 blue">{{accordion5State? <span class="float-right pull-right material-icons md-20 blue">{{accordion5State ?
'expand_more':'expand_less'}}</span> 'expand_more' : 'expand_less'}}</span>
</button> </button>
<taskana-task-details-attributes [attributes]="task.callbackInfo" [callbackInfo]="true"></taskana-task-details-attributes> <taskana-task-details-attributes [attributes]="task.callbackInfo"
[callbackInfo]="true"></taskana-task-details-attributes>
</accordion-group> </accordion-group>
</accordion> </accordion>
</div> </div>