TSK-1436: adapted breaking changes for frontend
This commit is contained in:
parent
41d956c633
commit
3172f9f1bc
|
@ -1,8 +1,5 @@
|
||||||
package pro.taskana.rest;
|
package pro.taskana.rest;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
|
@ -21,6 +18,10 @@ import org.springframework.web.filter.CorsFilter;
|
||||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class ExampleWebSecurityConfig {
|
public class ExampleWebSecurityConfig {
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ public class ExampleWebSecurityConfig {
|
||||||
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
CorsConfiguration config = new CorsConfiguration();
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
config.setAllowCredentials(true);
|
config.setAllowCredentials(true);
|
||||||
config.addAllowedOrigin("*");
|
config.addAllowedOriginPattern("*");
|
||||||
config.addAllowedHeader("*");
|
config.addAllowedHeader("*");
|
||||||
config.addAllowedMethod("*");
|
config.addAllowedMethod("*");
|
||||||
source.registerCorsConfiguration("/**", config);
|
source.registerCorsConfiguration("/**", config);
|
||||||
|
|
|
@ -3,8 +3,11 @@ package pro.taskana.common.rest.assembler;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
import org.springframework.hateoas.Link;
|
||||||
import org.springframework.hateoas.RepresentationModel;
|
import org.springframework.hateoas.RepresentationModel;
|
||||||
import org.springframework.hateoas.server.RepresentationModelAssembler;
|
import org.springframework.hateoas.server.RepresentationModelAssembler;
|
||||||
|
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
import pro.taskana.common.rest.models.CollectionRepresentationModel;
|
import pro.taskana.common.rest.models.CollectionRepresentationModel;
|
||||||
|
|
||||||
|
@ -17,6 +20,16 @@ public interface CollectionRepresentationModelAssembler<
|
||||||
default C toTaskanaCollectionModel(Iterable<T> entities) {
|
default C toTaskanaCollectionModel(Iterable<T> entities) {
|
||||||
return StreamSupport.stream(entities.spliterator(), false)
|
return StreamSupport.stream(entities.spliterator(), false)
|
||||||
.map(this::toModel)
|
.map(this::toModel)
|
||||||
.collect(Collectors.collectingAndThen(Collectors.toList(), this::buildCollectionEntity));
|
.collect(
|
||||||
|
Collectors.collectingAndThen(
|
||||||
|
Collectors.toList(),
|
||||||
|
content -> addLinksToCollectionModel(buildCollectionEntity(content))));
|
||||||
|
}
|
||||||
|
|
||||||
|
default C addLinksToCollectionModel(C model) {
|
||||||
|
final UriComponentsBuilder original = ServletUriComponentsBuilder.fromCurrentRequest();
|
||||||
|
|
||||||
|
model.add(Link.of(original.toUriString()).withSelfRel());
|
||||||
|
return model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.ParameterizedTypeReference;
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
import org.springframework.core.io.FileSystemResource;
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.hateoas.IanaLinkRelations;
|
||||||
import org.springframework.hateoas.Links;
|
import org.springframework.hateoas.Links;
|
||||||
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpEntity;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
|
@ -102,7 +103,7 @@ class ClassificationDefinitionControllerIntTest {
|
||||||
ClassificationDefinitionCollectionRepresentationModel.class));
|
ClassificationDefinitionCollectionRepresentationModel.class));
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(response.getBody()).isNotNull();
|
assertThat(response.getBody()).isNotNull();
|
||||||
assertThat(response.getBody().getLinks()).isEmpty();
|
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isPresent();
|
||||||
assertThat(response.getBody().getContent())
|
assertThat(response.getBody().getContent())
|
||||||
.extracting(ClassificationDefinitionRepresentationModel::getClassification)
|
.extracting(ClassificationDefinitionRepresentationModel::getClassification)
|
||||||
.extracting(ClassificationRepresentationModel::getLinks)
|
.extracting(ClassificationRepresentationModel::getLinks)
|
||||||
|
|
|
@ -34,7 +34,7 @@ class ClassificationDefinitionControllerRestDocTest extends BaseRestDocTest {
|
||||||
classification.setServiceLevel("P1D");
|
classification.setServiceLevel("P1D");
|
||||||
|
|
||||||
ClassificationCollectionRepresentationModel importCollection =
|
ClassificationCollectionRepresentationModel importCollection =
|
||||||
assembler.toTaskanaCollectionModel(List.of(classification));
|
new ClassificationCollectionRepresentationModel(List.of(assembler.toModel(classification)));
|
||||||
|
|
||||||
this.mockMvc
|
this.mockMvc
|
||||||
.perform(
|
.perform(
|
||||||
|
|
|
@ -103,7 +103,8 @@ class WorkbasketControllerRestDocTest extends BaseRestDocTest {
|
||||||
accessItem.setPermission(WorkbasketPermission.OPEN, true);
|
accessItem.setPermission(WorkbasketPermission.OPEN, true);
|
||||||
|
|
||||||
WorkbasketAccessItemCollectionRepresentationModel repModel =
|
WorkbasketAccessItemCollectionRepresentationModel repModel =
|
||||||
accessItemAssembler.toTaskanaCollectionModel(List.of(accessItem));
|
new WorkbasketAccessItemCollectionRepresentationModel(
|
||||||
|
List.of(accessItemAssembler.toModel(accessItem)));
|
||||||
|
|
||||||
mockMvc
|
mockMvc
|
||||||
.perform(
|
.perform(
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.core.ParameterizedTypeReference;
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
import org.springframework.core.io.FileSystemResource;
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.hateoas.IanaLinkRelations;
|
||||||
import org.springframework.hateoas.Links;
|
import org.springframework.hateoas.Links;
|
||||||
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpEntity;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
|
@ -102,7 +103,7 @@ class WorkbasketDefinitionControllerIntTest {
|
||||||
executeExportRequestForDomain("DOMAIN_A");
|
executeExportRequestForDomain("DOMAIN_A");
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(response.getBody()).isNotNull();
|
assertThat(response.getBody()).isNotNull();
|
||||||
assertThat(response.getBody().getLinks()).isEmpty();
|
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isPresent();
|
||||||
assertThat(response.getBody().getContent())
|
assertThat(response.getBody().getContent())
|
||||||
.extracting(WorkbasketDefinitionRepresentationModel::getWorkbasket)
|
.extracting(WorkbasketDefinitionRepresentationModel::getWorkbasket)
|
||||||
.extracting(WorkbasketRepresentationModel::getLinks)
|
.extracting(WorkbasketRepresentationModel::getLinks)
|
||||||
|
|
|
@ -20,7 +20,10 @@
|
||||||
"main": "src/main.ts",
|
"main": "src/main.ts",
|
||||||
"tsConfig": "src/tsconfig.app.json",
|
"tsConfig": "src/tsconfig.app.json",
|
||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"assets": ["src/assets", "src/environments/data-sources"],
|
"assets": [
|
||||||
|
"src/assets",
|
||||||
|
"src/environments/data-sources"
|
||||||
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
||||||
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
|
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||||
|
@ -80,7 +83,10 @@
|
||||||
"lint": {
|
"lint": {
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
"options": {
|
"options": {
|
||||||
"tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"],
|
"tsConfig": [
|
||||||
|
"src/tsconfig.app.json",
|
||||||
|
"src/tsconfig.spec.json"
|
||||||
|
],
|
||||||
"exclude": []
|
"exclude": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,11 +101,14 @@
|
||||||
"defaultProject": "taskana-web",
|
"defaultProject": "taskana-web",
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"@schematics/angular:component": {
|
"@schematics/angular:component": {
|
||||||
"prefix": "app",
|
"prefix": "taskana",
|
||||||
"style": "scss"
|
"style": "scss"
|
||||||
},
|
},
|
||||||
"@schematics/angular:directive": {
|
"@schematics/angular:directive": {
|
||||||
"prefix": "app"
|
"prefix": "taskana"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"cli": {
|
||||||
|
"analytics": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th class="align-left">
|
<th class="align-left">
|
||||||
<taskana-shared-sort [sortingFields]="sortingFields" (performSorting)="sorting($event)"
|
<taskana-shared-sort [sortingFields]="sortingFields" (performSorting)="sorting($event)"
|
||||||
menuPosition="left" defaultSortBy="access-id">
|
menuPosition="left" [defaultSortBy]="defaultSortBy">
|
||||||
</taskana-shared-sort>
|
</taskana-shared-sort>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
|
@ -124,4 +124,4 @@
|
||||||
</ng-form>
|
</ng-form>
|
||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { AccessItemsManagementComponent } from './access-items-management.component';
|
import { AccessItemsManagementComponent } from './access-items-management.component';
|
||||||
import { FormsValidatorService } from '../../../shared/services/forms-validator/forms-validator.service';
|
import { FormsValidatorService } from '../../../shared/services/forms-validator/forms-validator.service';
|
||||||
import { Actions, NgxsModule, ofActionDispatched, Store } from '@ngxs/store';
|
import { Actions, NgxsModule, ofActionDispatched, Store } from '@ngxs/store';
|
||||||
|
@ -14,11 +14,11 @@ import { AccessItemsManagementState } from '../../../shared/store/access-items-m
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { GetAccessItems } from '../../../shared/store/access-items-management-store/access-items-management.actions';
|
import { GetAccessItems } from '../../../shared/store/access-items-management-store/access-items-management.actions';
|
||||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||||
import { TypeAheadComponent } from '../../../shared/components/type-ahead/type-ahead.component';
|
import { TypeAheadComponent } from '../../../shared/components/type-ahead/type-ahead.component';
|
||||||
import { TypeaheadModule } from 'ngx-bootstrap';
|
import { TypeaheadModule } from 'ngx-bootstrap';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { Direction, Sorting } from '../../../shared/models/sorting';
|
import { Direction, Sorting, WorkbasketAccessItemQuerySortParameter } from '../../../shared/models/sorting';
|
||||||
import { StartupService } from '../../../shared/services/startup/startup.service';
|
import { StartupService } from '../../../shared/services/startup/startup.service';
|
||||||
import { TaskanaEngineService } from '../../../shared/services/taskana-engine/taskana-engine.service';
|
import { TaskanaEngineService } from '../../../shared/services/taskana-engine/taskana-engine.service';
|
||||||
import { WindowRefService } from '../../../shared/services/window/window.service';
|
import { WindowRefService } from '../../../shared/services/window/window.service';
|
||||||
|
@ -62,8 +62,9 @@ describe('AccessItemsManagementComponent', () => {
|
||||||
|
|
||||||
@Component({ selector: 'taskana-shared-sort', template: '' })
|
@Component({ selector: 'taskana-shared-sort', template: '' })
|
||||||
class TaskanaSharedSortStub {
|
class TaskanaSharedSortStub {
|
||||||
@Input() sortingFields: Map<string, string>;
|
@Input() sortingFields: Map<WorkbasketAccessItemQuerySortParameter, string>;
|
||||||
@Output() performSorting = new EventEmitter<Sorting>();
|
@Input() defaultSortBy: WorkbasketAccessItemQuerySortParameter;
|
||||||
|
@Output() performSorting = new EventEmitter<Sorting<WorkbasketAccessItemQuerySortParameter>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
|
@ -159,7 +160,7 @@ describe('AccessItemsManagementComponent', () => {
|
||||||
{ accessId: '1', name: 'users' },
|
{ accessId: '1', name: 'users' },
|
||||||
{ accessId: '2', name: 'users' }
|
{ accessId: '2', name: 'users' }
|
||||||
];
|
];
|
||||||
app.sortModel = { sortBy: 'access-id', sortDirection: 'desc' };
|
app.sortModel = { 'sort-by': WorkbasketAccessItemQuerySortParameter.ACCESS_ID, order: Direction.DESC };
|
||||||
app.searchForAccessItemsWorkbaskets();
|
app.searchForAccessItemsWorkbaskets();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let actionDispatched = false;
|
let actionDispatched = false;
|
||||||
|
@ -188,7 +189,10 @@ describe('AccessItemsManagementComponent', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should invoke sorting function correctly', () => {
|
it('should invoke sorting function correctly', () => {
|
||||||
const newSort = new Sorting('access-id', Direction.DESC);
|
const newSort: Sorting<WorkbasketAccessItemQuerySortParameter> = {
|
||||||
|
'sort-by': WorkbasketAccessItemQuerySortParameter.ACCESS_ID,
|
||||||
|
order: Direction.DESC
|
||||||
|
};
|
||||||
app.accessId = { accessId: '1', name: 'max' };
|
app.accessId = { accessId: '1', name: 'max' };
|
||||||
app.groups = [{ accessId: '1', name: 'users' }];
|
app.groups = [{ accessId: '1', name: 'users' }];
|
||||||
app.sorting(newSort);
|
app.sorting(newSort);
|
||||||
|
|
|
@ -4,7 +4,12 @@ import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@ang
|
||||||
import { Observable, Subject } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
import { FormsValidatorService } from 'app/shared/services/forms-validator/forms-validator.service';
|
import { FormsValidatorService } from 'app/shared/services/forms-validator/forms-validator.service';
|
||||||
import { WorkbasketAccessItems } from 'app/shared/models/workbasket-access-items';
|
import { WorkbasketAccessItems } from 'app/shared/models/workbasket-access-items';
|
||||||
import { Direction, Sorting } from 'app/shared/models/sorting';
|
import {
|
||||||
|
Direction,
|
||||||
|
Sorting,
|
||||||
|
WORKBASKET_ACCESS_ITEM_SORT_PARAMETER_NAMING,
|
||||||
|
WorkbasketAccessItemQuerySortParameter
|
||||||
|
} from 'app/shared/models/sorting';
|
||||||
import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors';
|
import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
import { AccessIdDefinition } from '../../../shared/models/access-id';
|
import { AccessIdDefinition } from '../../../shared/models/access-id';
|
||||||
|
@ -18,6 +23,7 @@ import {
|
||||||
} from '../../../shared/store/access-items-management-store/access-items-management.actions';
|
} from '../../../shared/store/access-items-management-store/access-items-management.actions';
|
||||||
import { AccessItemsManagementSelector } from '../../../shared/store/access-items-management-store/access-items-management.selector';
|
import { AccessItemsManagementSelector } from '../../../shared/store/access-items-management-store/access-items-management.selector';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { WorkbasketAccessItemQueryFilterParameter } from '../../../shared/models/workbasket-access-item-query-filter-parameter';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-access-items-management',
|
selector: 'taskana-administration-access-items-management',
|
||||||
|
@ -31,20 +37,19 @@ export class AccessItemsManagementComponent implements OnInit {
|
||||||
accessIdName: string;
|
accessIdName: string;
|
||||||
panelState: boolean = false;
|
panelState: boolean = false;
|
||||||
accessItemsForm: FormGroup;
|
accessItemsForm: FormGroup;
|
||||||
toggleValidationAccessIdMap = new Map<number, boolean>();
|
|
||||||
accessId: AccessIdDefinition;
|
accessId: AccessIdDefinition;
|
||||||
groups: AccessIdDefinition[];
|
groups: AccessIdDefinition[];
|
||||||
sortingFields = new Map([
|
defaultSortBy: WorkbasketAccessItemQuerySortParameter = WorkbasketAccessItemQuerySortParameter.ACCESS_ID;
|
||||||
['access-id', 'Access id'],
|
sortingFields: Map<WorkbasketAccessItemQuerySortParameter, string> = WORKBASKET_ACCESS_ITEM_SORT_PARAMETER_NAMING;
|
||||||
['workbasket-key', 'Workbasket Key']
|
sortModel: Sorting<WorkbasketAccessItemQuerySortParameter> = {
|
||||||
]);
|
'sort-by': this.defaultSortBy,
|
||||||
sortModel: Sorting = new Sorting('access-id', Direction.DESC);
|
order: Direction.DESC
|
||||||
|
};
|
||||||
accessItems: WorkbasketAccessItems[];
|
accessItems: WorkbasketAccessItems[];
|
||||||
isGroup: boolean = false;
|
isGroup: boolean = false;
|
||||||
|
|
||||||
@Select(EngineConfigurationSelectors.accessItemsCustomisation) accessItemsCustomization$: Observable<
|
@Select(EngineConfigurationSelectors.accessItemsCustomisation)
|
||||||
AccessItemsCustomisation
|
accessItemsCustomization$: Observable<AccessItemsCustomisation>;
|
||||||
>;
|
|
||||||
@Select(AccessItemsManagementSelector.groups) groups$: Observable<AccessIdDefinition[]>;
|
@Select(AccessItemsManagementSelector.groups) groups$: Observable<AccessIdDefinition[]>;
|
||||||
customFields$: Observable<CustomField[]>;
|
customFields$: Observable<CustomField[]>;
|
||||||
destroy$ = new Subject<void>();
|
destroy$ = new Subject<void>();
|
||||||
|
@ -81,15 +86,16 @@ export class AccessItemsManagementComponent implements OnInit {
|
||||||
|
|
||||||
searchForAccessItemsWorkbaskets() {
|
searchForAccessItemsWorkbaskets() {
|
||||||
this.removeFocus();
|
this.removeFocus();
|
||||||
this.store
|
const filterParameter: WorkbasketAccessItemQueryFilterParameter = {
|
||||||
.dispatch(new GetAccessItems([this.accessId, ...this.groups], '', '', this.sortModel))
|
'access-id': [this.accessId, ...this.groups].map((a) => a.accessId)
|
||||||
.subscribe((state) => {
|
};
|
||||||
this.setAccessItemsGroups(
|
this.store.dispatch(new GetAccessItems(filterParameter, this.sortModel)).subscribe((state) => {
|
||||||
state['accessItemsManagement'].accessItemsResource
|
this.setAccessItemsGroups(
|
||||||
? state['accessItemsManagement'].accessItemsResource.accessItems
|
state['accessItemsManagement'].accessItemsResource
|
||||||
: []
|
? state['accessItemsManagement'].accessItemsResource.accessItems
|
||||||
);
|
: []
|
||||||
});
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setAccessItemsGroups(accessItems: Array<WorkbasketAccessItems>) {
|
setAccessItemsGroups(accessItems: Array<WorkbasketAccessItems>) {
|
||||||
|
@ -150,7 +156,7 @@ export class AccessItemsManagementComponent implements OnInit {
|
||||||
return this.formsValidatorService.isFieldValid(this.accessItemsGroups[index], field);
|
return this.formsValidatorService.isFieldValid(this.accessItemsGroups[index], field);
|
||||||
}
|
}
|
||||||
|
|
||||||
sorting(sort: Sorting) {
|
sorting(sort: Sorting<WorkbasketAccessItemQuerySortParameter>) {
|
||||||
this.sortModel = sort;
|
this.sortModel = sort;
|
||||||
this.searchForAccessItemsWorkbaskets();
|
this.searchForAccessItemsWorkbaskets();
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,12 +177,12 @@
|
||||||
<mat-select required [(value)]="this.classification.category">
|
<mat-select required [(value)]="this.classification.category">
|
||||||
<mat-select-trigger>
|
<mat-select-trigger>
|
||||||
<svg-icon
|
<svg-icon
|
||||||
class="detailed-fields__category-icon" [src]="(getCategoryIcon(this.classification.category) | async)?.name">
|
class="detailed-fields__category-icon" [src]="(getCategoryIcon(this.classification.category) | async)?.left">
|
||||||
</svg-icon>
|
</svg-icon>
|
||||||
{{this.classification.category}}
|
{{this.classification.category}}
|
||||||
</mat-select-trigger>
|
</mat-select-trigger>
|
||||||
<mat-option *ngFor="let category of categories$ | async" value="{{category}}">
|
<mat-option *ngFor="let category of categories$ | async" value="{{category}}">
|
||||||
<svg-icon class="detailed-fields__category-icon" [src]="(getCategoryIcon(category) | async)?.name"></svg-icon>
|
<svg-icon class="detailed-fields__category-icon" [src]="(getCategoryIcon(category) | async)?.left"></svg-icon>
|
||||||
{{category}}
|
{{category}}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
|
|
|
@ -185,8 +185,8 @@ describe('ClassificationDetailsComponent', () => {
|
||||||
it('should return icon for category when getCategoryIcon() is called and category exists', (done) => {
|
it('should return icon for category when getCategoryIcon() is called and category exists', (done) => {
|
||||||
const categoryIcon = component.getCategoryIcon('AUTOMATIC');
|
const categoryIcon = component.getCategoryIcon('AUTOMATIC');
|
||||||
categoryIcon.subscribe((iconPair) => {
|
categoryIcon.subscribe((iconPair) => {
|
||||||
expect(iconPair.name).toBe('assets/icons/categories/automatic.svg');
|
expect(iconPair.left).toBe('assets/icons/categories/automatic.svg');
|
||||||
expect(iconPair.text).toBe('AUTOMATIC');
|
expect(iconPair.right).toBe('AUTOMATIC');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -194,7 +194,7 @@ describe('ClassificationDetailsComponent', () => {
|
||||||
it('should return icon when getCategoryIcon() is called and category does not exist', (done) => {
|
it('should return icon when getCategoryIcon() is called and category does not exist', (done) => {
|
||||||
const categoryIcon = component.getCategoryIcon('WATER');
|
const categoryIcon = component.getCategoryIcon('WATER');
|
||||||
categoryIcon.subscribe((iconPair) => {
|
categoryIcon.subscribe((iconPair) => {
|
||||||
expect(iconPair.name).toBe('assets/icons/categories/missing-icon.svg');
|
expect(iconPair.left).toBe('assets/icons/categories/missing-icon.svg');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,7 +7,6 @@ import { highlight } from 'app/shared/animations/validation.animation';
|
||||||
import { RequestInProgressService } from 'app/shared/services/request-in-progress/request-in-progress.service';
|
import { RequestInProgressService } from 'app/shared/services/request-in-progress/request-in-progress.service';
|
||||||
|
|
||||||
import { DomainService } from 'app/shared/services/domain/domain.service';
|
import { DomainService } from 'app/shared/services/domain/domain.service';
|
||||||
import { Pair } from 'app/shared/models/pair';
|
|
||||||
import { NgForm } from '@angular/forms';
|
import { NgForm } from '@angular/forms';
|
||||||
import { FormsValidatorService } from 'app/shared/services/forms-validator/forms-validator.service';
|
import { FormsValidatorService } from 'app/shared/services/forms-validator/forms-validator.service';
|
||||||
import { ImportExportService } from 'app/administration/services/import-export.service';
|
import { ImportExportService } from 'app/administration/services/import-export.service';
|
||||||
|
@ -30,6 +29,7 @@ import {
|
||||||
CopyClassification,
|
CopyClassification,
|
||||||
DeselectClassification
|
DeselectClassification
|
||||||
} from '../../../shared/store/classification-store/classification.actions';
|
} from '../../../shared/store/classification-store/classification.actions';
|
||||||
|
import { Pair } from '../../../shared/models/pair';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-classification-details',
|
selector: 'taskana-administration-classification-details',
|
||||||
|
@ -137,12 +137,12 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
|
||||||
this.store.dispatch(new DeselectClassification());
|
this.store.dispatch(new DeselectClassification());
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategoryIcon(category: string): Observable<Pair> {
|
getCategoryIcon(category: string): Observable<Pair<string, string>> {
|
||||||
return this.categoryIcons$.pipe(
|
return this.categoryIcons$.pipe(
|
||||||
map((iconMap) =>
|
map((iconMap) =>
|
||||||
iconMap[category]
|
iconMap[category]
|
||||||
? new Pair(iconMap[category], category)
|
? { left: iconMap[category], right: category }
|
||||||
: new Pair(iconMap.missing, 'Category does not match with the configuration')
|
: { left: iconMap.missing, right: 'Category does not match with the configuration' }
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,21 +26,21 @@
|
||||||
matTooltip="Filter Category">
|
matTooltip="Filter Category">
|
||||||
|
|
||||||
<mat-icon *ngIf="selectedCategory == ''">filter_list</mat-icon>
|
<mat-icon *ngIf="selectedCategory == ''">filter_list</mat-icon>
|
||||||
<svg-icon class="classification-list__icons" [src]="(getCategoryIcon(selectedCategory) | async)?.name"
|
<svg-icon class="classification-list__icons" [src]="(getCategoryIcon(selectedCategory) | async)?.left"
|
||||||
[title]="(getCategoryIcon(selectedCategory) | async)?.text"
|
[title]="(getCategoryIcon(selectedCategory) | async)?.right"
|
||||||
*ngIf="selectedCategory != ''">
|
*ngIf="selectedCategory != ''">
|
||||||
</svg-icon>
|
</svg-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<mat-menu #menu="matMenu">
|
<mat-menu #menu="matMenu">
|
||||||
<button class="classification-list__all-button" mat-menu-item (click)="selectCategory('')">
|
<button class="classification-list__all-button" mat-menu-item (click)="selectCategory('')">
|
||||||
<svg-icon class="classification-list__categories" src="./assets/icons/asterisk.svg"
|
<svg-icon class="classification-list__categories" [src]="(getCategoryIcon('all') | async)?.left"
|
||||||
[title]="(getCategoryIcon('all') | async)?.text"></svg-icon>
|
[title]="(getCategoryIcon('all') | async)?.right"></svg-icon>
|
||||||
<span>All</span>
|
<span>All</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item *ngFor="let category of categories$ | async" (click)="selectCategory(category)">
|
<button mat-menu-item *ngFor="let category of categories$ | async" (click)="selectCategory(category)">
|
||||||
<svg-icon class="classification-list__categories" [src]="(getCategoryIcon(category) | async)?.name"
|
<svg-icon class="classification-list__categories" [src]="(getCategoryIcon(category) | async)?.left"
|
||||||
[title]="(getCategoryIcon(category) | async)?.text"></svg-icon>
|
[title]="(getCategoryIcon(category) | async)?.right"></svg-icon>
|
||||||
<span> {{category}} </span>
|
<span> {{category}} </span>
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
|
@ -200,8 +200,8 @@ describe('ClassificationListComponent', () => {
|
||||||
it('should return icon for category when getCategoryIcon is called and category exists', (done) => {
|
it('should return icon for category when getCategoryIcon is called and category exists', (done) => {
|
||||||
const categoryIcon = component.getCategoryIcon('MANUAL');
|
const categoryIcon = component.getCategoryIcon('MANUAL');
|
||||||
categoryIcon.subscribe((iconPair) => {
|
categoryIcon.subscribe((iconPair) => {
|
||||||
expect(iconPair.name).toBe('assets/icons/categories/manual.svg');
|
expect(iconPair.left).toBe('assets/icons/categories/manual.svg');
|
||||||
expect(iconPair.text).toBe('MANUAL');
|
expect(iconPair.right).toBe('MANUAL');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -209,7 +209,7 @@ describe('ClassificationListComponent', () => {
|
||||||
it('should return a special icon when getCategoryIcon is called and category does not exist', (done) => {
|
it('should return a special icon when getCategoryIcon is called and category does not exist', (done) => {
|
||||||
const categoryIcon = component.getCategoryIcon('CLOUD');
|
const categoryIcon = component.getCategoryIcon('CLOUD');
|
||||||
categoryIcon.subscribe((iconPair) => {
|
categoryIcon.subscribe((iconPair) => {
|
||||||
expect(iconPair.name).toBe('assets/icons/categories/missing-icon.svg');
|
expect(iconPair.left).toBe('assets/icons/categories/missing-icon.svg');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { Actions, ofActionCompleted, ofActionDispatched, Select, Store } from '@
|
||||||
import { ImportExportService } from 'app/administration/services/import-export.service';
|
import { ImportExportService } from 'app/administration/services/import-export.service';
|
||||||
|
|
||||||
import { TaskanaType } from 'app/shared/models/taskana-type';
|
import { TaskanaType } from 'app/shared/models/taskana-type';
|
||||||
import { Pair } from 'app/shared/models/pair';
|
|
||||||
import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors';
|
import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors';
|
||||||
import { ClassificationSelectors } from 'app/shared/store/classification-store/classification.selectors';
|
import { ClassificationSelectors } from 'app/shared/store/classification-store/classification.selectors';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
|
@ -19,6 +18,7 @@ import {
|
||||||
import { DomainService } from '../../../shared/services/domain/domain.service';
|
import { DomainService } from '../../../shared/services/domain/domain.service';
|
||||||
import { ClassificationSummary } from '../../../shared/models/classification-summary';
|
import { ClassificationSummary } from '../../../shared/models/classification-summary';
|
||||||
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
||||||
|
import { Pair } from '../../../shared/models/pair';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-classification-list',
|
selector: 'taskana-administration-classification-list',
|
||||||
|
@ -94,15 +94,15 @@ export class ClassificationListComponent implements OnInit, OnDestroy {
|
||||||
this.location.go(this.location.path().replace(/(classifications).*/g, 'classifications/new-classification'));
|
this.location.go(this.location.path().replace(/(classifications).*/g, 'classifications/new-classification'));
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategoryIcon(category: string): Observable<Pair> {
|
getCategoryIcon(category: string): Observable<Pair<string, string>> {
|
||||||
return this.categoryIcons$.pipe(
|
return this.categoryIcons$.pipe(
|
||||||
map((iconMap) => {
|
map((iconMap) => {
|
||||||
if (category === '') {
|
if (category === '') {
|
||||||
return new Pair(iconMap['all'], 'All');
|
return { left: iconMap['all'], right: 'All' };
|
||||||
}
|
}
|
||||||
return iconMap[category]
|
return iconMap[category]
|
||||||
? new Pair(iconMap[category], category)
|
? { left: iconMap[category], right: category }
|
||||||
: new Pair(iconMap.missing, 'Category does not match with the configuration');
|
: { left: iconMap.missing, right: 'Category does not match with the configuration' };
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
(moveNode)="onMoveNode($event)" (treeDrop)="onDrop($event)">
|
(moveNode)="onMoveNode($event)" (treeDrop)="onDrop($event)">
|
||||||
<ng-template #treeNodeTemplate let-node let-index="index">
|
<ng-template #treeNodeTemplate let-node let-index="index">
|
||||||
<span class="text-top">
|
<span class="text-top">
|
||||||
<svg-icon *ngIf="node.data.category" class="fa-fw pr-1" [src]="(getCategoryIcon(node.data.category) | async)?.name" data-toggle="tooltip"
|
<svg-icon *ngIf="node.data.category" class="fa-fw pr-1" [src]="(getCategoryIcon(node.data.category) | async)?.left" data-toggle="tooltip"
|
||||||
[title]="(getCategoryIcon(node.data.category) | async)?.text"></svg-icon>
|
[title]="(getCategoryIcon(node.data.category) | async)?.right"></svg-icon>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<strong>{{ node.data.key }}</strong>
|
<strong>{{ node.data.key }}</strong>
|
||||||
|
|
|
@ -13,7 +13,6 @@ import {
|
||||||
import { TreeNodeModel } from 'app/administration/models/tree-node';
|
import { TreeNodeModel } from 'app/administration/models/tree-node';
|
||||||
|
|
||||||
import { ITreeOptions, KEYS, TREE_ACTIONS, TreeComponent } from 'angular-tree-component';
|
import { ITreeOptions, KEYS, TREE_ACTIONS, TreeComponent } from 'angular-tree-component';
|
||||||
import { Pair } from 'app/shared/models/pair';
|
|
||||||
import { combineLatest, Observable, Subject } from 'rxjs';
|
import { combineLatest, Observable, Subject } from 'rxjs';
|
||||||
import { filter, map, takeUntil } from 'rxjs/operators';
|
import { filter, map, takeUntil } from 'rxjs/operators';
|
||||||
import { Select, Store } from '@ngxs/store';
|
import { Select, Store } from '@ngxs/store';
|
||||||
|
@ -32,6 +31,7 @@ import {
|
||||||
UpdateClassification
|
UpdateClassification
|
||||||
} from '../../../shared/store/classification-store/classification.actions';
|
} from '../../../shared/store/classification-store/classification.actions';
|
||||||
import { ClassificationTreeService } from '../../services/classification-tree.service';
|
import { ClassificationTreeService } from '../../services/classification-tree.service';
|
||||||
|
import { Pair } from '../../../shared/models/pair';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-tree',
|
selector: 'taskana-administration-tree',
|
||||||
|
@ -168,12 +168,12 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategoryIcon(category: string): Observable<Pair> {
|
getCategoryIcon(category: string): Observable<Pair<string, string>> {
|
||||||
return this.categoryIcons$.pipe(
|
return this.categoryIcons$.pipe(
|
||||||
map((iconMap) =>
|
map((iconMap) =>
|
||||||
iconMap[category]
|
iconMap[category]
|
||||||
? new Pair(iconMap[category], category)
|
? { left: iconMap[category], right: category }
|
||||||
: new Pair(iconMap.missing, 'Category does not match with the configuration')
|
: { left: iconMap.missing, right: 'Category does not match with the configuration' }
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { Component, DebugElement, Input } from '@angular/core';
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { IconTypeComponent } from './icon-type.component';
|
import { IconTypeComponent } from './icon-type.component';
|
||||||
import { SvgIconComponent, SvgIconRegistryService } from 'angular-svg-icon';
|
import { SvgIconComponent, SvgIconRegistryService } from 'angular-svg-icon';
|
||||||
|
import { WorkbasketType } from '../../../shared/models/workbasket-type';
|
||||||
|
|
||||||
@Component({ selector: 'svg-icon', template: '' })
|
@Component({ selector: 'svg-icon', template: '' })
|
||||||
class SvgIconStub {
|
class SvgIconStub {
|
||||||
|
@ -31,11 +32,11 @@ describe('IconTypeComponent', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return icon path dependent on the type when calling getIconPath', () => {
|
it('should return icon path dependent on the type when calling getIconPath', () => {
|
||||||
expect(component.getIconPath('PERSONAL')).toBe('user.svg');
|
expect(component.getIconPath(WorkbasketType.PERSONAL)).toBe('user.svg');
|
||||||
expect(component.getIconPath('GROUP')).toBe('users.svg');
|
expect(component.getIconPath(WorkbasketType.GROUP)).toBe('users.svg');
|
||||||
expect(component.getIconPath('TOPIC')).toBe('topic.svg');
|
expect(component.getIconPath(WorkbasketType.TOPIC)).toBe('topic.svg');
|
||||||
expect(component.getIconPath('CLEARANCE')).toBe('clearance.svg');
|
expect(component.getIconPath(WorkbasketType.CLEARANCE)).toBe('clearance.svg');
|
||||||
expect(component.getIconPath('CLOUD')).toBe('asterisk.svg');
|
expect(component.getIconPath(undefined)).toBe('asterisk.svg');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display svg-icon', () => {
|
it('should display svg-icon', () => {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { ICONTYPES } from 'app/shared/models/icon-types';
|
import { WorkbasketType } from 'app/shared/models/workbasket-type';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-icon-type',
|
selector: 'taskana-administration-icon-type',
|
||||||
|
@ -8,7 +8,7 @@ import { ICONTYPES } from 'app/shared/models/icon-types';
|
||||||
})
|
})
|
||||||
export class IconTypeComponent {
|
export class IconTypeComponent {
|
||||||
@Input()
|
@Input()
|
||||||
type: ICONTYPES = ICONTYPES.ALL;
|
type: WorkbasketType;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
selected = false;
|
selected = false;
|
||||||
|
@ -22,24 +22,15 @@ export class IconTypeComponent {
|
||||||
@Input()
|
@Input()
|
||||||
size = 'small';
|
size = 'small';
|
||||||
|
|
||||||
public static get allTypes(): Map<string, string> {
|
getIconPath(type: WorkbasketType) {
|
||||||
return new Map([
|
|
||||||
['PERSONAL', 'Personal'],
|
|
||||||
['GROUP', 'Group'],
|
|
||||||
['CLEARANCE', 'Clearance'],
|
|
||||||
['TOPIC', 'Topic']
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
getIconPath(type: string) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'PERSONAL':
|
case WorkbasketType.PERSONAL:
|
||||||
return 'user.svg';
|
return 'user.svg';
|
||||||
case 'GROUP':
|
case WorkbasketType.GROUP:
|
||||||
return 'users.svg';
|
return 'users.svg';
|
||||||
case 'TOPIC':
|
case WorkbasketType.TOPIC:
|
||||||
return 'topic.svg';
|
return 'topic.svg';
|
||||||
case 'CLEARANCE':
|
case WorkbasketType.CLEARANCE:
|
||||||
return 'clearance.svg';
|
return 'clearance.svg';
|
||||||
default:
|
default:
|
||||||
return 'asterisk.svg';
|
return 'asterisk.svg';
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { takeUntil } from 'rxjs/operators';
|
||||||
import { WorkbasketAndAction, WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
import { WorkbasketAndAction, WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
||||||
import { TaskanaDate } from '../../../shared/util/taskana.date';
|
import { TaskanaDate } from '../../../shared/util/taskana.date';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
import { ICONTYPES } from '../../../shared/models/icon-types';
|
import { WorkbasketType } from '../../../shared/models/workbasket-type';
|
||||||
import {
|
import {
|
||||||
DeselectWorkbasket,
|
DeselectWorkbasket,
|
||||||
OnButtonPressed,
|
OnButtonPressed,
|
||||||
|
@ -94,7 +94,7 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy, OnChanges
|
||||||
initWorkbasket() {
|
initWorkbasket() {
|
||||||
const emptyWorkbasket: Workbasket = {};
|
const emptyWorkbasket: Workbasket = {};
|
||||||
emptyWorkbasket.domain = this.domainService.getSelectedDomainValue();
|
emptyWorkbasket.domain = this.domainService.getSelectedDomainValue();
|
||||||
emptyWorkbasket.type = ICONTYPES.PERSONAL;
|
emptyWorkbasket.type = WorkbasketType.PERSONAL;
|
||||||
this.addDateToWorkbasket(emptyWorkbasket);
|
this.addDateToWorkbasket(emptyWorkbasket);
|
||||||
this.workbasket = emptyWorkbasket;
|
this.workbasket = emptyWorkbasket;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
<mat-icon class="button-icon" *ngIf="allSelected" matTooltip="Select all items">check_box_outline_blank</mat-icon>
|
<mat-icon class="button-icon" *ngIf="allSelected" matTooltip="Select all items">check_box_outline_blank</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
<taskana-shared-filter *ngIf="toolbarState" (performFilter)="performAvailableFilter($event)"
|
<taskana-shared-workbasket-filter *ngIf="toolbarState" (performFilter)="performAvailableFilter($event)"
|
||||||
component="distribution-target" (inputComponent)="setComponent($event)"></taskana-shared-filter>
|
isExpanded="true" component="distribution-target"></taskana-shared-workbasket-filter>
|
||||||
|
|
||||||
<!-- WORKBASKET LIST -->
|
<!-- WORKBASKET LIST -->
|
||||||
<div class="distribution-targets-list__list" infiniteScroll [infiniteScrollDistance]="1" [infiniteScrollThrottle]="50" (scrolled)="onScroll()"
|
<div class="distribution-targets-list__list" infiniteScroll [infiniteScrollDistance]="1" [infiniteScrollThrottle]="50" (scrolled)="onScroll()"
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
<mat-selection-list #workbasket [multiple]="true">
|
<mat-selection-list #workbasket [multiple]="true">
|
||||||
<mat-list-option class="workbasket-distribution-targets__workbaskets-item"
|
<mat-list-option class="workbasket-distribution-targets__workbaskets-item"
|
||||||
*ngFor="let workbasket of distributionTargets | selectWorkbaskets: distributionTargetsSelected: side"
|
*ngFor="let workbasket of distributionTargets | selectWorkbaskets: distributionTargetsSelected: side"
|
||||||
[selected]="workbasket.selected" type="text"
|
[selected]="workbasket.selected"
|
||||||
(click)="workbasket.selected = !workbasket.selected"
|
(click)="workbasket.selected = !workbasket.selected"
|
||||||
[value]="workbasket.workbasketId">
|
[value]="workbasket.workbasketId">
|
||||||
<div class="distribution-targets-list__item-wrapper">
|
<div class="distribution-targets-list__item-wrapper">
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/core';
|
||||||
import { WorkbasketDistributionTargetsListComponent } from './workbasket-distribution-targets-list.component';
|
import { WorkbasketDistributionTargetsListComponent } from './workbasket-distribution-targets-list.component';
|
||||||
import { Filter } from '../../../shared/models/filter';
|
|
||||||
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
||||||
import { ICONTYPES } from '../../../shared/models/icon-types';
|
import { WorkbasketType } from '../../../shared/models/workbasket-type';
|
||||||
import { SelectWorkBasketPipe } from '../../../shared/pipes/select-workbaskets.pipe';
|
import { SelectWorkBasketPipe } from '../../../shared/pipes/select-workbaskets.pipe';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { workbasketReadStateMock } from '../../../shared/store/mock-data/mock-store';
|
import { workbasketReadStateMock } from '../../../shared/store/mock-data/mock-store';
|
||||||
|
@ -11,10 +10,11 @@ import { Side } from '../workbasket-distribution-targets/workbasket-distribution
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
import { MatListModule } from '@angular/material/list';
|
import { MatListModule } from '@angular/material/list';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-parameters';
|
||||||
|
|
||||||
@Component({ selector: 'taskana-shared-filter', template: '' })
|
@Component({ selector: 'taskana-shared-workbasket-filter', template: '' })
|
||||||
class FilterStub {
|
class FilterStub {
|
||||||
@Output() performFilter = new EventEmitter<Filter>();
|
@Output() performFilter = new EventEmitter<WorkbasketQueryFilterParameter>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({ selector: 'taskana-shared-spinner', template: '' })
|
@Component({ selector: 'taskana-shared-spinner', template: '' })
|
||||||
|
@ -24,7 +24,7 @@ class SpinnerStub {
|
||||||
|
|
||||||
@Component({ selector: 'taskana-administration-icon-type', template: '' })
|
@Component({ selector: 'taskana-administration-icon-type', template: '' })
|
||||||
class IconTypeStub {
|
class IconTypeStub {
|
||||||
@Input() type: ICONTYPES = ICONTYPES.ALL;
|
@Input() type: WorkbasketType;
|
||||||
@Input() text: string;
|
@Input() text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,11 @@ import {
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { WorkbasketSummary } from 'app/shared/models/workbasket-summary';
|
import { WorkbasketSummary } from 'app/shared/models/workbasket-summary';
|
||||||
import { Filter } from 'app/shared/models/filter';
|
|
||||||
import { expandDown } from 'app/shared/animations/expand.animation';
|
import { expandDown } from 'app/shared/animations/expand.animation';
|
||||||
import { Side } from '../workbasket-distribution-targets/workbasket-distribution-targets.component';
|
import { Side } from '../workbasket-distribution-targets/workbasket-distribution-targets.component';
|
||||||
import { MatSelectionList } from '@angular/material/list';
|
import { MatSelectionList } from '@angular/material/list';
|
||||||
|
import { Pair } from '../../../shared/models/pair';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-parameters';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-workbasket-distribution-targets-list',
|
selector: 'taskana-administration-workbasket-distribution-targets-list',
|
||||||
|
@ -23,7 +24,7 @@ import { MatSelectionList } from '@angular/material/list';
|
||||||
export class WorkbasketDistributionTargetsListComponent implements OnInit, AfterContentChecked {
|
export class WorkbasketDistributionTargetsListComponent implements OnInit, AfterContentChecked {
|
||||||
@Input() distributionTargets: WorkbasketSummary[];
|
@Input() distributionTargets: WorkbasketSummary[];
|
||||||
@Input() distributionTargetsSelected: WorkbasketSummary[];
|
@Input() distributionTargetsSelected: WorkbasketSummary[];
|
||||||
@Output() performDualListFilter = new EventEmitter<{ filterBy: Filter; side: Side }>();
|
@Output() performDualListFilter = new EventEmitter<Pair<Side, WorkbasketQueryFilterParameter>>();
|
||||||
@Input() requestInProgress = false;
|
@Input() requestInProgress = false;
|
||||||
@Input() loadingItems? = false;
|
@Input() loadingItems? = false;
|
||||||
@Input() side: Side;
|
@Input() side: Side;
|
||||||
|
@ -33,7 +34,6 @@ export class WorkbasketDistributionTargetsListComponent implements OnInit, After
|
||||||
@Output() allSelectedChange = new EventEmitter<boolean>();
|
@Output() allSelectedChange = new EventEmitter<boolean>();
|
||||||
|
|
||||||
toolbarState = false;
|
toolbarState = false;
|
||||||
component = '';
|
|
||||||
@ViewChild('workbasket') distributionTargetsList: MatSelectionList;
|
@ViewChild('workbasket') distributionTargetsList: MatSelectionList;
|
||||||
|
|
||||||
constructor(private changeDetector: ChangeDetectorRef) {}
|
constructor(private changeDetector: ChangeDetectorRef) {}
|
||||||
|
@ -55,17 +55,13 @@ export class WorkbasketDistributionTargetsListComponent implements OnInit, After
|
||||||
this.allSelectedChange.emit(this.allSelected);
|
this.allSelectedChange.emit(this.allSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
setComponent(component: string) {
|
|
||||||
this.component = component;
|
|
||||||
}
|
|
||||||
|
|
||||||
onScroll() {
|
onScroll() {
|
||||||
this.scrolling.emit(this.side);
|
this.scrolling.emit(this.side);
|
||||||
}
|
}
|
||||||
|
|
||||||
performAvailableFilter(filterModel: Filter) {
|
performAvailableFilter(pair: Pair<string, WorkbasketQueryFilterParameter>) {
|
||||||
if (this.component === 'distribution-target') {
|
if (pair.left === 'distribution-target') {
|
||||||
this.performDualListFilter.emit({ filterBy: filterModel, side: this.side });
|
this.performDualListFilter.emit({ left: this.side, right: pair.right });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/core';
|
||||||
import { Side, WorkbasketDistributionTargetsComponent } from './workbasket-distribution-targets.component';
|
import { Side, WorkbasketDistributionTargetsComponent } from './workbasket-distribution-targets.component';
|
||||||
import { WorkbasketSummary } from '../../../shared/models/workbasket-summary';
|
import { WorkbasketSummary } from '../../../shared/models/workbasket-summary';
|
||||||
import { Filter } from '../../../shared/models/filter';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
@ -20,6 +19,8 @@ import {
|
||||||
selectedWorkbasketMock,
|
selectedWorkbasketMock,
|
||||||
workbasketReadStateMock
|
workbasketReadStateMock
|
||||||
} from '../../../shared/store/mock-data/mock-store';
|
} from '../../../shared/store/mock-data/mock-store';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-parameters';
|
||||||
|
import { Pair } from '../../../shared/models/pair';
|
||||||
|
|
||||||
const routeParamsMock = { id: 'workbasket' };
|
const routeParamsMock = { id: 'workbasket' };
|
||||||
const activatedRouteMock = {
|
const activatedRouteMock = {
|
||||||
|
@ -31,7 +32,7 @@ const activatedRouteMock = {
|
||||||
class WorkbasketDistributionTargetsListStub {
|
class WorkbasketDistributionTargetsListStub {
|
||||||
@Input() distributionTargets: WorkbasketSummary[];
|
@Input() distributionTargets: WorkbasketSummary[];
|
||||||
@Input() distributionTargetsSelected: WorkbasketSummary[];
|
@Input() distributionTargetsSelected: WorkbasketSummary[];
|
||||||
@Output() performDualListFilter = new EventEmitter<{ filterBy: Filter; side: Side }>();
|
@Output() performDualListFilter = new EventEmitter<Pair<Side, WorkbasketQueryFilterParameter>>();
|
||||||
@Input() requestInProgress = false;
|
@Input() requestInProgress = false;
|
||||||
@Input() loadingItems? = false;
|
@Input() loadingItems? = false;
|
||||||
@Input() side: Side;
|
@Input() side: Side;
|
||||||
|
@ -128,11 +129,14 @@ describe('WorkbasketDistributionTargetsComponent', () => {
|
||||||
expect(component.distributionTargetsSelected).toHaveLength(3); //mock-data has 3 entries
|
expect(component.distributionTargetsSelected).toHaveLength(3); //mock-data has 3 entries
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: was ist das für ein test?
|
||||||
it('should emit filter model and side when performing filter', () => {
|
it('should emit filter model and side when performing filter', () => {
|
||||||
const performDualListFilterSpy = jest.spyOn(component, 'performFilter');
|
const performDualListFilterSpy = jest.spyOn(component, 'performFilter');
|
||||||
const filterModelMock: Filter = { filterParams: { name: '', description: '', owner: '', type: '', key: '' } };
|
const filterModelMock: WorkbasketQueryFilterParameter = { domain: ['DOMAIN_A'] };
|
||||||
component.performFilter({ filterBy: filterModelMock, side: component.side });
|
|
||||||
expect(performDualListFilterSpy).toHaveBeenCalledWith({ filterBy: filterModelMock, side: component.side });
|
component.performFilter({ left: Side.AVAILABLE, right: filterModelMock });
|
||||||
|
|
||||||
|
expect(performDualListFilterSpy).toHaveBeenCalledWith({ right: filterModelMock, left: Side.AVAILABLE });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should move distribution targets to selected list', () => {
|
it('should move distribution targets to selected list', () => {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { WorkbasketDistributionTargets } from 'app/shared/models/workbasket-dist
|
||||||
import { ACTION } from 'app/shared/models/action';
|
import { ACTION } from 'app/shared/models/action';
|
||||||
import { WorkbasketService } from 'app/shared/services/workbasket/workbasket.service';
|
import { WorkbasketService } from 'app/shared/services/workbasket/workbasket.service';
|
||||||
import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets.service';
|
import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets.service';
|
||||||
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
|
||||||
import { Page } from 'app/shared/models/page';
|
import { Page } from 'app/shared/models/page';
|
||||||
import { Select, Store } from '@ngxs/store';
|
import { Select, Store } from '@ngxs/store';
|
||||||
import { filter, takeUntil } from 'rxjs/operators';
|
import { filter, takeUntil } from 'rxjs/operators';
|
||||||
|
@ -20,8 +19,10 @@ import {
|
||||||
UpdateWorkbasketDistributionTargets
|
UpdateWorkbasketDistributionTargets
|
||||||
} from '../../../shared/store/workbasket-store/workbasket.actions';
|
} from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||||
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
|
||||||
import { ButtonAction } from '../../models/button-action';
|
import { ButtonAction } from '../../models/button-action';
|
||||||
|
import { Pair } from '../../../shared/models/pair';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-parameters';
|
||||||
|
import { QueryPagingParameter } from '../../../shared/models/query-paging-parameter';
|
||||||
|
|
||||||
export enum Side {
|
export enum Side {
|
||||||
AVAILABLE,
|
AVAILABLE,
|
||||||
|
@ -54,7 +55,11 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
|
||||||
loadingItems = false;
|
loadingItems = false;
|
||||||
side = Side;
|
side = Side;
|
||||||
private initialized = false;
|
private initialized = false;
|
||||||
page: Page;
|
currentPage: Page;
|
||||||
|
pageParameter: QueryPagingParameter = {
|
||||||
|
page: 1,
|
||||||
|
'page-size': 9
|
||||||
|
};
|
||||||
cards: number;
|
cards: number;
|
||||||
selectAllLeft = false;
|
selectAllLeft = false;
|
||||||
selectAllRight = false;
|
selectAllRight = false;
|
||||||
|
@ -77,8 +82,7 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
|
||||||
private workbasketService: WorkbasketService,
|
private workbasketService: WorkbasketService,
|
||||||
private savingWorkbaskets: SavingWorkbasketService,
|
private savingWorkbaskets: SavingWorkbasketService,
|
||||||
private notificationsService: NotificationService,
|
private notificationsService: NotificationService,
|
||||||
private store: Store,
|
private store: Store
|
||||||
public matDialog: MatDialog
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,7 +104,7 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.pipe(filter((availableDistributionTargets) => typeof availableDistributionTargets !== 'undefined'))
|
.pipe(filter((availableDistributionTargets) => typeof availableDistributionTargets !== 'undefined'))
|
||||||
.subscribe((availableDistributionTargets) => {
|
.subscribe((availableDistributionTargets) => {
|
||||||
this.availableDistributionTargets = [...availableDistributionTargets];
|
this.availableDistributionTargets = availableDistributionTargets.map((wb) => ({ ...wb }));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.savingWorkbaskets
|
this.savingWorkbaskets
|
||||||
|
@ -118,7 +122,7 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
|
||||||
this.distributionTargetsSelectedResource = { ...workbasketDistributionTargets };
|
this.distributionTargetsSelectedResource = { ...workbasketDistributionTargets };
|
||||||
this.distributionTargetsSelected = this.distributionTargetsSelectedResource.distributionTargets;
|
this.distributionTargetsSelected = this.distributionTargetsSelectedResource.distributionTargets;
|
||||||
this.distributionTargetsSelectedClone = { ...this.distributionTargetsSelected };
|
this.distributionTargetsSelectedClone = { ...this.distributionTargetsSelected };
|
||||||
TaskanaQueryParameters.page = 1;
|
this.pageParameter.page = 1;
|
||||||
this.getWorkbaskets();
|
this.getWorkbaskets();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -140,7 +144,7 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
onScroll() {
|
onScroll() {
|
||||||
if (this.page.totalPages > TaskanaQueryParameters.page) {
|
if (this.currentPage && this.currentPage.totalPages > this.pageParameter.page) {
|
||||||
this.loadingItems = true;
|
this.loadingItems = true;
|
||||||
this.getNextPage();
|
this.getNextPage();
|
||||||
}
|
}
|
||||||
|
@ -157,20 +161,20 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
|
||||||
getWorkbaskets(side?: Side) {
|
getWorkbaskets(side?: Side) {
|
||||||
if (this.distributionTargetsSelected && !this.initialized) {
|
if (this.distributionTargetsSelected && !this.initialized) {
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
TaskanaQueryParameters.pageSize = this.cards + this.distributionTargetsSelected.length;
|
this.pageParameter['page-size'] = this.cards + this.distributionTargetsSelected.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.workbasketService
|
this.workbasketService
|
||||||
.getWorkBasketsSummary(true)
|
.getWorkBasketsSummary(true, undefined, undefined, this.pageParameter)
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe((distributionTargetsAvailable: WorkbasketSummaryRepresentation) => {
|
.subscribe((distributionTargetsAvailable: WorkbasketSummaryRepresentation) => {
|
||||||
if (TaskanaQueryParameters.page === 1) {
|
if (this.pageParameter === 1) {
|
||||||
this.availableDistributionTargets = [];
|
this.availableDistributionTargets = [];
|
||||||
this.page = distributionTargetsAvailable.page;
|
this.currentPage = distributionTargetsAvailable.page;
|
||||||
}
|
}
|
||||||
if (side === this.side.AVAILABLE) {
|
if (side === Side.AVAILABLE) {
|
||||||
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
|
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
|
||||||
} else if (side === this.side.SELECTED) {
|
} else if (side === Side.SELECTED) {
|
||||||
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable.workbaskets);
|
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable.workbaskets);
|
||||||
} else {
|
} else {
|
||||||
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
|
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
|
||||||
|
@ -181,38 +185,24 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
getNextPage(side?: Side) {
|
getNextPage(side?: Side) {
|
||||||
TaskanaQueryParameters.page += 1;
|
this.pageParameter.page += 1;
|
||||||
this.getWorkbaskets(side);
|
this.getWorkbaskets(side);
|
||||||
}
|
}
|
||||||
|
|
||||||
performFilter(dualListFilter: any) {
|
performFilter({ left: side, right: filter }: Pair<Side, WorkbasketQueryFilterParameter>) {
|
||||||
this.workbasketService
|
this.workbasketService
|
||||||
.getWorkBasketsSummary(
|
.getWorkBasketsSummary(true, filter)
|
||||||
true,
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
dualListFilter.filterBy.filterParams.name,
|
|
||||||
dualListFilter.filterBy.filterParams.description,
|
|
||||||
'',
|
|
||||||
dualListFilter.filterBy.filterParams.owner,
|
|
||||||
dualListFilter.filterBy.filterParams.type,
|
|
||||||
'',
|
|
||||||
dualListFilter.filterBy.filterParams.key,
|
|
||||||
'',
|
|
||||||
true
|
|
||||||
)
|
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe((distributionTargetsAvailable: WorkbasketSummaryRepresentation) => {
|
.subscribe((distributionTargetsAvailable: WorkbasketSummaryRepresentation) => {
|
||||||
this.fillDistributionTargets(dualListFilter.side, []);
|
this.fillDistributionTargets(side, []);
|
||||||
|
|
||||||
if (TaskanaQueryParameters.page === 1) {
|
if (this.pageParameter === 1) {
|
||||||
this.availableDistributionTargets = [];
|
this.availableDistributionTargets = [];
|
||||||
this.page = distributionTargetsAvailable.page;
|
this.currentPage = distributionTargetsAvailable.page;
|
||||||
}
|
}
|
||||||
if (dualListFilter.side === this.side.AVAILABLE) {
|
if (side === Side.AVAILABLE) {
|
||||||
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
|
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
|
||||||
} else if (dualListFilter.side === this.side.SELECTED) {
|
} else if (side === Side.SELECTED) {
|
||||||
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable.workbaskets);
|
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable.workbaskets);
|
||||||
} else {
|
} else {
|
||||||
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
|
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
|
||||||
|
@ -240,8 +230,8 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
|
||||||
this.distributionTargetsSelected = [...this.distributionTargetsSelected, ...itemsSelected];
|
this.distributionTargetsSelected = [...this.distributionTargetsSelected, ...itemsSelected];
|
||||||
this.distributionTargetsLeft = this.distributionTargetsLeft.concat(itemsSelected);
|
this.distributionTargetsLeft = this.distributionTargetsLeft.concat(itemsSelected);
|
||||||
if (
|
if (
|
||||||
itemsLeft - itemsSelected.length <= TaskanaQueryParameters.pageSize &&
|
itemsLeft - itemsSelected.length <= this.pageParameter['page-size'] &&
|
||||||
itemsLeft + itemsRight < this.page.totalElements
|
itemsLeft + itemsRight < this.currentPage.totalElements
|
||||||
) {
|
) {
|
||||||
this.getNextPage(side);
|
this.getNextPage(side);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Component, DebugElement, Input } from '@angular/core';
|
||||||
import { Actions, NgxsModule, ofActionDispatched, Store } from '@ngxs/store';
|
import { Actions, NgxsModule, ofActionDispatched, Store } from '@ngxs/store';
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { ICONTYPES } from '../../../shared/models/icon-types';
|
import { WorkbasketType } from '../../../shared/models/workbasket-type';
|
||||||
import { MapValuesPipe } from '../../../shared/pipes/map-values.pipe';
|
import { MapValuesPipe } from '../../../shared/pipes/map-values.pipe';
|
||||||
import { RemoveNoneTypePipe } from '../../../shared/pipes/remove-empty-type.pipe';
|
import { RemoveNoneTypePipe } from '../../../shared/pipes/remove-empty-type.pipe';
|
||||||
import { WorkbasketService } from '../../../shared/services/workbasket/workbasket.service';
|
import { WorkbasketService } from '../../../shared/services/workbasket/workbasket.service';
|
||||||
|
@ -50,7 +50,7 @@ class FieldErrorDisplayStub {
|
||||||
|
|
||||||
@Component({ selector: 'taskana-administration-icon-type', template: '' })
|
@Component({ selector: 'taskana-administration-icon-type', template: '' })
|
||||||
class IconTypeStub {
|
class IconTypeStub {
|
||||||
@Input() type: ICONTYPES = ICONTYPES.ALL;
|
@Input() type: WorkbasketType;
|
||||||
@Input() text: string;
|
@Input() text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,9 @@
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="filter__filter-component-wrapper">
|
<div class="filter__filter-component-wrapper">
|
||||||
<taskana-shared-filter [isExpanded]="isExpanded"
|
<taskana-shared-workbasket-filter [isExpanded]="isExpanded"
|
||||||
(performFilter)="filtering($event)"
|
(performFilter)="filtering($event)"
|
||||||
component="workbasket-list"
|
component="workbasket-list"></taskana-shared-workbasket-filter>
|
||||||
(inputComponent)="setComponent($event)"></taskana-shared-filter>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,8 +9,7 @@ import { WorkbasketService } from '../../../shared/services/workbasket/workbaske
|
||||||
import { DomainService } from '../../../shared/services/domain/domain.service';
|
import { DomainService } from '../../../shared/services/domain/domain.service';
|
||||||
import { CreateWorkbasket } from '../../../shared/store/workbasket-store/workbasket.actions';
|
import { CreateWorkbasket } from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { Filter } from '../../../shared/models/filter';
|
import { Direction, Sorting, WorkbasketQuerySortParameter } from '../../../shared/models/sorting';
|
||||||
import { Sorting } from '../../../shared/models/sorting';
|
|
||||||
import { ACTION } from '../../../shared/models/action';
|
import { ACTION } from '../../../shared/models/action';
|
||||||
import { TaskanaType } from '../../../shared/models/taskana-type';
|
import { TaskanaType } from '../../../shared/models/taskana-type';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
@ -18,6 +17,8 @@ import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
||||||
|
import { Pair } from '../../../shared/models/pair';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-parameters';
|
||||||
|
|
||||||
const getDomainFn = jest.fn().mockReturnValue(true);
|
const getDomainFn = jest.fn().mockReturnValue(true);
|
||||||
const domainServiceMock = jest.fn().mockImplementation(
|
const domainServiceMock = jest.fn().mockImplementation(
|
||||||
|
@ -34,15 +35,15 @@ class ImportExportStub {
|
||||||
|
|
||||||
@Component({ selector: 'taskana-shared-sort', template: '' })
|
@Component({ selector: 'taskana-shared-sort', template: '' })
|
||||||
class SortStub {
|
class SortStub {
|
||||||
@Input() sortingFields: Map<string, string>;
|
@Input() sortingFields: Map<WorkbasketQuerySortParameter, string>;
|
||||||
@Input() defaultSortBy = 'key';
|
@Input() defaultSortBy: WorkbasketQuerySortParameter;
|
||||||
@Output() performSorting = new EventEmitter<Sorting>();
|
@Output() performSorting = new EventEmitter<Sorting<WorkbasketQuerySortParameter>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({ selector: 'taskana-shared-filter', template: '' })
|
@Component({ selector: 'taskana-shared-workbasket-filter', template: '' })
|
||||||
class FilterStub {
|
class FilterStub {
|
||||||
@Input() isExpanded = false;
|
@Input() isExpanded = false;
|
||||||
@Output() performFilter = new EventEmitter<Filter>();
|
@Output() performFilter = new EventEmitter<WorkbasketQueryFilterParameter>();
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestInProgressServiceSpy = jest.fn().mockImplementation(
|
const requestInProgressServiceSpy = jest.fn().mockImplementation(
|
||||||
|
@ -109,25 +110,35 @@ describe('WorkbasketListToolbarComponent', () => {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should emit value when sorting is called', (done) => {
|
it('should emit value when sorting is called', (done) => {
|
||||||
const mockSort: Sorting = { sortBy: '123', sortDirection: 'asc' };
|
const mockSort: Sorting<WorkbasketQuerySortParameter> = {
|
||||||
let sort: Sorting = { sortBy: '123', sortDirection: 'asc' };
|
'sort-by': WorkbasketQuerySortParameter.KEY,
|
||||||
component.performSorting.subscribe((sortBy: Sorting) => {
|
order: Direction.ASC
|
||||||
|
};
|
||||||
|
let sort: Sorting<WorkbasketQuerySortParameter> = undefined;
|
||||||
|
component.performSorting.subscribe((sortBy: Sorting<WorkbasketQuerySortParameter>) => {
|
||||||
sort = sortBy;
|
sort = sortBy;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
component.sorting(sort);
|
component.sorting(mockSort);
|
||||||
expect(sort).toMatchObject(mockSort);
|
expect(sort).toMatchObject(mockSort);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit value when filtering is called', async((done) => {
|
it('should NOT emit value when filtering is called with wrong component', async((done) => {
|
||||||
const mockFilter: Filter = { filterParams: 'abc' };
|
const mockFilter: Pair<string, WorkbasketQueryFilterParameter> = { left: 'foo', right: { domain: ['DOMAIN_A'] } };
|
||||||
let filterBy: Filter = { filterParams: 'abc' };
|
const performFilterSpy = jest.spyOn(component.performFilter, 'emit');
|
||||||
component.performFilter.subscribe((filter: Filter) => {
|
component.filtering(mockFilter);
|
||||||
filterBy = filter;
|
expect(performFilterSpy).toBeCalledTimes(0);
|
||||||
done();
|
}));
|
||||||
});
|
|
||||||
component.filtering(filterBy);
|
it('should emit value when filtering is called with correct component', async((done) => {
|
||||||
expect(filterBy).toMatchObject(mockFilter);
|
const mockFilter: Pair<string, WorkbasketQueryFilterParameter> = {
|
||||||
|
left: 'workbasket-list',
|
||||||
|
right: { domain: ['DOMAIN_A'] }
|
||||||
|
};
|
||||||
|
const performFilterSpy = jest.spyOn(component.performFilter, 'emit');
|
||||||
|
component.filtering(mockFilter);
|
||||||
|
expect(performFilterSpy).toBeCalledTimes(1);
|
||||||
|
expect(performFilterSpy).toBeCalledWith(mockFilter.right);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/* HTML */
|
/* HTML */
|
||||||
|
@ -151,7 +162,7 @@ describe('WorkbasketListToolbarComponent', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display filter component', () => {
|
it('should display filter component', () => {
|
||||||
expect(debugElement.nativeElement.querySelector('taskana-shared-filter')).toBeTruthy();
|
expect(debugElement.nativeElement.querySelector('taskana-shared-workbasket-filter')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show expanded filter component only when filter button is clicked', () => {
|
it('should show expanded filter component only when filter button is clicked', () => {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { Sorting } from 'app/shared/models/sorting';
|
import { Sorting, WORKBASKET_SORT_PARAMETER_NAMING, WorkbasketQuerySortParameter } from 'app/shared/models/sorting';
|
||||||
import { Filter } from 'app/shared/models/filter';
|
|
||||||
import { WorkbasketSummary } from 'app/shared/models/workbasket-summary';
|
import { WorkbasketSummary } from 'app/shared/models/workbasket-summary';
|
||||||
import { TaskanaType } from 'app/shared/models/taskana-type';
|
import { TaskanaType } from 'app/shared/models/taskana-type';
|
||||||
import { expandDown } from 'app/shared/animations/expand.animation';
|
import { expandDown } from 'app/shared/animations/expand.animation';
|
||||||
|
@ -11,6 +10,8 @@ import { ACTION } from '../../../shared/models/action';
|
||||||
import { CreateWorkbasket } from '../../../shared/store/workbasket-store/workbasket.actions';
|
import { CreateWorkbasket } from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||||
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
||||||
import { WorkbasketService } from '../../../shared/services/workbasket/workbasket.service';
|
import { WorkbasketService } from '../../../shared/services/workbasket/workbasket.service';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-parameters';
|
||||||
|
import { Pair } from '../../../shared/models/pair';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-workbasket-list-toolbar',
|
selector: 'taskana-administration-workbasket-list-toolbar',
|
||||||
|
@ -21,31 +22,15 @@ import { WorkbasketService } from '../../../shared/services/workbasket/workbaske
|
||||||
export class WorkbasketListToolbarComponent implements OnInit {
|
export class WorkbasketListToolbarComponent implements OnInit {
|
||||||
@Input() workbasketListExpanded: boolean = true;
|
@Input() workbasketListExpanded: boolean = true;
|
||||||
@Input() workbaskets: Array<WorkbasketSummary>;
|
@Input() workbaskets: Array<WorkbasketSummary>;
|
||||||
@Input() workbasketDefaultSortBy: string;
|
@Input() workbasketDefaultSortBy: WorkbasketQuerySortParameter;
|
||||||
@Output() performSorting = new EventEmitter<Sorting>();
|
@Output() performSorting = new EventEmitter<Sorting<WorkbasketQuerySortParameter>>();
|
||||||
@Output() performFilter = new EventEmitter<Filter>();
|
@Output() performFilter = new EventEmitter<WorkbasketQueryFilterParameter>();
|
||||||
|
|
||||||
selectionToImport = TaskanaType.WORKBASKETS;
|
selectionToImport = TaskanaType.WORKBASKETS;
|
||||||
sortingFields = new Map([
|
sortingFields: Map<WorkbasketQuerySortParameter, string> = WORKBASKET_SORT_PARAMETER_NAMING;
|
||||||
['name', 'Name'],
|
|
||||||
['key', 'Key'],
|
|
||||||
['description', 'Description'],
|
|
||||||
['owner', 'Owner'],
|
|
||||||
['type', 'Type']
|
|
||||||
]);
|
|
||||||
filteringTypes = new Map([
|
|
||||||
['ALL', 'All'],
|
|
||||||
['PERSONAL', 'Personal'],
|
|
||||||
['GROUP', 'Group'],
|
|
||||||
['CLEARANCE', 'Clearance'],
|
|
||||||
['TOPIC', 'Topic']
|
|
||||||
]);
|
|
||||||
|
|
||||||
filterParams = { name: '', key: '', type: '', description: '', owner: '' };
|
|
||||||
filterType = TaskanaType.WORKBASKETS;
|
|
||||||
isExpanded = false;
|
isExpanded = false;
|
||||||
showFilter = false;
|
showFilter = false;
|
||||||
component = '';
|
|
||||||
|
|
||||||
@Select(WorkbasketSelectors.workbasketActiveAction)
|
@Select(WorkbasketSelectors.workbasketActiveAction)
|
||||||
workbasketActiveAction$: Observable<ACTION>;
|
workbasketActiveAction$: Observable<ACTION>;
|
||||||
|
@ -61,20 +46,16 @@ export class WorkbasketListToolbarComponent implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sorting(sort: Sorting) {
|
sorting(sort: Sorting<WorkbasketQuerySortParameter>) {
|
||||||
this.performSorting.emit(sort);
|
this.performSorting.emit(sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
filtering(filterBy: Filter) {
|
filtering({ left: component, right: filter }: Pair<string, WorkbasketQueryFilterParameter>) {
|
||||||
if (this.component === 'workbasket-list') {
|
if (component === 'workbasket-list') {
|
||||||
this.performFilter.emit(filterBy);
|
this.performFilter.emit(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setComponent(component: string) {
|
|
||||||
this.component = component;
|
|
||||||
}
|
|
||||||
|
|
||||||
addWorkbasket() {
|
addWorkbasket() {
|
||||||
if (this.action !== ACTION.CREATE) {
|
if (this.action !== ACTION.CREATE) {
|
||||||
this.store.dispatch(new CreateWorkbasket());
|
this.store.dispatch(new CreateWorkbasket());
|
||||||
|
|
|
@ -10,11 +10,9 @@ import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { OrientationService } from '../../../shared/services/orientation/orientation.service';
|
import { OrientationService } from '../../../shared/services/orientation/orientation.service';
|
||||||
import { ImportExportService } from '../../services/import-export.service';
|
import { ImportExportService } from '../../services/import-export.service';
|
||||||
import { DeselectWorkbasket, SelectWorkbasket } from '../../../shared/store/workbasket-store/workbasket.actions';
|
import { DeselectWorkbasket, SelectWorkbasket } from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||||
import { TaskanaQueryParameters } from '../../../shared/util/query-parameters';
|
|
||||||
import { WorkbasketSummary } from '../../../shared/models/workbasket-summary';
|
import { WorkbasketSummary } from '../../../shared/models/workbasket-summary';
|
||||||
import { Sorting } from '../../../shared/models/sorting';
|
import { Direction, Sorting, WorkbasketQuerySortParameter } from '../../../shared/models/sorting';
|
||||||
import { Filter } from '../../../shared/models/filter';
|
import { WorkbasketType } from '../../../shared/models/workbasket-type';
|
||||||
import { ICONTYPES } from '../../../shared/models/icon-types';
|
|
||||||
import { Page } from '../../../shared/models/page';
|
import { Page } from '../../../shared/models/page';
|
||||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
|
@ -24,6 +22,7 @@ import { DomainService } from '../../../shared/services/domain/domain.service';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
||||||
import { selectedWorkbasketMock } from '../../../shared/store/mock-data/mock-store';
|
import { selectedWorkbasketMock } from '../../../shared/store/mock-data/mock-store';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-parameters';
|
||||||
|
|
||||||
const workbasketSavedTriggeredFn = jest.fn().mockReturnValue(of(1));
|
const workbasketSavedTriggeredFn = jest.fn().mockReturnValue(of(1));
|
||||||
const workbasketSummaryFn = jest.fn().mockReturnValue(of({}));
|
const workbasketSummaryFn = jest.fn().mockReturnValue(of({}));
|
||||||
|
@ -74,13 +73,13 @@ class WorkbasketListToolbarStub {
|
||||||
@Input() workbaskets: Array<WorkbasketSummary>;
|
@Input() workbaskets: Array<WorkbasketSummary>;
|
||||||
@Input() workbasketDefaultSortBy: string;
|
@Input() workbasketDefaultSortBy: string;
|
||||||
@Input() workbasketListExpanded: boolean;
|
@Input() workbasketListExpanded: boolean;
|
||||||
@Output() performSorting = new EventEmitter<Sorting>();
|
@Output() performSorting = new EventEmitter<Sorting<WorkbasketQuerySortParameter>>();
|
||||||
@Output() performFilter = new EventEmitter<Filter>();
|
@Output() performFilter = new EventEmitter<WorkbasketQueryFilterParameter>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({ selector: 'taskana-administration-icon-type', template: '' })
|
@Component({ selector: 'taskana-administration-icon-type', template: '' })
|
||||||
class IconTypeStub {
|
class IconTypeStub {
|
||||||
@Input() type: ICONTYPES = ICONTYPES.ALL;
|
@Input() type: WorkbasketType;
|
||||||
@Input() selected = false;
|
@Input() selected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,13 +157,16 @@ describe('WorkbasketListComponent', () => {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should set sort value when performSorting is called', () => {
|
it('should set sort value when performSorting is called', () => {
|
||||||
const sort = { sortBy: '1', sortDirection: 'asc' };
|
const sort: Sorting<WorkbasketQuerySortParameter> = {
|
||||||
|
'sort-by': WorkbasketQuerySortParameter.TYPE,
|
||||||
|
order: Direction.ASC
|
||||||
|
};
|
||||||
component.performSorting(sort);
|
component.performSorting(sort);
|
||||||
expect(component.sort).toMatchObject(sort);
|
expect(component.sort).toMatchObject(sort);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set filter value when performFilter is called', () => {
|
it('should set filter value when performFilter is called', () => {
|
||||||
const filter = { filterParams: '123' };
|
const filter: WorkbasketQueryFilterParameter = { domain: ['123'] };
|
||||||
component.performFilter(filter);
|
component.performFilter(filter);
|
||||||
expect(component.filterBy).toMatchObject(filter);
|
expect(component.filterBy).toMatchObject(filter);
|
||||||
});
|
});
|
||||||
|
@ -172,6 +174,6 @@ describe('WorkbasketListComponent', () => {
|
||||||
it('should change page value when change page function is called ', () => {
|
it('should change page value when change page function is called ', () => {
|
||||||
const page = 2;
|
const page = 2;
|
||||||
component.changePage(page);
|
component.changePage(page);
|
||||||
expect(TaskanaQueryParameters.page).toBe(page);
|
expect(component.pageParameter.page).toBe(page);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,13 +3,11 @@ import { Observable, Subject } from 'rxjs';
|
||||||
|
|
||||||
import { WorkbasketSummaryRepresentation } from 'app/shared/models/workbasket-summary-representation';
|
import { WorkbasketSummaryRepresentation } from 'app/shared/models/workbasket-summary-representation';
|
||||||
import { WorkbasketSummary } from 'app/shared/models/workbasket-summary';
|
import { WorkbasketSummary } from 'app/shared/models/workbasket-summary';
|
||||||
import { Filter } from 'app/shared/models/filter';
|
import { Direction, Sorting, WorkbasketQuerySortParameter } from 'app/shared/models/sorting';
|
||||||
import { Sorting } from 'app/shared/models/sorting';
|
|
||||||
import { Orientation } from 'app/shared/models/orientation';
|
import { Orientation } from 'app/shared/models/orientation';
|
||||||
|
|
||||||
import { WorkbasketService } from 'app/shared/services/workbasket/workbasket.service';
|
import { WorkbasketService } from 'app/shared/services/workbasket/workbasket.service';
|
||||||
import { OrientationService } from 'app/shared/services/orientation/orientation.service';
|
import { OrientationService } from 'app/shared/services/orientation/orientation.service';
|
||||||
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
|
||||||
import { ImportExportService } from 'app/administration/services/import-export.service';
|
import { ImportExportService } from 'app/administration/services/import-export.service';
|
||||||
import { Actions, ofActionCompleted, ofActionDispatched, Select, Store } from '@ngxs/store';
|
import { Actions, ofActionCompleted, ofActionDispatched, Select, Store } from '@ngxs/store';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
@ -23,6 +21,8 @@ import { Workbasket } from '../../../shared/models/workbasket';
|
||||||
import { MatSelectionList } from '@angular/material/list';
|
import { MatSelectionList } from '@angular/material/list';
|
||||||
import { DomainService } from '../../../shared/services/domain/domain.service';
|
import { DomainService } from '../../../shared/services/domain/domain.service';
|
||||||
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-parameters';
|
||||||
|
import { QueryPagingParameter } from '../../../shared/models/query-paging-parameter';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-administration-workbasket-list',
|
selector: 'taskana-administration-workbasket-list',
|
||||||
|
@ -31,13 +31,17 @@ import { RequestInProgressService } from '../../../shared/services/request-in-pr
|
||||||
})
|
})
|
||||||
export class WorkbasketListComponent implements OnInit, OnDestroy {
|
export class WorkbasketListComponent implements OnInit, OnDestroy {
|
||||||
selectedId = '';
|
selectedId = '';
|
||||||
pageSelected = 1;
|
|
||||||
pageSize = 9;
|
|
||||||
type = 'workbaskets';
|
type = 'workbaskets';
|
||||||
cards: number = this.pageSize;
|
workbasketDefaultSortBy: WorkbasketQuerySortParameter = WorkbasketQuerySortParameter.NAME;
|
||||||
workbasketDefaultSortBy: string = 'name';
|
sort: Sorting<WorkbasketQuerySortParameter> = {
|
||||||
sort: Sorting = new Sorting(this.workbasketDefaultSortBy);
|
'sort-by': this.workbasketDefaultSortBy,
|
||||||
filterBy: Filter = new Filter({ name: '', owner: '', type: '', description: '', key: '' });
|
order: Direction.ASC
|
||||||
|
};
|
||||||
|
filterBy: WorkbasketQueryFilterParameter = {};
|
||||||
|
pageParameter: QueryPagingParameter = {
|
||||||
|
page: 1,
|
||||||
|
'page-size': 9
|
||||||
|
};
|
||||||
requestInProgress: boolean;
|
requestInProgress: boolean;
|
||||||
requestInProgressLocal = false;
|
requestInProgressLocal = false;
|
||||||
@Input() expanded: boolean;
|
@Input() expanded: boolean;
|
||||||
|
@ -88,9 +92,6 @@ export class WorkbasketListComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
TaskanaQueryParameters.page = this.pageSelected;
|
|
||||||
TaskanaQueryParameters.pageSize = this.pageSize;
|
|
||||||
|
|
||||||
this.workbasketService
|
this.workbasketService
|
||||||
.workbasketSavedTriggered()
|
.workbasketSavedTriggered()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
|
@ -145,23 +146,23 @@ export class WorkbasketListComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
performSorting(sort: Sorting) {
|
performSorting(sort: Sorting<WorkbasketQuerySortParameter>) {
|
||||||
this.sort = sort;
|
this.sort = sort;
|
||||||
this.performRequest();
|
this.performRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
performFilter(filterBy: Filter) {
|
performFilter(filterBy: WorkbasketQueryFilterParameter) {
|
||||||
this.filterBy = filterBy;
|
this.filterBy = filterBy;
|
||||||
this.performRequest();
|
this.performRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
changePage(page) {
|
changePage(page) {
|
||||||
TaskanaQueryParameters.page = page;
|
this.pageParameter.page = page;
|
||||||
this.performRequest();
|
this.performRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshWorkbasketList() {
|
refreshWorkbasketList() {
|
||||||
this.cards = this.orientationService.calculateNumberItemsList(
|
this.pageParameter['page-size'] = this.orientationService.calculateNumberItemsList(
|
||||||
window.innerHeight,
|
window.innerHeight,
|
||||||
92,
|
92,
|
||||||
200 + this.toolbarElement.nativeElement.offsetHeight,
|
200 + this.toolbarElement.nativeElement.offsetHeight,
|
||||||
|
@ -171,27 +172,9 @@ export class WorkbasketListComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
performRequest() {
|
performRequest() {
|
||||||
TaskanaQueryParameters.pageSize = this.cards;
|
this.store.dispatch(new GetWorkbasketsSummary(true, this.filterBy, this.sort, this.pageParameter)).subscribe(() => {
|
||||||
this.store
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
.dispatch(
|
});
|
||||||
new GetWorkbasketsSummary(
|
|
||||||
true,
|
|
||||||
this.sort.sortBy,
|
|
||||||
this.sort.sortDirection,
|
|
||||||
'',
|
|
||||||
this.filterBy.filterParams.name,
|
|
||||||
this.filterBy.filterParams.description,
|
|
||||||
'',
|
|
||||||
this.filterBy.filterParams.owner,
|
|
||||||
this.filterBy.filterParams.type,
|
|
||||||
'',
|
|
||||||
this.filterBy.filterParams.key,
|
|
||||||
''
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.subscribe(() => {
|
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
import { Routes, RouterModule } from '@angular/router';
|
||||||
import { TaskQueryComponent } from './task-query/task-query.component';
|
import { TaskHistoryQueryComponent } from './task-history-query/task-history-query.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: TaskQueryComponent
|
component: TaskHistoryQueryComponent
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
|
|
|
@ -4,10 +4,10 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
import { SharedModule } from 'app/shared/shared.module';
|
import { SharedModule } from 'app/shared/shared.module';
|
||||||
import { HistoryRoutingModule } from './history-routing.module';
|
import { HistoryRoutingModule } from './history-routing.module';
|
||||||
import { TaskQueryComponent } from './task-query/task-query.component';
|
import { TaskHistoryQueryComponent } from './task-history-query/task-history-query.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [CommonModule, HistoryRoutingModule, SharedModule, FormsModule, ReactiveFormsModule],
|
imports: [CommonModule, HistoryRoutingModule, SharedModule, FormsModule, ReactiveFormsModule],
|
||||||
declarations: [TaskQueryComponent]
|
declarations: [TaskHistoryQueryComponent]
|
||||||
})
|
})
|
||||||
export class HistoryModule {}
|
export class HistoryModule {}
|
||||||
|
|
|
@ -1,56 +1,36 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { TaskHistoryEventData } from 'app/shared/models/task-history-event';
|
|
||||||
import { TaskHistoryEventResourceData } from 'app/shared/models/task-history-event-resource';
|
import { TaskHistoryEventResourceData } from 'app/shared/models/task-history-event-resource';
|
||||||
import { QueryParameters } from 'app/shared/models/query-parameters';
|
import { QueryParameters } from 'app/shared/models/query-parameters';
|
||||||
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
||||||
import { Direction } from 'app/shared/models/sorting';
|
import { Sorting, TaskHistoryQuerySortParameter } from 'app/shared/models/sorting';
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { environment } from 'environments/environment';
|
|
||||||
import { StartupService } from '../../../shared/services/startup/startup.service';
|
import { StartupService } from '../../../shared/services/startup/startup.service';
|
||||||
|
import { TaskHistoryQueryFilterParameter } from '../../../shared/models/task-history-query-filter-parameter';
|
||||||
|
import { QueryPagingParameter } from '../../../shared/models/query-paging-parameter';
|
||||||
|
import { asUrlQueryString } from '../../../shared/util/query-parameters-v2';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class TaskQueryService {
|
export class TaskHistoryQueryService {
|
||||||
constructor(private httpClient: HttpClient, private startupService: StartupService) {}
|
constructor(private httpClient: HttpClient, private startupService: StartupService) {}
|
||||||
|
|
||||||
get url(): string {
|
get url(): string {
|
||||||
return this.startupService.getTaskanaRestUrl();
|
return this.startupService.getTaskanaRestUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
queryTask(
|
getTaskHistoryEvents(
|
||||||
orderBy: string = 'created',
|
filterParameter?: TaskHistoryQueryFilterParameter,
|
||||||
sortDirection: string = Direction.ASC,
|
sortParameter?: Sorting<TaskHistoryQuerySortParameter>,
|
||||||
searchForValues: TaskHistoryEventData,
|
pagingParameter?: QueryPagingParameter
|
||||||
allPages: boolean = false
|
|
||||||
): Observable<TaskHistoryEventResourceData> {
|
): Observable<TaskHistoryEventResourceData> {
|
||||||
return this.httpClient.get<TaskHistoryEventResourceData>(
|
return this.httpClient.get<TaskHistoryEventResourceData>(
|
||||||
`${this.url}/v1/task-history-event${this.getQueryParameters(
|
`${this.url}/v1/task-history-event${asUrlQueryString({
|
||||||
orderBy,
|
...filterParameter,
|
||||||
sortDirection,
|
...sortParameter,
|
||||||
searchForValues.taskId,
|
...pagingParameter
|
||||||
searchForValues.parentBusinessProcessId,
|
})}`
|
||||||
searchForValues.businessProcessId,
|
|
||||||
searchForValues.eventType,
|
|
||||||
searchForValues.userId,
|
|
||||||
searchForValues.domain,
|
|
||||||
searchForValues.workbasketKey,
|
|
||||||
searchForValues.porCompany,
|
|
||||||
searchForValues.porSystem,
|
|
||||||
searchForValues.porInstance,
|
|
||||||
searchForValues.porType,
|
|
||||||
searchForValues.porValue,
|
|
||||||
searchForValues.taskClassificationKey,
|
|
||||||
searchForValues.taskClassificationCategory,
|
|
||||||
searchForValues.attachmentClassificationKey,
|
|
||||||
searchForValues.custom1,
|
|
||||||
searchForValues.custom2,
|
|
||||||
searchForValues.custom3,
|
|
||||||
searchForValues.custom4,
|
|
||||||
searchForValues.created,
|
|
||||||
allPages
|
|
||||||
)}`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +58,7 @@ export class TaskQueryService {
|
||||||
custom4: string,
|
custom4: string,
|
||||||
created: string,
|
created: string,
|
||||||
allPages: boolean = false
|
allPages: boolean = false
|
||||||
): string {
|
): void {
|
||||||
const parameters = new QueryParameters();
|
const parameters = new QueryParameters();
|
||||||
parameters.SORTBY = orderBy;
|
parameters.SORTBY = orderBy;
|
||||||
parameters.SORTDIRECTION = sortDirection;
|
parameters.SORTDIRECTION = sortDirection;
|
||||||
|
@ -107,7 +87,5 @@ export class TaskQueryService {
|
||||||
delete TaskanaQueryParameters.page;
|
delete TaskanaQueryParameters.page;
|
||||||
delete TaskanaQueryParameters.pageSize;
|
delete TaskanaQueryParameters.pageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TaskanaQueryParameters.getQueryParameters(parameters);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@
|
||||||
<span class="icon-space">
|
<span class="icon-space">
|
||||||
{{getHeaderFieldDescription(taskHeader.key)}}
|
{{getHeaderFieldDescription(taskHeader.key)}}
|
||||||
</span>
|
</span>
|
||||||
<span *ngIf="orderBy.sortBy === taskHeader.key"
|
<span *ngIf="orderBy['sort-by'] === taskHeader.key"
|
||||||
[ngClass]="{'flip': orderBy.sortDirection === 'desc'}"
|
[ngClass]="{'flip': orderBy.sortDirection === 'desc'}"
|
||||||
class="material-icons md-20 blue pull-right">sort</span>
|
class="material-icons md-20 blue pull-right">sort</span>
|
||||||
</div>
|
</div>
|
|
@ -1,5 +1,5 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Direction, Sorting } from 'app/shared/models/sorting';
|
import { Direction, Sorting, TaskHistoryQuerySortParameter } from 'app/shared/models/sorting';
|
||||||
import { OrientationService } from 'app/shared/services/orientation/orientation.service';
|
import { OrientationService } from 'app/shared/services/orientation/orientation.service';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { Orientation } from 'app/shared/models/orientation';
|
import { Orientation } from 'app/shared/models/orientation';
|
||||||
|
@ -8,29 +8,30 @@ import { FormControl, FormGroup } from '@angular/forms';
|
||||||
import { TaskHistoryEventResourceData } from 'app/shared/models/task-history-event-resource';
|
import { TaskHistoryEventResourceData } from 'app/shared/models/task-history-event-resource';
|
||||||
import { RequestInProgressService } from 'app/shared/services/request-in-progress/request-in-progress.service';
|
import { RequestInProgressService } from 'app/shared/services/request-in-progress/request-in-progress.service';
|
||||||
import { TaskHistoryEventData } from '../../shared/models/task-history-event';
|
import { TaskHistoryEventData } from '../../shared/models/task-history-event';
|
||||||
import { TaskQueryService } from '../services/task-query/task-query.service';
|
import { TaskHistoryQueryService } from '../services/task-history-query/task-history-query.service';
|
||||||
import { NotificationService } from '../../shared/services/notifications/notification.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-task-query',
|
selector: 'taskana-task-query',
|
||||||
templateUrl: './task-query.component.html',
|
templateUrl: './task-history-query.component.html',
|
||||||
styleUrls: ['./task-query.component.scss']
|
styleUrls: ['./task-history-query.component.scss']
|
||||||
})
|
})
|
||||||
export class TaskQueryComponent implements OnInit {
|
export class TaskHistoryQueryComponent implements OnInit {
|
||||||
taskQueryResource: TaskHistoryEventResourceData;
|
taskQueryResource: TaskHistoryEventResourceData;
|
||||||
taskQuery: Array<TaskHistoryEventData>;
|
taskQuery: Array<TaskHistoryEventData>;
|
||||||
taskQueryHeader = new TaskHistoryEventData();
|
taskQueryHeader = new TaskHistoryEventData();
|
||||||
orderBy = new Sorting(TaskanaQueryParameters.parameters.CREATED);
|
orderBy: Sorting<TaskHistoryQuerySortParameter> = {
|
||||||
|
'sort-by': TaskHistoryQuerySortParameter.CREATED,
|
||||||
|
order: Direction.ASC
|
||||||
|
};
|
||||||
orientationSubscription: Subscription;
|
orientationSubscription: Subscription;
|
||||||
taskQuerySubscription: Subscription;
|
taskQuerySubscription: Subscription;
|
||||||
|
|
||||||
taskQueryForm = new FormGroup({});
|
taskQueryForm = new FormGroup({});
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private taskQueryService: TaskQueryService,
|
private taskQueryService: TaskHistoryQueryService,
|
||||||
private orientationService: OrientationService,
|
private orientationService: OrientationService,
|
||||||
private requestInProgressService: RequestInProgressService,
|
private requestInProgressService: RequestInProgressService
|
||||||
private errorsService: NotificationService
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
@ -146,11 +147,12 @@ export class TaskQueryComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
changeOrderBy(key: string) {
|
changeOrderBy(key: string) {
|
||||||
|
console.log(key);
|
||||||
if (this.filterFieldsToAllowQuerying(key)) {
|
if (this.filterFieldsToAllowQuerying(key)) {
|
||||||
if (this.orderBy.sortBy === key) {
|
// if (this.orderBy.sortBy === key) {
|
||||||
this.orderBy.sortDirection = this.toggleSortDirection(this.orderBy.sortDirection);
|
// this.orderBy.sortDirection = this.toggleSortDirection(this.orderBy.sortDirection);
|
||||||
}
|
// }
|
||||||
this.orderBy.sortBy = key;
|
// this.orderBy.sortBy = key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,12 +195,12 @@ export class TaskQueryComponent implements OnInit {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
this.calculateQueryPages();
|
this.calculateQueryPages();
|
||||||
this.taskQuerySubscription = this.taskQueryService
|
this.taskQuerySubscription = this.taskQueryService
|
||||||
.queryTask(
|
.getTaskHistoryEvents
|
||||||
this.orderBy.sortBy.replace(/([A-Z])|([0-9])/g, (g) => `-${g[0].toLowerCase()}`),
|
// this.orderBy.sortBy.replace(/([A-Z])|([0-9])/g, (g) => `-${g[0].toLowerCase()}`),
|
||||||
this.orderBy.sortDirection,
|
// this.orderBy.sortDirection,
|
||||||
new TaskHistoryEventData(this.taskQueryForm.value),
|
// new TaskHistoryEventData(this.taskQueryForm.value),
|
||||||
false
|
// false
|
||||||
)
|
()
|
||||||
.subscribe((taskQueryResource) => {
|
.subscribe((taskQueryResource) => {
|
||||||
this.requestInProgressService.setRequestInProgress(false);
|
this.requestInProgressService.setRequestInProgress(false);
|
||||||
this.taskQueryResource = taskQueryResource.taskHistoryEvents ? taskQueryResource : null;
|
this.taskQueryResource = taskQueryResource.taskHistoryEvents ? taskQueryResource : null;
|
|
@ -1,5 +1,5 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { RestConnectorService } from 'app/monitor/services/rest-connector.service';
|
import { MonitorService } from 'app/monitor/services/monitor.service';
|
||||||
import { ChartData } from 'app/monitor/models/chart-data';
|
import { ChartData } from 'app/monitor/models/chart-data';
|
||||||
import { ReportData } from '../../models/report-data';
|
import { ReportData } from '../../models/report-data';
|
||||||
import { ChartColorsDefinition } from '../../models/chart-colors';
|
import { ChartColorsDefinition } from '../../models/chart-colors';
|
||||||
|
@ -22,7 +22,7 @@ export class ClassificationReportComponent implements OnInit {
|
||||||
|
|
||||||
lineChartColors = ChartColorsDefinition.getColors();
|
lineChartColors = ChartColorsDefinition.getColors();
|
||||||
|
|
||||||
constructor(private restConnectorService: RestConnectorService) {}
|
constructor(private restConnectorService: MonitorService) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.reportData = await this.restConnectorService.getClassificationTasksReport().toPromise();
|
this.reportData = await this.restConnectorService.getClassificationTasksReport().toPromise();
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<div *ngFor="let header of reportData.meta.header"
|
<div *ngFor="let header of reportData.meta.header"
|
||||||
class="table-cell table-cell--bold">{{header}}</div>
|
class="table-cell table-cell--bold">{{header}}</div>
|
||||||
<div class="table-cell table-cell--bold table-cell--border-left">{{reportData.meta.totalDesc}}</div>
|
<div class="table-cell table-cell--bold table-cell--border-left">{{reportData.meta.sumRowDesc}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="table-body">
|
<div class="table-body">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { ReportData } from 'app/monitor/models/report-data';
|
import { ReportData } from 'app/monitor/models/report-data';
|
||||||
import { RestConnectorService } from '../../services/rest-connector.service';
|
import { MonitorService } from '../../services/monitor.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-monitor-task-report',
|
selector: 'taskana-monitor-task-report',
|
||||||
|
@ -13,7 +13,7 @@ export class TaskReportComponent implements OnInit {
|
||||||
pieChartType = 'pie';
|
pieChartType = 'pie';
|
||||||
reportData: ReportData;
|
reportData: ReportData;
|
||||||
|
|
||||||
constructor(private restConnectorService: RestConnectorService) {}
|
constructor(private restConnectorService: MonitorService) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.reportData = await this.restConnectorService.getTaskStatusReport().toPromise();
|
this.reportData = await this.restConnectorService.getTaskStatusReport().toPromise();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { ReportData } from '../../models/report-data';
|
import { ReportData } from '../../models/report-data';
|
||||||
import { RestConnectorService } from '../../services/rest-connector.service';
|
import { MonitorService } from '../../services/monitor.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-monitor-timestamp-report',
|
selector: 'taskana-monitor-timestamp-report',
|
||||||
|
@ -10,7 +10,7 @@ import { RestConnectorService } from '../../services/rest-connector.service';
|
||||||
export class TimestampReportComponent implements OnInit {
|
export class TimestampReportComponent implements OnInit {
|
||||||
reportData: ReportData;
|
reportData: ReportData;
|
||||||
|
|
||||||
constructor(private restConnectorService: RestConnectorService) {}
|
constructor(private restConnectorService: MonitorService) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.restConnectorService.getDailyEntryExitReport().subscribe((data: ReportData) => {
|
this.restConnectorService.getDailyEntryExitReport().subscribe((data: ReportData) => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||||
import { ReportData } from '../../models/report-data';
|
import { ReportData } from '../../models/report-data';
|
||||||
import { ChartData } from '../../models/chart-data';
|
import { ChartData } from '../../models/chart-data';
|
||||||
import { ChartColorsDefinition } from '../../models/chart-colors';
|
import { ChartColorsDefinition } from '../../models/chart-colors';
|
||||||
import { RestConnectorService } from '../../services/rest-connector.service';
|
import { MonitorService } from '../../services/monitor.service';
|
||||||
import { MetaInfoData } from '../../models/meta-info-data';
|
import { MetaInfoData } from '../../models/meta-info-data';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -26,7 +26,7 @@ export class WorkbasketReportDueDateComponent implements OnInit {
|
||||||
|
|
||||||
lineChartColors = ChartColorsDefinition.getColors();
|
lineChartColors = ChartColorsDefinition.getColors();
|
||||||
|
|
||||||
constructor(private restConnectorService: RestConnectorService) {}
|
constructor(private restConnectorService: MonitorService) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.reportData = await this.restConnectorService.getWorkbasketStatisticsQueryingByDueDate().toPromise();
|
this.reportData = await this.restConnectorService.getWorkbasketStatisticsQueryingByDueDate().toPromise();
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||||
import { ReportData } from '../../models/report-data';
|
import { ReportData } from '../../models/report-data';
|
||||||
import { ChartData } from '../../models/chart-data';
|
import { ChartData } from '../../models/chart-data';
|
||||||
import { ChartColorsDefinition } from '../../models/chart-colors';
|
import { ChartColorsDefinition } from '../../models/chart-colors';
|
||||||
import { RestConnectorService } from '../../services/rest-connector.service';
|
import { MonitorService } from '../../services/monitor.service';
|
||||||
import { MetaInfoData } from '../../models/meta-info-data';
|
import { MetaInfoData } from '../../models/meta-info-data';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -27,7 +27,7 @@ export class WorkbasketReportPlannedDateComponent implements OnInit {
|
||||||
|
|
||||||
lineChartColors = ChartColorsDefinition.getColors();
|
lineChartColors = ChartColorsDefinition.getColors();
|
||||||
|
|
||||||
constructor(private restConnectorService: RestConnectorService) {}
|
constructor(private restConnectorService: MonitorService) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.reportData = await this.restConnectorService.getWorkbasketStatisticsQueryingByPlannedDate().toPromise();
|
this.reportData = await this.restConnectorService.getWorkbasketStatisticsQueryingByPlannedDate().toPromise();
|
||||||
|
|
|
@ -3,5 +3,5 @@ export class MetaInfoData {
|
||||||
date: string;
|
date: string;
|
||||||
header: Array<string>;
|
header: Array<string>;
|
||||||
rowDesc: Array<string>;
|
rowDesc: Array<string>;
|
||||||
totalDesc: string;
|
sumRowDesc: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { TaskReportComponent } from './components/task-report/task-report.compon
|
||||||
import { ClassificationReportComponent } from './components/classification-report/classification-report.component';
|
import { ClassificationReportComponent } from './components/classification-report/classification-report.component';
|
||||||
import { TimestampReportComponent } from './components/timestamp-report/timestamp-report.component';
|
import { TimestampReportComponent } from './components/timestamp-report/timestamp-report.component';
|
||||||
|
|
||||||
import { RestConnectorService } from './services/rest-connector.service';
|
import { MonitorService } from './services/monitor.service';
|
||||||
|
|
||||||
import { WorkbasketReportComponent } from './components/workbasket-report/workbasket-report.component';
|
import { WorkbasketReportComponent } from './components/workbasket-report/workbasket-report.component';
|
||||||
import { WorkbasketReportPlannedDateComponent } from './components/workbasket-report-planned-date/workbasket-report-planned-date.component';
|
import { WorkbasketReportPlannedDateComponent } from './components/workbasket-report-planned-date/workbasket-report-planned-date.component';
|
||||||
|
@ -51,6 +51,6 @@ const DECLARATIONS = [
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: DECLARATIONS,
|
declarations: DECLARATIONS,
|
||||||
imports: MODULES,
|
imports: MODULES,
|
||||||
providers: [RestConnectorService, MapToIterable]
|
providers: [MonitorService, MapToIterable]
|
||||||
})
|
})
|
||||||
export class MonitorModule {}
|
export class MonitorModule {}
|
||||||
|
|
|
@ -4,28 +4,40 @@ import { environment } from 'environments/environment';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { ChartData } from 'app/monitor/models/chart-data';
|
import { ChartData } from 'app/monitor/models/chart-data';
|
||||||
import { ReportData } from '../models/report-data';
|
import { ReportData } from '../models/report-data';
|
||||||
|
import { asUrlQueryString } from '../../shared/util/query-parameters-v2';
|
||||||
|
import { TaskState } from '../../shared/models/task-state';
|
||||||
|
|
||||||
const monitorUrl = '/v1/monitor/';
|
const monitorUrl = '/v1/monitor/';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RestConnectorService {
|
export class MonitorService {
|
||||||
constructor(private httpClient: HttpClient) {}
|
constructor(private httpClient: HttpClient) {}
|
||||||
|
|
||||||
getTaskStatusReport(): Observable<ReportData> {
|
getTaskStatusReport(): Observable<ReportData> {
|
||||||
|
const queryParams = {
|
||||||
|
states: [TaskState.READY, TaskState.CLAIMED, TaskState.COMPLETED]
|
||||||
|
};
|
||||||
return this.httpClient.get<ReportData>(
|
return this.httpClient.get<ReportData>(
|
||||||
`${environment.taskanaRestUrl + monitorUrl}tasks-status-report?states=READY,CLAIMED,COMPLETED`
|
`${environment.taskanaRestUrl + monitorUrl}tasks-status-report${asUrlQueryString(queryParams)}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getWorkbasketStatisticsQueryingByDueDate(): Observable<ReportData> {
|
getWorkbasketStatisticsQueryingByDueDate(): Observable<ReportData> {
|
||||||
|
const queryParams = {
|
||||||
|
states: [TaskState.READY, TaskState.CLAIMED, TaskState.COMPLETED]
|
||||||
|
};
|
||||||
return this.httpClient.get<ReportData>(
|
return this.httpClient.get<ReportData>(
|
||||||
`${environment.taskanaRestUrl + monitorUrl}tasks-workbasket-report?states=READY,CLAIMED,COMPLETED`
|
`${environment.taskanaRestUrl + monitorUrl}tasks-workbasket-report${asUrlQueryString(queryParams)}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getWorkbasketStatisticsQueryingByPlannedDate(): Observable<ReportData> {
|
getWorkbasketStatisticsQueryingByPlannedDate(): Observable<ReportData> {
|
||||||
|
const queryParams = {
|
||||||
|
daysInPast: 7,
|
||||||
|
states: [TaskState.READY, TaskState.CLAIMED, TaskState.COMPLETED]
|
||||||
|
};
|
||||||
return this.httpClient.get<ReportData>(
|
return this.httpClient.get<ReportData>(
|
||||||
`${environment.taskanaRestUrl}/v1/monitor/tasks-workbasket-planned-date-report?daysInPast=7&states=READY,CLAIMED,COMPLETED`
|
`${environment.taskanaRestUrl}/v1/monitor/tasks-workbasket-planned-date-report${asUrlQueryString(queryParams)}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,127 +0,0 @@
|
||||||
<!-- WORKBASKET FILTER -->
|
|
||||||
<div *ngIf="filterTypeIsWorkbasket(); else taskType">
|
|
||||||
|
|
||||||
<!-- COLLAPSED WORKBASKET FILTER -->
|
|
||||||
<div class="filter__collapsed-filter" *ngIf="!isExpanded">
|
|
||||||
<!-- TEXT INPUT -->
|
|
||||||
<mat-form-field appearance="legacy" floatLabel="auto" class="collapsed-filter_input-field">
|
|
||||||
<mat-label>Filter by name</mat-label>
|
|
||||||
<input matInput [(ngModel)]="filter.filterParams.name" matTooltip="Type to filter by name" (keyup.enter)="search()">
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<!-- CLEAR BUTTON -->
|
|
||||||
<button mat-stroked-button (click)="clear(); search()" matTooltip="Clear workbasket filter" class="filter__undo-button">
|
|
||||||
<mat-icon style="color: #555">undo</mat-icon>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- SEARCH BUTTON -->
|
|
||||||
<button mat-stroked-button (click)="search()" matTooltip="Search by given filter" class="filter__search-button">
|
|
||||||
<mat-icon>search</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- EXPANDED WORKBASKET FILTER -->
|
|
||||||
<div class="filter" *ngIf="isExpanded">
|
|
||||||
|
|
||||||
<!-- TEXT INPUT -->
|
|
||||||
<div class="filter__text-input">
|
|
||||||
<div class="filter__name-and-key-input">
|
|
||||||
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
|
||||||
<mat-label>Filter by name</mat-label>
|
|
||||||
<input matInput [(ngModel)]="filter.filterParams.name" matTooltip="Type to filter by name" (keyup.enter)="search()">
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
|
||||||
<mat-label>Filter by key</mat-label>
|
|
||||||
<input matInput [(ngModel)]="filter.filterParams.key" matTooltip="Type to filter by key" (keyup.enter)="search()">
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="filter__name-and-key-input">
|
|
||||||
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
|
||||||
<mat-label>Filter by description</mat-label>
|
|
||||||
<input matInput [(ngModel)]="filter.filterParams.description" matTooltip="Type to filter by description" (keyup.enter)="search()">
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
|
||||||
<mat-label>Filter by owner</mat-label>
|
|
||||||
<input matInput [(ngModel)]="filter.filterParams.owner" matTooltip="Type to filter by owner" (keyup.enter)="search()">
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- SEARCH AND CLEAR BUTTON -->
|
|
||||||
<div class="filter__action-buttons">
|
|
||||||
|
|
||||||
<!-- TYPE FILTER -->
|
|
||||||
<button mat-stroked-button [matMenuTriggerFor]="menu" matTooltip="Filter workbaskets by type">
|
|
||||||
Filter by type
|
|
||||||
<mat-icon *ngIf="filter.filterParams?.type == ''" style="color: #555">filter_list</mat-icon>
|
|
||||||
<taskana-administration-icon-type *ngIf="filter.filterParams?.type != ''" [type]="filter.filterParams?.type"> </taskana-administration-icon-type>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<mat-menu #menu="matMenu">
|
|
||||||
<button mat-menu-item *ngFor="let type of allTypes | mapValues" (click)="selectType(type.key); search()">
|
|
||||||
<taskana-administration-icon-type [type]='type.key' [text]="type.value"></taskana-administration-icon-type>
|
|
||||||
</button>
|
|
||||||
</mat-menu>
|
|
||||||
|
|
||||||
<!-- CLEAR BUTTON -->
|
|
||||||
<button mat-stroked-button (click)="clear(); search()" matTooltip="Clear workbasket filter">
|
|
||||||
Reset
|
|
||||||
<mat-icon style="color: #555">undo</mat-icon>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- SEARCH BUTTON -->
|
|
||||||
<button mat-stroked-button (click)="search()" matTooltip="Search by given filter" class="filter__search-button">
|
|
||||||
Apply
|
|
||||||
<mat-icon>search</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- TASK FILTER -->
|
|
||||||
<ng-template #taskType>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-2">
|
|
||||||
<taskana-shared-number-picker [(ngModel)]="filter.filterParams.priority" (keyup.enter)="search()" title="priority" id="display-priority-filter"></taskana-shared-number-picker>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-4">
|
|
||||||
<input type="text" [(ngModel)]="filter.filterParams.name" (keyup.enter)="search()" class="form-control" id="display-name-filter"
|
|
||||||
placeholder="Filter name">
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-4">
|
|
||||||
<input type="text" [(ngModel)]="filter.filterParams.owner" (keyup.enter)="search()" class="form-control" id="display-owner-filter"
|
|
||||||
placeholder="Filter owner">
|
|
||||||
</div>
|
|
||||||
<button (click)="clear(); search()" class="btn btn-default pull-right margin-right" type="button" data-toggle="tooltip"
|
|
||||||
title="Clear">
|
|
||||||
<span class="material-icons md-20 blue">clear</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="dropdown col-xs-2 col-xs-offset-2">
|
|
||||||
<button class="btn btn-default" data-toggle="dropdown" type="button" data-toggle="dropdown" aria-haspopup="true"
|
|
||||||
aria-expanded="true" title="State: {{filter.filterParams.state ? filter.filterParams?.state : 'All'}}">
|
|
||||||
<span>{{filter.filterParams.state ? filter.filterParams?.state : 'All'}}</span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu dropdown-menu-users" role="menu">
|
|
||||||
<li>
|
|
||||||
<a *ngFor="let state of allStates | mapValues" type="button" (click)="selectState(state.key); search()"
|
|
||||||
data-toggle="tooltip" [title]="state.value">
|
|
||||||
<label class="blue">{{state.value}}</label>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<button (click)="search()" type="button" class="btn btn-default pull-right margin-right" data-toggle="tooltip"
|
|
||||||
title="Search">
|
|
||||||
<span class="material-icons md-20 blue">search</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
||||||
import { ICONTYPES } from 'app/shared/models/icon-types';
|
|
||||||
import { Filter } from 'app/shared/models/filter';
|
|
||||||
import { TaskanaType } from 'app/shared/models/taskana-type';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'taskana-shared-filter',
|
|
||||||
templateUrl: './filter.component.html',
|
|
||||||
styleUrls: ['./filter.component.scss']
|
|
||||||
})
|
|
||||||
export class FilterComponent implements OnInit {
|
|
||||||
@Input() component: string;
|
|
||||||
@Input() allTypes: Map<ICONTYPES, string> = new Map([
|
|
||||||
[ICONTYPES.ALL, 'All'],
|
|
||||||
[ICONTYPES.PERSONAL, 'Personal'],
|
|
||||||
[ICONTYPES.GROUP, 'Group'],
|
|
||||||
[ICONTYPES.CLEARANCE, 'Clearance'],
|
|
||||||
[ICONTYPES.TOPIC, 'Topic']
|
|
||||||
]);
|
|
||||||
|
|
||||||
@Input() allStates: Map<string, string> = new Map([
|
|
||||||
['ALL', 'All'],
|
|
||||||
['READY', 'Ready'],
|
|
||||||
['CLAIMED', 'Claimed'],
|
|
||||||
['COMPLETED', 'Completed']
|
|
||||||
]);
|
|
||||||
|
|
||||||
@Input() filterParams = { name: '', key: '', type: '', description: '', owner: '' };
|
|
||||||
@Input() filterType = TaskanaType.WORKBASKETS;
|
|
||||||
@Input() isExpanded = true;
|
|
||||||
@Output() performFilter = new EventEmitter<Filter>();
|
|
||||||
@Output() inputComponent = new EventEmitter<string>();
|
|
||||||
|
|
||||||
filter: Filter;
|
|
||||||
filterParamKeys = [];
|
|
||||||
lastFilterKey: string;
|
|
||||||
toggleDropDown = false;
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.initializeFilterModel();
|
|
||||||
if (this.filterParams) {
|
|
||||||
this.filterParamKeys = Object.keys(this.filterParams);
|
|
||||||
this.lastFilterKey = this.filterParamKeys[this.filterParamKeys.length - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
selectType(type: ICONTYPES) {
|
|
||||||
this.filter.filterParams.type = type === ICONTYPES.ALL ? '' : type;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectState(state: ICONTYPES) {
|
|
||||||
this.filter.filterParams.state = state === 'ALL' ? '' : state;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
Object.keys(this.filterParams).forEach((key) => {
|
|
||||||
this.filterParams[key] = '';
|
|
||||||
});
|
|
||||||
this.initializeFilterModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
search() {
|
|
||||||
this.inputComponent.emit(this.component);
|
|
||||||
this.performFilter.emit(this.filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeFilterModel(): void {
|
|
||||||
this.filter = new Filter(this.filterParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkUppercaseFilterType(filterType: string) {
|
|
||||||
return filterType === 'type' || filterType === 'state';
|
|
||||||
}
|
|
||||||
|
|
||||||
filterTypeIsWorkbasket(): boolean {
|
|
||||||
return this.filterType === TaskanaType.WORKBASKETS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* keys that are hardcoded in the HTML need to be specified here
|
|
||||||
* @returns {string[]}
|
|
||||||
*/
|
|
||||||
getUnusedKeys(): string[] {
|
|
||||||
return Object.keys(this.filterParamKeys).filter((key) => ['name', 'key', 'type'].indexOf(key) < 0);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,9 +29,9 @@ export class DialogPopUpComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
initError() {
|
initError() {
|
||||||
this.title = notifications.get(this.data.key).name || '';
|
this.title = notifications.get(this.data.key).left || '';
|
||||||
this.message =
|
this.message =
|
||||||
notifications.get(this.data.key).text || (this.data && this.data.passedError && this.data.passedError.error)
|
notifications.get(this.data.key).right || (this.data && this.data.passedError && this.data.passedError.error)
|
||||||
? this.data.passedError.error.message
|
? this.data.passedError.error.message
|
||||||
: '';
|
: '';
|
||||||
if (this.data.additions) {
|
if (this.data.additions) {
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
<!-- SORT DIRECTION -->
|
<!-- SORT DIRECTION -->
|
||||||
<mat-menu #sortDirection="matMenu">
|
<mat-menu #sortDirection="matMenu">
|
||||||
<!-- ASCENDING ORDER BUTTON -->
|
<!-- ASCENDING ORDER BUTTON -->
|
||||||
<button mat-menu-item (click)="changeOrder('asc')">
|
<button mat-menu-item (click)="changeOrder(sortDirectionEnum.ASC)">
|
||||||
<span *ngIf="sort.sortDirection === 'asc'; else coloredAsc">
|
<span *ngIf="sort.order === 'asc'; else coloredAsc">
|
||||||
<mat-icon class="sort__selected-value"> arrow_upward </mat-icon>
|
<mat-icon class="sort__selected-value"> arrow_upward </mat-icon>
|
||||||
<span class="sort__selected-value"> Ascending </span>
|
<span class="sort__selected-value"> Ascending </span>
|
||||||
</span>
|
</span>
|
||||||
|
@ -22,8 +22,8 @@
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- DESCENDING ORDER BUTTON -->
|
<!-- DESCENDING ORDER BUTTON -->
|
||||||
<button mat-menu-item (click)="changeOrder('desc')">
|
<button mat-menu-item (click)="changeOrder(sortDirectionEnum.DESC)">
|
||||||
<span *ngIf="sort.sortDirection === 'desc'; else coloredDesc">
|
<span *ngIf="sort.order === 'desc'; else coloredDesc">
|
||||||
<mat-icon class="sort__selected-value"> arrow_downward </mat-icon>
|
<mat-icon class="sort__selected-value"> arrow_downward </mat-icon>
|
||||||
<span class="sort__selected-value"> Descending </span>
|
<span class="sort__selected-value"> Descending </span>
|
||||||
</span>
|
</span>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
<mat-menu #sortValue="matMenu">
|
<mat-menu #sortValue="matMenu">
|
||||||
<button mat-menu-item *ngFor="let sortingField of sortingFields | mapValues"
|
<button mat-menu-item *ngFor="let sortingField of sortingFields | mapValues"
|
||||||
(click)="changeSortBy(sortingField.key)">
|
(click)="changeSortBy(sortingField.key)">
|
||||||
<span class="{{sortingField.key === sort.sortBy ? 'sort__selected-value' : ''}}">
|
<span class="{{sortingField.key === sort['sort-by'] ? 'sort__selected-value' : ''}}">
|
||||||
{{sortingField.value}}
|
{{sortingField.value}}
|
||||||
</span>
|
</span>
|
||||||
<ng-template #coloredValue>
|
<ng-template #coloredValue>
|
||||||
|
|
|
@ -6,26 +6,32 @@ import { Direction, Sorting } from 'app/shared/models/sorting';
|
||||||
templateUrl: './sort.component.html',
|
templateUrl: './sort.component.html',
|
||||||
styleUrls: ['./sort.component.scss']
|
styleUrls: ['./sort.component.scss']
|
||||||
})
|
})
|
||||||
export class SortComponent implements OnInit {
|
export class SortComponent<T> implements OnInit {
|
||||||
@Input() sortingFields: Map<string, string>;
|
@Input() sortingFields: Map<T, string>;
|
||||||
@Input() menuPosition = 'right';
|
@Input() menuPosition = 'right';
|
||||||
@Input() defaultSortBy = 'key';
|
@Input() defaultSortBy: T;
|
||||||
|
|
||||||
@Output() performSorting = new EventEmitter<Sorting>();
|
@Output() performSorting = new EventEmitter<Sorting<T>>();
|
||||||
|
|
||||||
sort: Sorting = new Sorting();
|
sort: Sorting<T> = {
|
||||||
|
'sort-by': undefined,
|
||||||
|
order: Direction.ASC
|
||||||
|
};
|
||||||
|
|
||||||
|
// this allows the html template to use the Direction enum.
|
||||||
|
sortDirectionEnum = Direction;
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.sort.sortBy = this.defaultSortBy;
|
this.sort['sort-by'] = this.defaultSortBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
changeOrder(sortDirection: string) {
|
changeOrder(sortDirection: Direction) {
|
||||||
this.sort.sortDirection = sortDirection === Direction.ASC ? Direction.ASC : Direction.DESC;
|
this.sort.order = sortDirection;
|
||||||
this.search();
|
this.search();
|
||||||
}
|
}
|
||||||
|
|
||||||
changeSortBy(sortBy: string) {
|
changeSortBy(sortBy: T) {
|
||||||
this.sort.sortBy = sortBy;
|
this.sort['sort-by'] = sortBy;
|
||||||
this.search();
|
this.search();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-2">
|
||||||
|
<taskana-shared-number-picker [(ngModel)]="filter.priority[0]"
|
||||||
|
(keyup.enter)="search()" title="priority"
|
||||||
|
id="display-priority-filter"></taskana-shared-number-picker>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<input type="text" [(ngModel)]="filter['name-like'][0]" (keyup.enter)="search()"
|
||||||
|
class="form-control" id="display-name-filter"
|
||||||
|
placeholder="Filter name">
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<input type="text" [(ngModel)]="filter['owner-like'][0]" (keyup.enter)="search()"
|
||||||
|
class="form-control" id="display-owner-filter"
|
||||||
|
placeholder="Filter owner">
|
||||||
|
</div>
|
||||||
|
<button (click)="clear(); search()" class="btn btn-default pull-right margin-right" type="button"
|
||||||
|
data-toggle="tooltip"
|
||||||
|
title="Clear">
|
||||||
|
<span class="material-icons md-20 blue">clear</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="dropdown col-xs-2 col-xs-offset-2">
|
||||||
|
<button class="btn btn-default" type="button" data-toggle="dropdown"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-expanded="true"
|
||||||
|
title="State: {{filter.state && filter.state[0] ? filter.state[0] : 'All'}}">
|
||||||
|
<span>{{filter.state ? filter.state[0] : 'All'}}</span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-users" role="menu">
|
||||||
|
<li>
|
||||||
|
<a *ngFor="let state of allStates | mapValues" type="button"
|
||||||
|
(click)="selectState(state.key); search()"
|
||||||
|
data-toggle="tooltip" [title]="state.value">
|
||||||
|
<label class="blue">{{state.value}}</label>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<button (click)="search()" type="button" class="btn btn-default pull-right margin-right"
|
||||||
|
data-toggle="tooltip"
|
||||||
|
title="Search">
|
||||||
|
<span class="material-icons md-20 blue">search</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||||
|
import { ALL_STATES, TaskState } from '../../models/task-state';
|
||||||
|
import { TaskQueryFilterParameter } from '../../models/task-query-filter-parameter';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'taskana-shared-task-filter',
|
||||||
|
templateUrl: './task-filter.component.html',
|
||||||
|
styleUrls: ['./task-filter.component.scss']
|
||||||
|
})
|
||||||
|
export class TaskFilterComponent implements OnInit {
|
||||||
|
filter: TaskQueryFilterParameter;
|
||||||
|
|
||||||
|
@Output() performFilter = new EventEmitter<TaskQueryFilterParameter>();
|
||||||
|
|
||||||
|
allStates: Map<TaskState, string> = ALL_STATES;
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
selectState(state: TaskState) {
|
||||||
|
this.filter.state = state ? [state] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
search() {
|
||||||
|
this.performFilter.emit(this.filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.filter = {
|
||||||
|
priority: [],
|
||||||
|
'name-like': [],
|
||||||
|
'owner-like': []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ export class ToastComponent implements OnInit {
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (this.data) {
|
if (this.data) {
|
||||||
this.message = notifications.get(this.data.key).text;
|
this.message = notifications.get(this.data.key).right;
|
||||||
if (this.data.additions) {
|
if (this.data.additions) {
|
||||||
this.data.additions.forEach((value: string, replacementKey: string) => {
|
this.data.additions.forEach((value: string, replacementKey: string) => {
|
||||||
this.message = this.message.replace(`{${replacementKey}}`, value);
|
this.message = this.message.replace(`{${replacementKey}}`, value);
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
<div>
|
||||||
|
<!-- COLLAPSED WORKBASKET FILTER -->
|
||||||
|
<div class="filter__collapsed-filter" *ngIf="!isExpanded">
|
||||||
|
<!-- TEXT INPUT -->
|
||||||
|
<mat-form-field appearance="legacy" floatLabel="auto" class="collapsed-filter_input-field">
|
||||||
|
<mat-label>Filter by name</mat-label>
|
||||||
|
<input matInput [(ngModel)]="filter['name-like'][0]" matTooltip="Type to filter by name"
|
||||||
|
(keyup.enter)="search()">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<!-- CLEAR BUTTON -->
|
||||||
|
<button mat-stroked-button (click)="clear(); search()" matTooltip="Clear workbasket filter"
|
||||||
|
class="filter__undo-button">
|
||||||
|
<mat-icon style="color: #555">undo</mat-icon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- SEARCH BUTTON -->
|
||||||
|
<button mat-stroked-button (click)="search()" matTooltip="Search by given filter" class="filter__search-button">
|
||||||
|
<mat-icon>search</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- EXPANDED WORKBASKET FILTER -->
|
||||||
|
<div class="filter" *ngIf="isExpanded">
|
||||||
|
|
||||||
|
<!-- TEXT INPUT -->
|
||||||
|
<div class="filter__text-input">
|
||||||
|
<div class="filter__name-and-key-input">
|
||||||
|
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
||||||
|
<mat-label>Filter by name</mat-label>
|
||||||
|
<input matInput [(ngModel)]="filter['name-like'][0]" matTooltip="Type to filter by name"
|
||||||
|
(keyup.enter)="search()">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
||||||
|
<mat-label>Filter by key</mat-label>
|
||||||
|
<input matInput [(ngModel)]="filter['key-like'][0]" matTooltip="Type to filter by key"
|
||||||
|
(keyup.enter)="search()">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="filter__name-and-key-input">
|
||||||
|
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
||||||
|
<mat-label>Filter by description</mat-label>
|
||||||
|
<input matInput [(ngModel)]="filter['description-like']" matTooltip="Type to filter by description"
|
||||||
|
(keyup.enter)="search()">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="legacy" floatLabel="auto" class="filter__input-field">
|
||||||
|
<mat-label>Filter by owner</mat-label>
|
||||||
|
<input matInput [(ngModel)]="filter['owner-like'][0]" matTooltip="Type to filter by owner"
|
||||||
|
(keyup.enter)="search()">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- SEARCH AND CLEAR BUTTON -->
|
||||||
|
<div class="filter__action-buttons">
|
||||||
|
|
||||||
|
<!-- TYPE FILTER -->
|
||||||
|
<button mat-stroked-button [matMenuTriggerFor]="menu" matTooltip="Filter workbaskets by type">
|
||||||
|
Filter by type
|
||||||
|
<mat-icon *ngIf="filter.type" style="color: #555">filter_list</mat-icon>
|
||||||
|
<taskana-administration-icon-type *ngIf="filter.type[0]"
|
||||||
|
[type]="filter.type[0]"></taskana-administration-icon-type>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<mat-menu #menu="matMenu">
|
||||||
|
<button mat-menu-item *ngFor="let type of allTypes | mapValues" (click)="selectType(type.key); search()">
|
||||||
|
<taskana-administration-icon-type [type]='type.key' [text]="type.value"></taskana-administration-icon-type>
|
||||||
|
</button>
|
||||||
|
</mat-menu>
|
||||||
|
|
||||||
|
<!-- CLEAR BUTTON -->
|
||||||
|
<button mat-stroked-button (click)="clear(); search()" matTooltip="Clear workbasket filter">
|
||||||
|
Reset
|
||||||
|
<mat-icon style="color: #555">undo</mat-icon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- SEARCH BUTTON -->
|
||||||
|
<button mat-stroked-button (click)="search()" matTooltip="Search by given filter" class="filter__search-button">
|
||||||
|
Apply
|
||||||
|
<mat-icon>search</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -18,15 +18,10 @@
|
||||||
margin: 0 8px 0 8px;
|
margin: 0 8px 0 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter__action-buttons {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.filter__undo-buttons {
|
.filter__undo-buttons {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter__search-button {
|
.filter__search-button {
|
||||||
background: $aquamarine;
|
background: $aquamarine;
|
||||||
color: white;
|
color: white;
|
||||||
|
@ -38,37 +33,15 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu-users {
|
.filter__action-buttons {
|
||||||
& > li {
|
width: 100%;
|
||||||
margin-bottom: 5px;
|
padding: 10px 0;
|
||||||
}
|
display: flex;
|
||||||
margin-left: 15px;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-group-search {
|
.filter__search-button {
|
||||||
padding: 0 15px;
|
background: $aquamarine;
|
||||||
border-top: 1px solid #ddd;
|
color: white;
|
||||||
}
|
margin-left: 4px;
|
||||||
.list-group-search {
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
row.padding {
|
|
||||||
padding: 1px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-list {
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-list > li {
|
|
||||||
padding-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blue {
|
|
||||||
color: #2e9eca;
|
|
||||||
}
|
|
||||||
|
|
||||||
button.btn.btn-default.pull-right.margin-right {
|
|
||||||
margin-top: 1px;
|
|
||||||
}
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
import { ALL_TYPES, WorkbasketType } from '../../models/workbasket-type';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../models/workbasket-query-parameters';
|
||||||
|
import { Pair } from '../../models/pair';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'taskana-shared-workbasket-filter',
|
||||||
|
templateUrl: './workbasket-filter.component.html',
|
||||||
|
styleUrls: ['./workbasket-filter.component.scss']
|
||||||
|
})
|
||||||
|
export class WorkbasketFilterComponent implements OnInit {
|
||||||
|
allTypes: Map<WorkbasketType, string> = ALL_TYPES;
|
||||||
|
|
||||||
|
@Input() component: string;
|
||||||
|
@Input() isExpanded: boolean;
|
||||||
|
|
||||||
|
@Output() performFilter = new EventEmitter<Pair<string, WorkbasketQueryFilterParameter>>();
|
||||||
|
|
||||||
|
filter: WorkbasketQueryFilterParameter;
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.filter = {
|
||||||
|
'name-like': [],
|
||||||
|
'key-like': [],
|
||||||
|
'description-like': [],
|
||||||
|
'owner-like': [],
|
||||||
|
type: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
selectType(type: WorkbasketType) {
|
||||||
|
this.filter.type = type ? [type] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
search() {
|
||||||
|
this.performFilter.emit({ left: this.component, right: this.filter });
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
export interface ClassificationQueryFilterParameters {
|
||||||
|
name?: string[];
|
||||||
|
'name-like'?: string[];
|
||||||
|
key?: string[];
|
||||||
|
category?: string[];
|
||||||
|
domain?: string[];
|
||||||
|
type?: string[];
|
||||||
|
'custom-1-like'?: string[];
|
||||||
|
'custom-2-like'?: string[];
|
||||||
|
'custom-3-like'?: string[];
|
||||||
|
'custom-4-like'?: string[];
|
||||||
|
'custom-5-like'?: string[];
|
||||||
|
'custom-6-like'?: string[];
|
||||||
|
'custom-7-like'?: string[];
|
||||||
|
'custom-8-like'?: string[];
|
||||||
|
}
|
|
@ -7,8 +7,8 @@ export class ErrorModel {
|
||||||
public readonly message: string;
|
public readonly message: string;
|
||||||
|
|
||||||
constructor(key: NOTIFICATION_TYPES, passedError?: HttpErrorResponse, addition?: Map<String, String>) {
|
constructor(key: NOTIFICATION_TYPES, passedError?: HttpErrorResponse, addition?: Map<String, String>) {
|
||||||
this.title = notifications.get(key).name;
|
this.title = notifications.get(key).left;
|
||||||
let messageTemp = notifications.get(key).text;
|
let messageTemp = notifications.get(key).right;
|
||||||
this.errObj = passedError;
|
this.errObj = passedError;
|
||||||
if (addition) {
|
if (addition) {
|
||||||
addition.forEach((value: string, replacementKey: string) => {
|
addition.forEach((value: string, replacementKey: string) => {
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
export class Filter {
|
|
||||||
filterParams: any;
|
|
||||||
|
|
||||||
constructor(filterParams?: any) {
|
|
||||||
this.filterParams = filterParams;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
export enum ICONTYPES {
|
|
||||||
ALL = 'ALL',
|
|
||||||
PERSONAL = 'PERSONAL',
|
|
||||||
GROUP = 'GROUP',
|
|
||||||
CLEARANCE = 'CLEARANCE',
|
|
||||||
TOPIC = 'TOPIC'
|
|
||||||
}
|
|
|
@ -59,163 +59,194 @@ export enum NOTIFICATION_TYPES {
|
||||||
WARNING_CANT_COPY
|
WARNING_CANT_COPY
|
||||||
}
|
}
|
||||||
|
|
||||||
export const notifications = new Map<NOTIFICATION_TYPES, Pair>([
|
export const notifications = new Map<NOTIFICATION_TYPES, Pair<string, string>>([
|
||||||
// access-items-management.component.ts
|
// access-items-management.component.ts
|
||||||
[NOTIFICATION_TYPES.FETCH_ERR, new Pair('There was an error while retrieving your access ids with groups.', '')],
|
[
|
||||||
|
NOTIFICATION_TYPES.FETCH_ERR,
|
||||||
|
{ left: 'There was an error while retrieving your access ids with groups.', right: '' }
|
||||||
|
],
|
||||||
// access-items-management.component.ts
|
// access-items-management.component.ts
|
||||||
[NOTIFICATION_TYPES.FETCH_ERR_2, new Pair('There was an error while retrieving your access items ', '')],
|
[NOTIFICATION_TYPES.FETCH_ERR_2, { left: 'There was an error while retrieving your access items ', right: '' }],
|
||||||
// access-items-management.component.ts
|
// access-items-management.component.ts
|
||||||
[NOTIFICATION_TYPES.DELETE_ERR, new Pair("You can't delete a group", '')],
|
[NOTIFICATION_TYPES.DELETE_ERR, { left: "You can't delete a group", right: '' }],
|
||||||
// classification-details.component
|
// classification-details.component
|
||||||
[NOTIFICATION_TYPES.CREATE_ERR, new Pair('There was an error while creating this classification', '')],
|
[NOTIFICATION_TYPES.CREATE_ERR, { left: 'There was an error while creating this classification', right: '' }],
|
||||||
// classification-details.component
|
// classification-details.component
|
||||||
[NOTIFICATION_TYPES.REMOVE_ERR, new Pair('There was an error while removing your classification', '')],
|
[NOTIFICATION_TYPES.REMOVE_ERR, { left: 'There was an error while removing your classification', right: '' }],
|
||||||
// classification-details.component
|
// classification-details.component
|
||||||
[NOTIFICATION_TYPES.SAVE_ERR, new Pair('There was an error while saving your classification', '')],
|
[NOTIFICATION_TYPES.SAVE_ERR, { left: 'There was an error while saving your classification', right: '' }],
|
||||||
// classification-details.component
|
// classification-details.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.SELECT_ERR,
|
NOTIFICATION_TYPES.SELECT_ERR,
|
||||||
new Pair('There is no classification selected', 'Please check if you are creating a classification')
|
{ left: 'There is no classification selected', right: 'Please check if you are creating a classification' }
|
||||||
],
|
],
|
||||||
// import-export.component
|
// import-export.component
|
||||||
[NOTIFICATION_TYPES.FILE_ERR, new Pair('Wrong format', 'This file format is not allowed! Please use a .json file.')],
|
[
|
||||||
|
NOTIFICATION_TYPES.FILE_ERR,
|
||||||
|
{ left: 'Wrong format', right: 'This file format is not allowed! Please use a .json file.' }
|
||||||
|
],
|
||||||
// import-export.component
|
// import-export.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.IMPORT_ERR_1,
|
NOTIFICATION_TYPES.IMPORT_ERR_1,
|
||||||
new Pair('Import was not successful', 'Import was not successful, you have no access to apply this operation.')
|
{
|
||||||
|
left: 'Import was not successful',
|
||||||
|
right: 'Import was not successful, you have no access to apply this operation.'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
// import-export.component
|
// import-export.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.IMPORT_ERR_2,
|
NOTIFICATION_TYPES.IMPORT_ERR_2,
|
||||||
new Pair('Import was not successful', 'Import was not successful, operation was not found.')
|
{ left: 'Import was not successful', right: 'Import was not successful, operation was not found.' }
|
||||||
],
|
],
|
||||||
// import-export.component
|
// import-export.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.IMPORT_ERR_3,
|
NOTIFICATION_TYPES.IMPORT_ERR_3,
|
||||||
new Pair('Import was not successful', 'Import was not successful, operation has some conflicts.')
|
{ left: 'Import was not successful', right: 'Import was not successful, operation has some conflicts.' }
|
||||||
],
|
],
|
||||||
// import-export.component
|
// import-export.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.IMPORT_ERR_4,
|
NOTIFICATION_TYPES.IMPORT_ERR_4,
|
||||||
new Pair('Import was not successful', 'Import was not successful, maximum file size exceeded.')
|
{ left: 'Import was not successful', right: 'Import was not successful, maximum file size exceeded.' }
|
||||||
],
|
],
|
||||||
// import-export.component
|
// import-export.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.UPLOAD_ERR,
|
NOTIFICATION_TYPES.UPLOAD_ERR,
|
||||||
new Pair(
|
{
|
||||||
'Upload failed',
|
left: 'Upload failed',
|
||||||
`The upload didn't proceed sucessfully.
|
right: `The upload didn't proceed sucessfully.
|
||||||
\n The uploaded file probably exceeded the maximum file size of 10 MB.`
|
\n The uploaded file probably exceeded the maximum file size of 10 MB.`
|
||||||
)
|
}
|
||||||
],
|
],
|
||||||
// taskdetails.component
|
// taskdetails.component
|
||||||
[NOTIFICATION_TYPES.FETCH_ERR_3, new Pair('', 'An error occurred while fetching the task')],
|
[NOTIFICATION_TYPES.FETCH_ERR_3, { left: '', right: 'An error occurred while fetching the task' }],
|
||||||
// workbasket-details.component
|
// workbasket-details.component
|
||||||
[NOTIFICATION_TYPES.FETCH_ERR_4, new Pair('', 'An error occurred while fetching the workbasket')],
|
[NOTIFICATION_TYPES.FETCH_ERR_4, { left: '', right: 'An error occurred while fetching the workbasket' }],
|
||||||
// access-items.component
|
// access-items.component
|
||||||
[NOTIFICATION_TYPES.SAVE_ERR_2, new Pair("There was an error while saving your workbasket's access items", '')],
|
[
|
||||||
|
NOTIFICATION_TYPES.SAVE_ERR_2,
|
||||||
|
{ left: "There was an error while saving your workbasket's access items", right: '' }
|
||||||
|
],
|
||||||
// workbaskets-distribution-targets.component
|
// workbaskets-distribution-targets.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.SAVE_ERR_3,
|
NOTIFICATION_TYPES.SAVE_ERR_3,
|
||||||
new Pair("There was an error while saving your workbasket's distribution targets", '')
|
{ left: "There was an error while saving your workbasket's distribution targets", right: '' }
|
||||||
],
|
],
|
||||||
// workbasket-information.component
|
// workbasket-information.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.REMOVE_ERR_2,
|
NOTIFICATION_TYPES.REMOVE_ERR_2,
|
||||||
new Pair('There was an error removing distribution target for {workbasketId}.', '')
|
{ left: 'There was an error removing distribution target for {workbasketId}.', right: '' }
|
||||||
],
|
],
|
||||||
// workbasket-information.component
|
// workbasket-information.component
|
||||||
[NOTIFICATION_TYPES.SAVE_ERR_4, new Pair('There was an error while saving your workbasket', '')],
|
[NOTIFICATION_TYPES.SAVE_ERR_4, { left: 'There was an error while saving your workbasket', right: '' }],
|
||||||
// workbasket-information.component
|
// workbasket-information.component
|
||||||
[NOTIFICATION_TYPES.CREATE_ERR_2, new Pair('There was an error while creating this workbasket', '')],
|
[NOTIFICATION_TYPES.CREATE_ERR_2, { left: 'There was an error while creating this workbasket', right: '' }],
|
||||||
// workbasket-information.component
|
// workbasket-information.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.MARK_ERR,
|
NOTIFICATION_TYPES.MARK_ERR,
|
||||||
new Pair(
|
{
|
||||||
'Workbasket was marked for deletion.',
|
left: 'Workbasket was marked for deletion.',
|
||||||
'The Workbasket {workbasketId} still contains completed tasks and could not be deleted.' +
|
right:
|
||||||
|
'The Workbasket {workbasketId} still contains completed tasks and could not be deleted.' +
|
||||||
' Instead is was marked for deletion and will be deleted automatically ' +
|
' Instead is was marked for deletion and will be deleted automatically ' +
|
||||||
'as soon as the completed tasks are cleared from the database.'
|
'as soon as the completed tasks are cleared from the database.'
|
||||||
)
|
}
|
||||||
],
|
],
|
||||||
// domain.guard
|
// domain.guard
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.FETCH_ERR_5,
|
NOTIFICATION_TYPES.FETCH_ERR_5,
|
||||||
new Pair('There was an error, please contact your administrator', 'There was an error getting Domains')
|
{ left: 'There was an error, please contact your administrator', right: 'There was an error getting Domains' }
|
||||||
],
|
],
|
||||||
// history.guard
|
// history.guard
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.FETCH_ERR_6,
|
NOTIFICATION_TYPES.FETCH_ERR_6,
|
||||||
new Pair('There was an error, please contact your administrator', 'There was an error getting history provider')
|
{
|
||||||
|
left: 'There was an error, please contact your administrator',
|
||||||
|
right: 'There was an error getting history provider'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
// http-client-interceptor.service
|
// http-client-interceptor.service
|
||||||
[NOTIFICATION_TYPES.ACCESS_ERR, new Pair('You have no access to this resource', '')],
|
[NOTIFICATION_TYPES.ACCESS_ERR, { left: 'You have no access to this resource', right: '' }],
|
||||||
// http-client-interceptor.service
|
// http-client-interceptor.service
|
||||||
[NOTIFICATION_TYPES.GENERAL_ERR, new Pair('There was an error, please contact your administrator', '')],
|
[NOTIFICATION_TYPES.GENERAL_ERR, { left: 'There was an error, please contact your administrator', right: '' }],
|
||||||
// spinner.component
|
// spinner.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.TIMEOUT_ERR,
|
NOTIFICATION_TYPES.TIMEOUT_ERR,
|
||||||
new Pair(
|
{
|
||||||
'There was an error with your request, please make sure you have internet connection',
|
left: 'There was an error with your request, please make sure you have internet connection',
|
||||||
'Request time exceeded'
|
right: 'Request time exceeded'
|
||||||
)
|
}
|
||||||
],
|
],
|
||||||
// taskdetails.component
|
// taskdetails.component
|
||||||
[NOTIFICATION_TYPES.FETCH_ERR_7, new Pair('An error occurred while fetching the task', '')],
|
[NOTIFICATION_TYPES.FETCH_ERR_7, { left: 'An error occurred while fetching the task', right: '' }],
|
||||||
// taskdetails.component
|
// taskdetails.component
|
||||||
[NOTIFICATION_TYPES.DELETE_ERR_2, new Pair('An error occurred while deleting the task', '')],
|
[NOTIFICATION_TYPES.DELETE_ERR_2, { left: 'An error occurred while deleting the task', right: '' }],
|
||||||
|
|
||||||
// ALERTS
|
// ALERTS
|
||||||
|
|
||||||
// access-items-management.component
|
// access-items-management.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT, new Pair('', '{accessId} was removed successfully')],
|
[NOTIFICATION_TYPES.SUCCESS_ALERT, { left: '', right: '{accessId} was removed successfully' }],
|
||||||
// classification-details.component
|
// classification-details.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_2, new Pair('', 'Classification {classificationKey} was created successfully')],
|
[
|
||||||
|
NOTIFICATION_TYPES.SUCCESS_ALERT_2,
|
||||||
|
{ left: '', right: 'Classification {classificationKey} was created successfully' }
|
||||||
|
],
|
||||||
// classification-details.component
|
// classification-details.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_3, new Pair('', 'Classification {classificationKey} was saved successfully')],
|
[
|
||||||
|
NOTIFICATION_TYPES.SUCCESS_ALERT_3,
|
||||||
|
{ left: '', right: 'Classification {classificationKey} was saved successfully' }
|
||||||
|
],
|
||||||
// classification-details.component
|
// classification-details.component
|
||||||
// access-items.component
|
// access-items.component
|
||||||
// workbasket.distribution-targets.component
|
// workbasket.distribution-targets.component
|
||||||
// workbasket-information.component
|
// workbasket-information.component
|
||||||
// taskdetails.component
|
// taskdetails.component
|
||||||
[NOTIFICATION_TYPES.INFO_ALERT, new Pair('', 'Information restored')],
|
[NOTIFICATION_TYPES.INFO_ALERT, { left: '', right: 'Information restored' }],
|
||||||
// classification-details.component
|
// classification-details.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_4, new Pair('', 'Classification {classificationKey} was removed successfully')],
|
[
|
||||||
|
NOTIFICATION_TYPES.SUCCESS_ALERT_4,
|
||||||
|
{ left: '', right: 'Classification {classificationKey} was removed successfully' }
|
||||||
|
],
|
||||||
// classification-list.component
|
// classification-list.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_5, new Pair('', 'Classification {classificationKey} was moved successfully')],
|
[
|
||||||
|
NOTIFICATION_TYPES.SUCCESS_ALERT_5,
|
||||||
|
{ left: '', right: 'Classification {classificationKey} was moved successfully' }
|
||||||
|
],
|
||||||
// import-export.component
|
// import-export.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_6, new Pair('', 'Import was successful')],
|
[NOTIFICATION_TYPES.SUCCESS_ALERT_6, { left: '', right: 'Import was successful' }],
|
||||||
// access-items.component
|
// access-items.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_7, new Pair('', 'Workbasket {workbasketKey} Access items were saved successfully')],
|
[
|
||||||
|
NOTIFICATION_TYPES.SUCCESS_ALERT_7,
|
||||||
|
{ left: '', right: 'Workbasket {workbasketKey} Access items were saved successfully' }
|
||||||
|
],
|
||||||
// workbasket.distribution-targets.component
|
// workbasket.distribution-targets.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.SUCCESS_ALERT_8,
|
NOTIFICATION_TYPES.SUCCESS_ALERT_8,
|
||||||
new Pair('', 'Workbasket {workbasketName} Distribution targets were saved successfully')
|
{ left: '', right: 'Workbasket {workbasketName} Distribution targets were saved successfully' }
|
||||||
],
|
],
|
||||||
// workbasket-information.component
|
// workbasket-information.component
|
||||||
[
|
[
|
||||||
NOTIFICATION_TYPES.SUCCESS_ALERT_9,
|
NOTIFICATION_TYPES.SUCCESS_ALERT_9,
|
||||||
new Pair('', 'DistributionTargets for workbasketID {workbasketId} was removed successfully')
|
{ left: '', right: 'DistributionTargets for workbasketID {workbasketId} was removed successfully' }
|
||||||
],
|
],
|
||||||
// workbasket-information.component
|
// workbasket-information.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_10, new Pair('', 'Workbasket {workbasketKey} was saved successfully')],
|
[NOTIFICATION_TYPES.SUCCESS_ALERT_10, { left: '', right: 'Workbasket {workbasketKey} was saved successfully' }],
|
||||||
// workbasket-information.component
|
// workbasket-information.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_11, new Pair('', 'Workbasket {workbasketKey} was created successfully')],
|
[NOTIFICATION_TYPES.SUCCESS_ALERT_11, { left: '', right: 'Workbasket {workbasketKey} was created successfully' }],
|
||||||
// workbasket-information.component
|
// workbasket-information.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_12, new Pair('', 'The Workbasket {workbasketId} has been deleted.')],
|
[NOTIFICATION_TYPES.SUCCESS_ALERT_12, { left: '', right: 'The Workbasket {workbasketId} has been deleted.' }],
|
||||||
// forms-validator.service
|
// forms-validator.service
|
||||||
[NOTIFICATION_TYPES.WARNING_ALERT, new Pair('', 'There are some empty fields which are required.')],
|
[NOTIFICATION_TYPES.WARNING_ALERT, { left: '', right: 'There are some empty fields which are required.' }],
|
||||||
// forms-validator.service x2
|
// forms-validator.service x2
|
||||||
[NOTIFICATION_TYPES.WARNING_ALERT_2, new Pair('', 'The {owner} introduced is not valid.')],
|
[NOTIFICATION_TYPES.WARNING_ALERT_2, { left: '', right: 'The {owner} introduced is not valid.' }],
|
||||||
// taskdetails.component
|
// taskdetails.component
|
||||||
[NOTIFICATION_TYPES.DANGER_ALERT, new Pair('', 'There was an error while updating.')],
|
[NOTIFICATION_TYPES.DANGER_ALERT, { left: '', right: 'There was an error while updating.' }],
|
||||||
// taskdetails.component
|
// taskdetails.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_13, new Pair('', 'Task {taskId} was created successfully.')],
|
[NOTIFICATION_TYPES.SUCCESS_ALERT_13, { left: '', right: 'Task {taskId} was created successfully.' }],
|
||||||
// taskdetails.component
|
// taskdetails.component
|
||||||
[NOTIFICATION_TYPES.SUCCESS_ALERT_14, new Pair('', 'Updating was successful.')],
|
[NOTIFICATION_TYPES.SUCCESS_ALERT_14, { left: '', right: 'Updating was successful.' }],
|
||||||
// taskdetails.component
|
// taskdetails.component
|
||||||
[NOTIFICATION_TYPES.DANGER_ALERT_2, new Pair('', 'There was an error while creating a new task.')],
|
[NOTIFICATION_TYPES.DANGER_ALERT_2, { left: '', right: 'There was an error while creating a new task.' }],
|
||||||
// task-master.component
|
// task-master.component
|
||||||
[NOTIFICATION_TYPES.INFO_ALERT_2, new Pair('', 'The selected Workbasket is empty!')],
|
[NOTIFICATION_TYPES.INFO_ALERT_2, { left: '', right: 'The selected Workbasket is empty!' }],
|
||||||
[NOTIFICATION_TYPES.WARNING_CANT_COPY, new Pair('', "Can't copy a not created classification")]
|
[NOTIFICATION_TYPES.WARNING_CANT_COPY, { left: '', right: "Can't copy a not created classification" }]
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
export class Pair {
|
export interface Pair<L, R> {
|
||||||
constructor(public name?: string, public text?: string) {}
|
left: L;
|
||||||
|
right: R;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface QueryPagingParameter {
|
||||||
|
page?: number;
|
||||||
|
'page-size'?: number;
|
||||||
|
}
|
|
@ -1,13 +1,87 @@
|
||||||
export enum Direction {
|
export enum Direction {
|
||||||
ASC = 'asc',
|
ASC = 'ASCENDING',
|
||||||
DESC = 'desc'
|
DESC = 'DESCENDING'
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Sorting {
|
export interface Sorting<T> {
|
||||||
sortBy: string;
|
'sort-by': T;
|
||||||
sortDirection: string;
|
order: Direction;
|
||||||
constructor(sortBy: string = 'key', sortDirection: Direction = Direction.ASC) {
|
}
|
||||||
this.sortBy = sortBy;
|
|
||||||
this.sortDirection = sortDirection;
|
export enum TaskQuerySortParameter {
|
||||||
}
|
CLASSIFICATION_KEY = 'CLASSIFICATION_KEY',
|
||||||
|
POR_TYPE = 'POR_TYPE',
|
||||||
|
POR_VALUE = 'POR_VALUE',
|
||||||
|
STATE = 'STATE',
|
||||||
|
NAME = 'NAME',
|
||||||
|
DUE = 'DUE',
|
||||||
|
PLANNED = 'PLANNED',
|
||||||
|
PRIORITY = 'PRIORITY'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TASK_SORT_PARAMETER_NAMING: Map<TaskQuerySortParameter, string> = new Map([
|
||||||
|
[TaskQuerySortParameter.NAME, 'Name'],
|
||||||
|
[TaskQuerySortParameter.PRIORITY, 'Priority'],
|
||||||
|
[TaskQuerySortParameter.DUE, 'Due'],
|
||||||
|
[TaskQuerySortParameter.PLANNED, 'Planned']
|
||||||
|
]);
|
||||||
|
|
||||||
|
export enum WorkbasketQuerySortParameter {
|
||||||
|
NAME = 'NAME',
|
||||||
|
KEY = 'KEY',
|
||||||
|
OWNER = 'OWNER',
|
||||||
|
TYPE = 'TYPE',
|
||||||
|
DESCRIPTION = 'DESCRIPTION'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const WORKBASKET_SORT_PARAMETER_NAMING: Map<WorkbasketQuerySortParameter, string> = new Map([
|
||||||
|
[WorkbasketQuerySortParameter.NAME, 'Name'],
|
||||||
|
[WorkbasketQuerySortParameter.KEY, 'Key'],
|
||||||
|
[WorkbasketQuerySortParameter.DESCRIPTION, 'Description'],
|
||||||
|
[WorkbasketQuerySortParameter.OWNER, 'Owner'],
|
||||||
|
[WorkbasketQuerySortParameter.TYPE, 'Type']
|
||||||
|
]);
|
||||||
|
|
||||||
|
export enum WorkbasketAccessItemQuerySortParameter {
|
||||||
|
WORKBASKET_KEY = 'WORKBASKET_KEY',
|
||||||
|
ACCESS_ID = 'ACCESS_ID'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const WORKBASKET_ACCESS_ITEM_SORT_PARAMETER_NAMING: Map<
|
||||||
|
WorkbasketAccessItemQuerySortParameter,
|
||||||
|
string
|
||||||
|
> = new Map([
|
||||||
|
[WorkbasketAccessItemQuerySortParameter.ACCESS_ID, 'Access id'],
|
||||||
|
[WorkbasketAccessItemQuerySortParameter.WORKBASKET_KEY, 'Workbasket Key']
|
||||||
|
]);
|
||||||
|
|
||||||
|
export enum ClassificationQuerySortParameter {
|
||||||
|
DOMAIN = 'DOMAIN',
|
||||||
|
KEY = 'KEY',
|
||||||
|
CATEGORY = 'CATEGORY',
|
||||||
|
NAME = 'NAME'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum TaskHistoryQuerySortParameter {
|
||||||
|
TASK_HISTORY_EVENT_ID = 'TASK_HISTORY_EVENT_ID',
|
||||||
|
BUSINESS_PROCESS_ID = 'BUSINESS_PROCESS_ID',
|
||||||
|
PARENT_BUSINESS_PROCESS_ID = 'PARENT_BUSINESS_PROCESS_ID',
|
||||||
|
TASK_ID = 'TASK_ID',
|
||||||
|
EVENT_TYPE = 'EVENT_TYPE',
|
||||||
|
CREATED = 'CREATED',
|
||||||
|
USER_ID = 'USER_ID',
|
||||||
|
DOMAIN = 'DOMAIN',
|
||||||
|
WORKBASKET_KEY = 'WORKBASKET_KEY',
|
||||||
|
POR_COMPANY = 'POR_COMPANY',
|
||||||
|
POR_SYSTEM = 'POR_SYSTEM',
|
||||||
|
POR_INSTANCE = 'POR_INSTANCE',
|
||||||
|
POR_TYPE = 'POR_TYPE',
|
||||||
|
POR_VALUE = 'POR_VALUE',
|
||||||
|
TASK_CLASSIFICATION_KEY = 'TASK_CLASSIFICATION_KEY',
|
||||||
|
TASK_CLASSIFICATION_CATEGORY = 'TASK_CLASSIFICATION_CATEGORY',
|
||||||
|
ATTACHMENT_CLASSIFICATION_KEY = 'ATTACHMENT_CLASSIFICATION_KEY',
|
||||||
|
CUSTOM_1 = 'CUSTOM_1',
|
||||||
|
CUSTOM_2 = 'CUSTOM_2',
|
||||||
|
CUSTOM_3 = 'CUSTOM_3',
|
||||||
|
CUSTOM_4 = 'CUSTOM_4'
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
export interface TaskHistoryQueryFilterParameter {
|
||||||
|
'event-type': string[];
|
||||||
|
'event-type-like': string[];
|
||||||
|
'user-id': string[];
|
||||||
|
'user-id-like': string[];
|
||||||
|
created: string[];
|
||||||
|
domain: string[];
|
||||||
|
'task-id': string[];
|
||||||
|
'task-id-like': string[];
|
||||||
|
'business-process-id': string[];
|
||||||
|
'business-process-id-like': string[];
|
||||||
|
'parent-business-process-id': string[];
|
||||||
|
'parent-business-process-id-like': string[];
|
||||||
|
'task-classification-key': string[];
|
||||||
|
'task-classification-key-like': string[];
|
||||||
|
'task-classification-category': string[];
|
||||||
|
'task-classification-category-like': string[];
|
||||||
|
'attachment-classification-key': string[];
|
||||||
|
'attachment-classification-key-like': string[];
|
||||||
|
'workbasket-key-like': string[];
|
||||||
|
'por-company': string[];
|
||||||
|
'por-company-like': string[];
|
||||||
|
'por-system': string[];
|
||||||
|
'por-system-like': string[];
|
||||||
|
'por-instance': string[];
|
||||||
|
'por-instance-like': string[];
|
||||||
|
'por-value': string[];
|
||||||
|
'por-value-like': string[];
|
||||||
|
'custom-1': string[];
|
||||||
|
'custom-1-like': string[];
|
||||||
|
'custom-2': string[];
|
||||||
|
'custom-2-like': string[];
|
||||||
|
'custom-3': string[];
|
||||||
|
'custom-3-like': string[];
|
||||||
|
'custom-4': string[];
|
||||||
|
'custom-4-like': string[];
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { TaskState } from './task-state';
|
||||||
|
|
||||||
|
export interface TaskQueryFilterParameter {
|
||||||
|
name?: string[];
|
||||||
|
'name-like'?: string[];
|
||||||
|
priority?: number[];
|
||||||
|
state?: TaskState[];
|
||||||
|
'classification.key'?: string[];
|
||||||
|
'task-id'?: string[];
|
||||||
|
'workbasket-id'?: string[];
|
||||||
|
'workbasket-key'?: string[];
|
||||||
|
domain?: string[];
|
||||||
|
owner?: string[];
|
||||||
|
'owner-like'?: string[];
|
||||||
|
'por.company'?: string[];
|
||||||
|
'por.system'?: string[];
|
||||||
|
'por.instance'?: string[];
|
||||||
|
'por.type'?: string[];
|
||||||
|
'por.value'?: string[];
|
||||||
|
planned?: string[];
|
||||||
|
'planned-from'?: string[];
|
||||||
|
'planned-until'?: string[];
|
||||||
|
due?: string[];
|
||||||
|
'due-from'?: string[];
|
||||||
|
'due-until'?: string[];
|
||||||
|
'wildcard-search-fields'?: string[];
|
||||||
|
'wildcard-search-value'?: string[];
|
||||||
|
'external-id'?: string[];
|
||||||
|
'custom-1'?: string[];
|
||||||
|
'custom-2'?: string[];
|
||||||
|
'custom-3'?: string[];
|
||||||
|
'custom-4'?: string[];
|
||||||
|
'custom-5'?: string[];
|
||||||
|
'custom-6'?: string[];
|
||||||
|
'custom-7'?: string[];
|
||||||
|
'custom-8'?: string[];
|
||||||
|
'custom-9'?: string[];
|
||||||
|
'custom-10'?: string[];
|
||||||
|
'custom-11'?: string[];
|
||||||
|
'custom-12'?: string[];
|
||||||
|
'custom-13'?: string[];
|
||||||
|
'custom-14'?: string[];
|
||||||
|
'custom-15'?: string[];
|
||||||
|
'custom-16'?: string[];
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
export enum TaskState {
|
||||||
|
READY = 'READY',
|
||||||
|
CLAIMED = 'CLAIMED',
|
||||||
|
COMPLETED = 'COMPLETED',
|
||||||
|
CANCELLED = 'CANCELLED',
|
||||||
|
TERMINATED = 'TERMINATED'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ALL_STATES: Map<TaskState, string> = new Map([
|
||||||
|
[undefined, 'All'],
|
||||||
|
[TaskState.READY, 'Ready'],
|
||||||
|
[TaskState.CLAIMED, 'Claimed'],
|
||||||
|
[TaskState.COMPLETED, 'Completed'],
|
||||||
|
[TaskState.CANCELLED, 'Cancelled'],
|
||||||
|
[TaskState.TERMINATED, 'Terminated']
|
||||||
|
]);
|
|
@ -0,0 +1,6 @@
|
||||||
|
export interface WorkbasketAccessItemQueryFilterParameter {
|
||||||
|
'workbasket-key'?: string[];
|
||||||
|
'workbasket-key-like'?: string[];
|
||||||
|
'access-id'?: string[];
|
||||||
|
'access-id-like'?: string[];
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
export enum WorkbasketPermission {
|
||||||
|
READ = 'READ',
|
||||||
|
OPEN = 'OPEN',
|
||||||
|
APPEND = 'APPEND',
|
||||||
|
TRANSFER = 'TRANSFER',
|
||||||
|
DISTRIBUTE = 'DISTRIBUTE',
|
||||||
|
CUSTOM_1 = 'CUSTOM_1',
|
||||||
|
CUSTOM_2 = 'CUSTOM_2',
|
||||||
|
CUSTOM_3 = 'CUSTOM_3',
|
||||||
|
CUSTOM_4 = 'CUSTOM_4',
|
||||||
|
CUSTOM_5 = 'CUSTOM_5',
|
||||||
|
CUSTOM_6 = 'CUSTOM_6',
|
||||||
|
CUSTOM_7 = 'CUSTOM_7',
|
||||||
|
CUSTOM_8 = 'CUSTOM_8',
|
||||||
|
CUSTOM_9 = 'CUSTOM_9',
|
||||||
|
CUSTOM_10 = 'CUSTOM_10',
|
||||||
|
CUSTOM_11 = 'CUSTOM_11',
|
||||||
|
CUSTOM_12 = 'CUSTOM_12'
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { WorkbasketType } from './workbasket-type';
|
||||||
|
import { WorkbasketPermission } from './workbasket-permission';
|
||||||
|
|
||||||
|
export interface WorkbasketQueryFilterParameter {
|
||||||
|
name?: string[];
|
||||||
|
'name-like'?: string[];
|
||||||
|
key?: string[];
|
||||||
|
'key-like'?: string[];
|
||||||
|
owner?: string[];
|
||||||
|
'owner-like'?: string[];
|
||||||
|
'description-like'?: string[];
|
||||||
|
domain?: string[];
|
||||||
|
type?: WorkbasketType[];
|
||||||
|
'required-permission'?: WorkbasketPermission[];
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
import { ICONTYPES } from './icon-types';
|
import { WorkbasketType } from './workbasket-type';
|
||||||
|
|
||||||
export interface WorkbasketSummary {
|
export interface WorkbasketSummary {
|
||||||
workbasketId?: string;
|
workbasketId?: string;
|
||||||
key?: string;
|
key?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
domain?: string;
|
domain?: string;
|
||||||
type?: ICONTYPES;
|
type?: WorkbasketType;
|
||||||
description?: string;
|
description?: string;
|
||||||
owner?: string;
|
owner?: string;
|
||||||
custom1?: string;
|
custom1?: string;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
export enum WorkbasketType {
|
||||||
|
PERSONAL = 'PERSONAL',
|
||||||
|
GROUP = 'GROUP',
|
||||||
|
CLEARANCE = 'CLEARANCE',
|
||||||
|
TOPIC = 'TOPIC'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ALL_TYPES: Map<WorkbasketType, string> = new Map([
|
||||||
|
[undefined, 'All'],
|
||||||
|
[WorkbasketType.PERSONAL, 'Personal'],
|
||||||
|
[WorkbasketType.GROUP, 'Group'],
|
||||||
|
[WorkbasketType.CLEARANCE, 'Clearance'],
|
||||||
|
[WorkbasketType.TOPIC, 'Topic']
|
||||||
|
]);
|
|
@ -1,12 +1,12 @@
|
||||||
import { Links } from './links';
|
import { Links } from './links';
|
||||||
import { ICONTYPES } from './icon-types';
|
import { WorkbasketType } from './workbasket-type';
|
||||||
|
|
||||||
export interface Workbasket {
|
export interface Workbasket {
|
||||||
workbasketId?: string;
|
workbasketId?: string;
|
||||||
key?: string;
|
key?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
domain?: string;
|
domain?: string;
|
||||||
type?: ICONTYPES;
|
type?: WorkbasketType;
|
||||||
description?: string;
|
description?: string;
|
||||||
owner?: string;
|
owner?: string;
|
||||||
custom1?: string;
|
custom1?: string;
|
||||||
|
@ -21,6 +21,8 @@ export interface Workbasket {
|
||||||
created?: string;
|
created?: string;
|
||||||
modified?: string;
|
modified?: string;
|
||||||
_links?: Links;
|
_links?: Links;
|
||||||
|
// this is not part of the API, but needed for frontend
|
||||||
|
selected?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const customFieldCount: number = 4;
|
export const customFieldCount: number = 4;
|
||||||
|
|
|
@ -1,31 +1,21 @@
|
||||||
import { Pipe, PipeTransform } from '@angular/core';
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
|
||||||
import { WorkbasketSummary } from '../models/workbasket-summary';
|
import { WorkbasketSummary } from '../models/workbasket-summary';
|
||||||
|
import { Side } from '../../administration/components/workbasket-distribution-targets/workbasket-distribution-targets.component';
|
||||||
|
|
||||||
@Pipe({ name: 'selectWorkbaskets' })
|
@Pipe({ name: 'selectWorkbaskets' })
|
||||||
export class SelectWorkBasketPipe implements PipeTransform {
|
export class SelectWorkBasketPipe implements PipeTransform {
|
||||||
transform(originArray: any, selectionArray: any, arg1: any): WorkbasketSummary[] {
|
transform(
|
||||||
let returnArray = [];
|
allWorkbaskets: WorkbasketSummary[],
|
||||||
if (!originArray || !selectionArray) {
|
selectedWorkbaskets: WorkbasketSummary[],
|
||||||
return returnArray;
|
side: Side
|
||||||
|
): WorkbasketSummary[] {
|
||||||
|
if (!allWorkbaskets || !selectedWorkbaskets) {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
for (let index = originArray.length - 1; index >= 0; index--) {
|
if (side === Side.SELECTED) {
|
||||||
if (
|
return selectedWorkbaskets;
|
||||||
(arg1 &&
|
|
||||||
!selectionArray.some(
|
|
||||||
(elementToRemove) => originArray[index].workbasketId === elementToRemove.workbasketId
|
|
||||||
)) ||
|
|
||||||
(!arg1 &&
|
|
||||||
selectionArray.some((elementToRemove) => originArray[index].workbasketId === elementToRemove.workbasketId))
|
|
||||||
) {
|
|
||||||
originArray.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const isNotSelectedWorkbasket = (wb) => !selectedWorkbaskets.some((sWb) => sWb.workbasketId === wb.workbasketId);
|
||||||
if (originArray.length > TaskanaQueryParameters.pageSize) {
|
return allWorkbaskets.filter(isNotSelectedWorkbasket);
|
||||||
originArray.slice(0, TaskanaQueryParameters.pageSize);
|
|
||||||
}
|
|
||||||
returnArray = originArray;
|
|
||||||
return returnArray;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,11 @@ import { environment } from 'environments/environment';
|
||||||
import { AccessIdDefinition } from 'app/shared/models/access-id';
|
import { AccessIdDefinition } from 'app/shared/models/access-id';
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { WorkbasketAccessItemsRepresentation } from 'app/shared/models/workbasket-access-items-representation';
|
import { WorkbasketAccessItemsRepresentation } from 'app/shared/models/workbasket-access-items-representation';
|
||||||
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
import { Sorting, WorkbasketAccessItemQuerySortParameter } from 'app/shared/models/sorting';
|
||||||
import { Sorting } from 'app/shared/models/sorting';
|
|
||||||
import { QueryParameters } from 'app/shared/models/query-parameters';
|
|
||||||
import { StartupService } from '../startup/startup.service';
|
import { StartupService } from '../startup/startup.service';
|
||||||
|
import { WorkbasketAccessItemQueryFilterParameter } from '../../models/workbasket-access-item-query-filter-parameter';
|
||||||
|
import { QueryPagingParameter } from '../../models/query-paging-parameter';
|
||||||
|
import { asUrlQueryString } from '../../util/query-parameters-v2';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
|
@ -34,16 +35,17 @@ export class AccessIdsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccessItems(
|
getAccessItems(
|
||||||
accessIds: AccessIdDefinition[],
|
filterParameter?: WorkbasketAccessItemQueryFilterParameter,
|
||||||
accessIdLike?: string,
|
sortParameter?: Sorting<WorkbasketAccessItemQuerySortParameter>,
|
||||||
workbasketKeyLike?: string,
|
pagingParameter?: QueryPagingParameter
|
||||||
sortModel: Sorting = new Sorting('workbasket-key')
|
|
||||||
): Observable<WorkbasketAccessItemsRepresentation> {
|
): Observable<WorkbasketAccessItemsRepresentation> {
|
||||||
return this.httpClient.get<WorkbasketAccessItemsRepresentation>(
|
return this.httpClient.get<WorkbasketAccessItemsRepresentation>(
|
||||||
encodeURI(
|
encodeURI(
|
||||||
`${environment.taskanaRestUrl}/v1/workbasket-access-items/${TaskanaQueryParameters.getQueryParameters(
|
`${environment.taskanaRestUrl}/v1/workbasket-access-items/${asUrlQueryString({
|
||||||
AccessIdsService.accessIdsParameters(sortModel, accessIds, accessIdLike, workbasketKeyLike)
|
...filterParameter,
|
||||||
)}`
|
...sortParameter,
|
||||||
|
...pagingParameter
|
||||||
|
})}`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -53,22 +55,4 @@ export class AccessIdsService {
|
||||||
`${environment.taskanaRestUrl}/v1/workbasket-access-items/?access-id=${accessId}`
|
`${environment.taskanaRestUrl}/v1/workbasket-access-items/?access-id=${accessId}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static accessIdsParameters(
|
|
||||||
sortModel: Sorting,
|
|
||||||
accessIds: AccessIdDefinition[],
|
|
||||||
accessIdLike?: string,
|
|
||||||
workbasketKeyLike?: string
|
|
||||||
): QueryParameters {
|
|
||||||
// TODO extend this query for support of multiple sortbys
|
|
||||||
const parameters = new QueryParameters();
|
|
||||||
parameters.SORTBY = sortModel.sortBy;
|
|
||||||
parameters.SORTDIRECTION = sortModel.sortDirection;
|
|
||||||
parameters.ACCESSIDS = accessIds.map((values: AccessIdDefinition) => values.accessId).join('|');
|
|
||||||
parameters.ACCESSIDLIKE = accessIdLike;
|
|
||||||
parameters.WORKBASKETKEYLIKE = workbasketKeyLike;
|
|
||||||
delete TaskanaQueryParameters.page;
|
|
||||||
delete TaskanaQueryParameters.pageSize;
|
|
||||||
return parameters;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,19 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { mergeMap, tap } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { Classification } from 'app/shared/models/classification';
|
import { Classification } from 'app/shared/models/classification';
|
||||||
|
|
||||||
import { ClassificationPagingList } from 'app/shared/models/classification-paging-list';
|
import { ClassificationPagingList } from 'app/shared/models/classification-paging-list';
|
||||||
import { DomainService } from 'app/shared/services/domain/domain.service';
|
import { DomainService } from 'app/shared/services/domain/domain.service';
|
||||||
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
import { ClassificationQuerySortParameter, Sorting } from 'app/shared/models/sorting';
|
||||||
import { Direction } from 'app/shared/models/sorting';
|
|
||||||
import { QueryParameters } from 'app/shared/models/query-parameters';
|
|
||||||
import { StartupService } from '../startup/startup.service';
|
import { StartupService } from '../startup/startup.service';
|
||||||
|
import { asUrlQueryString } from '../../util/query-parameters-v2';
|
||||||
|
import { ClassificationQueryFilterParameters } from '../../models/classification-query-filter-parameters';
|
||||||
|
import { QueryPagingParameter } from '../../models/query-paging-parameter';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ClassificationsService {
|
export class ClassificationsService {
|
||||||
private classificationResourcePromise: Promise<ClassificationPagingList>;
|
|
||||||
private lastDomain: string;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private httpClient: HttpClient,
|
private httpClient: HttpClient,
|
||||||
private domainService: DomainService,
|
private domainService: DomainService,
|
||||||
|
@ -27,47 +24,17 @@ export class ClassificationsService {
|
||||||
return this.startupService.getTaskanaRestUrl() + '/v1/classifications/';
|
return this.startupService.getTaskanaRestUrl() + '/v1/classifications/';
|
||||||
}
|
}
|
||||||
|
|
||||||
private static classificationParameters(domain: string, type?: string): QueryParameters {
|
|
||||||
const parameters = new QueryParameters();
|
|
||||||
parameters.SORTBY = TaskanaQueryParameters.parameters.KEY;
|
|
||||||
parameters.SORTDIRECTION = Direction.ASC;
|
|
||||||
parameters.DOMAIN = domain;
|
|
||||||
parameters.TYPE = type;
|
|
||||||
delete TaskanaQueryParameters.page;
|
|
||||||
delete TaskanaQueryParameters.pageSize;
|
|
||||||
|
|
||||||
return parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET
|
// GET
|
||||||
getClassifications(classificationType?: string): Observable<ClassificationPagingList> {
|
getClassifications(
|
||||||
return this.domainService.getSelectedDomain().pipe(
|
filterParameter?: ClassificationQueryFilterParameters,
|
||||||
mergeMap((domain) =>
|
sortParameter?: Sorting<ClassificationQuerySortParameter>,
|
||||||
this.httpClient.get<ClassificationPagingList>(
|
pagingParameter?: QueryPagingParameter
|
||||||
`${this.url}${TaskanaQueryParameters.getQueryParameters(
|
): Observable<ClassificationPagingList> {
|
||||||
ClassificationsService.classificationParameters(domain, classificationType)
|
return this.httpClient.get<ClassificationPagingList>(
|
||||||
)}`
|
`${this.url}${asUrlQueryString({ ...filterParameter, ...sortParameter, ...pagingParameter })}`
|
||||||
)
|
|
||||||
),
|
|
||||||
tap(() => this.domainService.domainChangedComplete())
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET
|
|
||||||
getClassificationsByDomain(domain: string, forceRefresh = false): Promise<ClassificationPagingList> {
|
|
||||||
if (this.lastDomain !== domain || !this.classificationResourcePromise || forceRefresh) {
|
|
||||||
this.lastDomain = domain;
|
|
||||||
this.classificationResourcePromise = this.httpClient
|
|
||||||
.get<ClassificationPagingList>(
|
|
||||||
`${this.url}${TaskanaQueryParameters.getQueryParameters(
|
|
||||||
ClassificationsService.classificationParameters(domain)
|
|
||||||
)}`
|
|
||||||
)
|
|
||||||
.toPromise();
|
|
||||||
}
|
|
||||||
return this.classificationResourcePromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET
|
// GET
|
||||||
getClassification(id: string): Observable<Classification> {
|
getClassification(id: string): Observable<Classification> {
|
||||||
return this.httpClient.get<Classification>(`${this.url}${id}`);
|
return this.httpClient.get<Classification>(`${this.url}${id}`);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Orientation } from 'app/shared/models/orientation';
|
import { Orientation } from 'app/shared/models/orientation';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class OrientationService {
|
export class OrientationService {
|
||||||
|
@ -9,8 +8,15 @@ export class OrientationService {
|
||||||
private currentOrientation;
|
private currentOrientation;
|
||||||
public orientation = new BehaviorSubject<Orientation>(this.currentOrientation);
|
public orientation = new BehaviorSubject<Orientation>(this.currentOrientation);
|
||||||
|
|
||||||
|
private static detectOrientation(): Orientation {
|
||||||
|
if (window.innerHeight > window.innerWidth) {
|
||||||
|
return Orientation.portrait;
|
||||||
|
}
|
||||||
|
return Orientation.landscape;
|
||||||
|
}
|
||||||
|
|
||||||
onResize() {
|
onResize() {
|
||||||
const orientation = this.detectOrientation();
|
const orientation = OrientationService.detectOrientation();
|
||||||
if (orientation !== this.currentOrientation) {
|
if (orientation !== this.currentOrientation) {
|
||||||
this.currentOrientation = orientation;
|
this.currentOrientation = orientation;
|
||||||
if (!this.lock) {
|
if (!this.lock) {
|
||||||
|
@ -41,14 +47,6 @@ export class OrientationService {
|
||||||
if (doubleList && window.innerWidth < 992) {
|
if (doubleList && window.innerWidth < 992) {
|
||||||
cards = Math.floor(cards / 2);
|
cards = Math.floor(cards / 2);
|
||||||
}
|
}
|
||||||
TaskanaQueryParameters.pageSize = cards > 0 ? cards : 1;
|
|
||||||
return cards;
|
return cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
private detectOrientation(): Orientation {
|
|
||||||
if (window.innerHeight > window.innerWidth) {
|
|
||||||
return Orientation.portrait;
|
|
||||||
}
|
|
||||||
return Orientation.landscape;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,14 @@ import { WorkbasketAccessItems } from 'app/shared/models/workbasket-access-items
|
||||||
import { WorkbasketSummaryRepresentation } from 'app/shared/models/workbasket-summary-representation';
|
import { WorkbasketSummaryRepresentation } from 'app/shared/models/workbasket-summary-representation';
|
||||||
import { WorkbasketAccessItemsRepresentation } from 'app/shared/models/workbasket-access-items-representation';
|
import { WorkbasketAccessItemsRepresentation } from 'app/shared/models/workbasket-access-items-representation';
|
||||||
import { WorkbasketDistributionTargets } from 'app/shared/models/workbasket-distribution-targets';
|
import { WorkbasketDistributionTargets } from 'app/shared/models/workbasket-distribution-targets';
|
||||||
import { Direction } from 'app/shared/models/sorting';
|
import { Sorting, WorkbasketQuerySortParameter } from 'app/shared/models/sorting';
|
||||||
|
|
||||||
import { DomainService } from 'app/shared/services/domain/domain.service';
|
import { DomainService } from 'app/shared/services/domain/domain.service';
|
||||||
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
|
||||||
import { mergeMap, tap, catchError } from 'rxjs/operators';
|
import { mergeMap, tap, catchError } from 'rxjs/operators';
|
||||||
import { QueryParameters } from 'app/shared/models/query-parameters';
|
|
||||||
import { WorkbasketRepresentation } from '../../models/workbasket-representation';
|
import { WorkbasketRepresentation } from '../../models/workbasket-representation';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../models/workbasket-query-parameters';
|
||||||
|
import { QueryPagingParameter } from '../../models/query-paging-parameter';
|
||||||
|
import { asUrlQueryString } from '../../util/query-parameters-v2';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkbasketService {
|
export class WorkbasketService {
|
||||||
|
@ -28,18 +29,9 @@ export class WorkbasketService {
|
||||||
// GET
|
// GET
|
||||||
getWorkBasketsSummary(
|
getWorkBasketsSummary(
|
||||||
forceRequest: boolean = false,
|
forceRequest: boolean = false,
|
||||||
sortBy: string = TaskanaQueryParameters.parameters.KEY,
|
filterParameter?: WorkbasketQueryFilterParameter,
|
||||||
order: string = Direction.ASC,
|
sortParameter?: Sorting<WorkbasketQuerySortParameter>,
|
||||||
name?: string,
|
pagingParameter?: QueryPagingParameter
|
||||||
nameLike?: string,
|
|
||||||
descLike?: string,
|
|
||||||
owner?: string,
|
|
||||||
ownerLike?: string,
|
|
||||||
type?: string,
|
|
||||||
key?: string,
|
|
||||||
keyLike?: string,
|
|
||||||
requiredPermission?: string,
|
|
||||||
allPages: boolean = false
|
|
||||||
) {
|
) {
|
||||||
if (this.workbasketSummaryRef && !forceRequest) {
|
if (this.workbasketSummaryRef && !forceRequest) {
|
||||||
return this.workbasketSummaryRef;
|
return this.workbasketSummaryRef;
|
||||||
|
@ -48,23 +40,11 @@ export class WorkbasketService {
|
||||||
return this.domainService.getSelectedDomain().pipe(
|
return this.domainService.getSelectedDomain().pipe(
|
||||||
mergeMap((domain) => {
|
mergeMap((domain) => {
|
||||||
this.workbasketSummaryRef = this.httpClient.get<WorkbasketSummaryRepresentation>(
|
this.workbasketSummaryRef = this.httpClient.get<WorkbasketSummaryRepresentation>(
|
||||||
`${environment.taskanaRestUrl}/v1/workbaskets/${TaskanaQueryParameters.getQueryParameters(
|
`${environment.taskanaRestUrl}/v1/workbaskets/${asUrlQueryString({
|
||||||
this.workbasketParameters(
|
...filterParameter,
|
||||||
sortBy,
|
...sortParameter,
|
||||||
order,
|
...pagingParameter
|
||||||
name,
|
})}`
|
||||||
nameLike,
|
|
||||||
descLike,
|
|
||||||
owner,
|
|
||||||
ownerLike,
|
|
||||||
type,
|
|
||||||
key,
|
|
||||||
keyLike,
|
|
||||||
requiredPermission,
|
|
||||||
allPages,
|
|
||||||
domain
|
|
||||||
)
|
|
||||||
)}`
|
|
||||||
);
|
);
|
||||||
return this.workbasketSummaryRef;
|
return this.workbasketSummaryRef;
|
||||||
}),
|
}),
|
||||||
|
@ -179,40 +159,5 @@ export class WorkbasketService {
|
||||||
return observableThrowError(errMsg);
|
return observableThrowError(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private workbasketParameters(
|
|
||||||
sortBy: string = TaskanaQueryParameters.parameters.KEY,
|
|
||||||
order: string = Direction.ASC,
|
|
||||||
name?: string,
|
|
||||||
nameLike?: string,
|
|
||||||
descLike?: string,
|
|
||||||
owner?: string,
|
|
||||||
ownerLike?: string,
|
|
||||||
type?: string,
|
|
||||||
key?: string,
|
|
||||||
keyLike?: string,
|
|
||||||
requiredPermission?: string,
|
|
||||||
allPages?: boolean,
|
|
||||||
domain?: string
|
|
||||||
): QueryParameters {
|
|
||||||
const parameters = new QueryParameters();
|
|
||||||
parameters.SORTBY = sortBy;
|
|
||||||
parameters.SORTDIRECTION = order;
|
|
||||||
parameters.NAME = name;
|
|
||||||
parameters.NAMELIKE = nameLike;
|
|
||||||
parameters.DESCLIKE = descLike;
|
|
||||||
parameters.OWNER = owner;
|
|
||||||
parameters.OWNERLIKE = ownerLike;
|
|
||||||
parameters.TYPE = type;
|
|
||||||
parameters.KEY = key;
|
|
||||||
parameters.KEYLIKE = keyLike;
|
|
||||||
parameters.REQUIREDPERMISSION = requiredPermission;
|
|
||||||
parameters.DOMAIN = domain;
|
|
||||||
if (allPages) {
|
|
||||||
delete TaskanaQueryParameters.page;
|
|
||||||
delete TaskanaQueryParameters.pageSize;
|
|
||||||
}
|
|
||||||
return parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import { SpinnerComponent } from 'app/shared/components/spinner/spinner.componen
|
||||||
import { MasterAndDetailComponent } from 'app/shared/components/master-and-detail/master-and-detail.component';
|
import { MasterAndDetailComponent } from 'app/shared/components/master-and-detail/master-and-detail.component';
|
||||||
import { TaskanaTreeComponent } from 'app/administration/components/tree/tree.component';
|
import { TaskanaTreeComponent } from 'app/administration/components/tree/tree.component';
|
||||||
import { TypeAheadComponent } from 'app/shared/components/type-ahead/type-ahead.component';
|
import { TypeAheadComponent } from 'app/shared/components/type-ahead/type-ahead.component';
|
||||||
import { FilterComponent } from 'app/shared/components/filter/filter.component';
|
|
||||||
import { IconTypeComponent } from 'app/administration/components/type-icon/icon-type.component';
|
import { IconTypeComponent } from 'app/administration/components/type-icon/icon-type.component';
|
||||||
import { FieldErrorDisplayComponent } from 'app/shared/components/field-error-display/field-error-display.component';
|
import { FieldErrorDisplayComponent } from 'app/shared/components/field-error-display/field-error-display.component';
|
||||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
|
@ -61,6 +60,8 @@ import { MatPaginatorModule } from '@angular/material/paginator';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
|
import { WorkbasketFilterComponent } from './components/workbasket-filter/workbasket-filter.component';
|
||||||
|
import { TaskFilterComponent } from './components/task-filter/task-filter.component';
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
@ -93,7 +94,6 @@ const DECLARATIONS = [
|
||||||
OrderBy,
|
OrderBy,
|
||||||
MapToIterable,
|
MapToIterable,
|
||||||
SortComponent,
|
SortComponent,
|
||||||
FilterComponent,
|
|
||||||
IconTypeComponent,
|
IconTypeComponent,
|
||||||
FieldErrorDisplayComponent,
|
FieldErrorDisplayComponent,
|
||||||
PaginationComponent,
|
PaginationComponent,
|
||||||
|
@ -102,7 +102,9 @@ const DECLARATIONS = [
|
||||||
DatePickerComponent,
|
DatePickerComponent,
|
||||||
DropdownComponent,
|
DropdownComponent,
|
||||||
ToastComponent,
|
ToastComponent,
|
||||||
DialogPopUpComponent
|
DialogPopUpComponent,
|
||||||
|
WorkbasketFilterComponent,
|
||||||
|
TaskFilterComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { AccessIdDefinition } from '../../models/access-id';
|
import { AccessIdDefinition } from '../../models/access-id';
|
||||||
import { Sorting } from '../../models/sorting';
|
import { Sorting, WorkbasketAccessItemQuerySortParameter } from '../../models/sorting';
|
||||||
|
import { WorkbasketAccessItemQueryFilterParameter } from '../../models/workbasket-access-item-query-filter-parameter';
|
||||||
|
import { QueryPagingParameter } from '../../models/query-paging-parameter';
|
||||||
|
|
||||||
export class SelectAccessId {
|
export class SelectAccessId {
|
||||||
static readonly type = '[Access Items Management] Select access ID';
|
static readonly type = '[Access Items Management] Select access ID';
|
||||||
|
@ -14,10 +16,9 @@ export class GetGroupsByAccessId {
|
||||||
export class GetAccessItems {
|
export class GetAccessItems {
|
||||||
static readonly type = '[Access Items Management] Get access items';
|
static readonly type = '[Access Items Management] Get access items';
|
||||||
constructor(
|
constructor(
|
||||||
public accessIds: AccessIdDefinition[],
|
public filterParameter?: WorkbasketAccessItemQueryFilterParameter,
|
||||||
public accessIdLike?: string,
|
public sortParameter?: Sorting<WorkbasketAccessItemQuerySortParameter>,
|
||||||
public workbasketKeyLike?: string,
|
public pagingParameter?: QueryPagingParameter
|
||||||
public sortModel: Sorting = new Sorting('workbasket-key')
|
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ export class AccessItemsManagementState implements NgxsAfterBootstrap {
|
||||||
getAccessItems(ctx: StateContext<AccessItemsManagementStateModel>, action: GetAccessItems): Observable<any> {
|
getAccessItems(ctx: StateContext<AccessItemsManagementStateModel>, action: GetAccessItems): Observable<any> {
|
||||||
this.requestInProgressService.setRequestInProgress(true);
|
this.requestInProgressService.setRequestInProgress(true);
|
||||||
return this.accessIdsService
|
return this.accessIdsService
|
||||||
.getAccessItems(action.accessIds, action.accessIdLike, action.workbasketKeyLike, action.sortModel)
|
.getAccessItems(action.filterParameter, action.sortParameter, action.pagingParameter)
|
||||||
.pipe(
|
.pipe(
|
||||||
take(1),
|
take(1),
|
||||||
tap(
|
tap(
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import { Action, NgxsAfterBootstrap, State, StateContext } from '@ngxs/store';
|
import { Action, NgxsAfterBootstrap, State, StateContext } from '@ngxs/store';
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { take, tap } from 'rxjs/operators';
|
import { mergeMap, take, tap } from 'rxjs/operators';
|
||||||
import { TaskanaDate } from 'app/shared/util/taskana.date';
|
import { TaskanaDate } from 'app/shared/util/taskana.date';
|
||||||
import {
|
import {
|
||||||
CategoriesResponse,
|
CategoriesResponse,
|
||||||
ClassificationCategoriesService
|
ClassificationCategoriesService
|
||||||
} from '../../services/classification-categories/classification-categories.service';
|
} from '../../services/classification-categories/classification-categories.service';
|
||||||
import {
|
import {
|
||||||
SaveCreatedClassification,
|
|
||||||
DeselectClassification,
|
|
||||||
GetClassifications,
|
|
||||||
CopyClassification,
|
CopyClassification,
|
||||||
CreateClassification,
|
CreateClassification,
|
||||||
|
DeselectClassification,
|
||||||
|
GetClassifications,
|
||||||
RemoveSelectedClassification,
|
RemoveSelectedClassification,
|
||||||
RestoreSelectedClassification,
|
RestoreSelectedClassification,
|
||||||
|
SaveCreatedClassification,
|
||||||
SaveModifiedClassification,
|
SaveModifiedClassification,
|
||||||
SelectClassification,
|
SelectClassification,
|
||||||
SetSelectedClassificationType,
|
SetSelectedClassificationType,
|
||||||
|
@ -23,6 +23,8 @@ import { ClassificationsService } from '../../services/classifications/classific
|
||||||
import { DomainService } from '../../services/domain/domain.service';
|
import { DomainService } from '../../services/domain/domain.service';
|
||||||
import { Classification } from '../../models/classification';
|
import { Classification } from '../../models/classification';
|
||||||
import { ClassificationSummary } from '../../models/classification-summary';
|
import { ClassificationSummary } from '../../models/classification-summary';
|
||||||
|
import { ClassificationQueryFilterParameters } from '../../models/classification-query-filter-parameters';
|
||||||
|
import { ClassificationQuerySortParameter, Direction, Sorting } from '../../models/sorting';
|
||||||
|
|
||||||
class InitializeStore {
|
class InitializeStore {
|
||||||
static readonly type = '[ClassificationState] Initializing state';
|
static readonly type = '[ClassificationState] Initializing state';
|
||||||
|
@ -94,13 +96,22 @@ export class ClassificationState implements NgxsAfterBootstrap {
|
||||||
@Action(GetClassifications)
|
@Action(GetClassifications)
|
||||||
getClassifications(ctx: StateContext<ClassificationStateModel>): Observable<any> {
|
getClassifications(ctx: StateContext<ClassificationStateModel>): Observable<any> {
|
||||||
const { selectedClassificationType } = ctx.getState();
|
const { selectedClassificationType } = ctx.getState();
|
||||||
return this.classificationsService.getClassifications(selectedClassificationType).pipe(
|
return this.domainService.getSelectedDomain().pipe(
|
||||||
take(1),
|
mergeMap((domain) => {
|
||||||
tap((list) =>
|
const filter: ClassificationQueryFilterParameters = {
|
||||||
ctx.patchState({
|
domain: [domain],
|
||||||
classifications: list.classifications
|
type: [selectedClassificationType]
|
||||||
})
|
};
|
||||||
)
|
const sort: Sorting<ClassificationQuerySortParameter> = {
|
||||||
|
'sort-by': ClassificationQuerySortParameter.KEY,
|
||||||
|
order: Direction.ASC
|
||||||
|
};
|
||||||
|
return this.classificationsService.getClassifications(filter, sort).pipe(
|
||||||
|
take(1),
|
||||||
|
tap((list) => ctx.patchState({ classifications: list.classifications }))
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
tap(() => this.domainService.domainChangedComplete())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Workbasket } from '../../models/workbasket';
|
import { Workbasket } from '../../models/workbasket';
|
||||||
import { ICONTYPES } from '../../models/icon-types';
|
import { WorkbasketType } from '../../models/workbasket-type';
|
||||||
import { ACTION } from '../../models/action';
|
import { ACTION } from '../../models/action';
|
||||||
import { WorkbasketAccessItemsRepresentation } from '../../models/workbasket-access-items-representation';
|
import { WorkbasketAccessItemsRepresentation } from '../../models/workbasket-access-items-representation';
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ export const selectedWorkbasketMock: Workbasket = {
|
||||||
key: 'sOrt003',
|
key: 'sOrt003',
|
||||||
name: 'bAsxet2',
|
name: 'bAsxet2',
|
||||||
domain: 'DOMAIN_A',
|
domain: 'DOMAIN_A',
|
||||||
type: ICONTYPES.TOPIC,
|
type: WorkbasketType.TOPIC,
|
||||||
description: 'Lorem ipsum dolor sit amet.',
|
description: 'Lorem ipsum dolor sit amet.',
|
||||||
owner: 'Max',
|
owner: 'Max',
|
||||||
custom1: '',
|
custom1: '',
|
||||||
|
@ -194,7 +194,7 @@ export const workbasketReadStateMock = {
|
||||||
key: 'USER-2-1',
|
key: 'USER-2-1',
|
||||||
name: 'PPK User 1 KSC 2',
|
name: 'PPK User 1 KSC 2',
|
||||||
domain: 'DOMAIN_A',
|
domain: 'DOMAIN_A',
|
||||||
type: ICONTYPES.PERSONAL,
|
type: WorkbasketType.PERSONAL,
|
||||||
description: 'PPK User 1 KSC 2',
|
description: 'PPK User 1 KSC 2',
|
||||||
owner: '',
|
owner: '',
|
||||||
custom1: '',
|
custom1: '',
|
||||||
|
@ -212,7 +212,7 @@ export const workbasketReadStateMock = {
|
||||||
key: 'USER-1-2',
|
key: 'USER-1-2',
|
||||||
name: 'PPK User 2 KSC 1',
|
name: 'PPK User 2 KSC 1',
|
||||||
domain: 'DOMAIN_A',
|
domain: 'DOMAIN_A',
|
||||||
type: ICONTYPES.PERSONAL,
|
type: WorkbasketType.PERSONAL,
|
||||||
description: 'PPK User 2 KSC 1',
|
description: 'PPK User 2 KSC 1',
|
||||||
owner: 'Peter Maier',
|
owner: 'Peter Maier',
|
||||||
custom1: 'custom1',
|
custom1: 'custom1',
|
||||||
|
@ -230,7 +230,7 @@ export const workbasketReadStateMock = {
|
||||||
key: 'USER-2-2',
|
key: 'USER-2-2',
|
||||||
name: 'PPK User 2 KSC 2',
|
name: 'PPK User 2 KSC 2',
|
||||||
domain: 'DOMAIN_A',
|
domain: 'DOMAIN_A',
|
||||||
type: ICONTYPES.PERSONAL,
|
type: WorkbasketType.PERSONAL,
|
||||||
description: 'PPK User 2 KSC 2',
|
description: 'PPK User 2 KSC 2',
|
||||||
owner: '',
|
owner: '',
|
||||||
custom1: '',
|
custom1: '',
|
||||||
|
@ -248,7 +248,7 @@ export const workbasketReadStateMock = {
|
||||||
key: 'TPK_VIP',
|
key: 'TPK_VIP',
|
||||||
name: 'Themenpostkorb VIP',
|
name: 'Themenpostkorb VIP',
|
||||||
domain: 'DOMAIN_A',
|
domain: 'DOMAIN_A',
|
||||||
type: ICONTYPES.TOPIC,
|
type: WorkbasketType.TOPIC,
|
||||||
description: 'Themenpostkorb VIP',
|
description: 'Themenpostkorb VIP',
|
||||||
owner: '',
|
owner: '',
|
||||||
custom1: '',
|
custom1: '',
|
||||||
|
@ -266,7 +266,7 @@ export const workbasketReadStateMock = {
|
||||||
key: 'TPK_VIP_2',
|
key: 'TPK_VIP_2',
|
||||||
name: 'Themenpostkorb VIP 2',
|
name: 'Themenpostkorb VIP 2',
|
||||||
domain: 'DOMAIN_A',
|
domain: 'DOMAIN_A',
|
||||||
type: ICONTYPES.TOPIC,
|
type: WorkbasketType.TOPIC,
|
||||||
description: 'Themenpostkorb VIP',
|
description: 'Themenpostkorb VIP',
|
||||||
owner: '',
|
owner: '',
|
||||||
custom1: '',
|
custom1: '',
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Workbasket } from '../../models/workbasket';
|
import { Workbasket } from '../../models/workbasket';
|
||||||
import { TaskanaQueryParameters } from '../../util/query-parameters';
|
import { Sorting, WorkbasketQuerySortParameter } from '../../models/sorting';
|
||||||
import { Direction } from '../../models/sorting';
|
|
||||||
import { ACTION } from '../../models/action';
|
import { ACTION } from '../../models/action';
|
||||||
import { WorkbasketAccessItems } from '../../models/workbasket-access-items';
|
import { WorkbasketAccessItems } from '../../models/workbasket-access-items';
|
||||||
import { WorkbasketComponent } from '../../../administration/models/workbasket-component';
|
import { WorkbasketComponent } from '../../../administration/models/workbasket-component';
|
||||||
import { ButtonAction } from '../../../administration/models/button-action';
|
import { ButtonAction } from '../../../administration/models/button-action';
|
||||||
|
import { QueryPagingParameter } from '../../models/query-paging-parameter';
|
||||||
|
import { WorkbasketQueryFilterParameter } from '../../models/workbasket-query-parameters';
|
||||||
|
|
||||||
// Workbasket List
|
// Workbasket List
|
||||||
export class GetWorkbasketsSummary {
|
export class GetWorkbasketsSummary {
|
||||||
|
@ -12,18 +13,9 @@ export class GetWorkbasketsSummary {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public forceRequest: boolean = false,
|
public forceRequest: boolean = false,
|
||||||
public sortBy: string = TaskanaQueryParameters.parameters.KEY,
|
public filterParameter: WorkbasketQueryFilterParameter,
|
||||||
public order: string = Direction.ASC,
|
public sortParameter: Sorting<WorkbasketQuerySortParameter>,
|
||||||
public name?: string,
|
public pageParameter: QueryPagingParameter
|
||||||
public nameLike?: string,
|
|
||||||
public descLike?: string,
|
|
||||||
public owner?: string,
|
|
||||||
public ownerLike?: string,
|
|
||||||
public type?: string,
|
|
||||||
public key?: string,
|
|
||||||
public keyLike?: string,
|
|
||||||
public requiredPermission?: string,
|
|
||||||
public allPages: boolean = false
|
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,21 +81,7 @@ export class WorkbasketState implements NgxsAfterBootstrap {
|
||||||
paginatedWorkbasketsSummary: undefined
|
paginatedWorkbasketsSummary: undefined
|
||||||
});
|
});
|
||||||
return this.workbasketService
|
return this.workbasketService
|
||||||
.getWorkBasketsSummary(
|
.getWorkBasketsSummary(action.forceRequest, action.filterParameter, action.sortParameter, action.pageParameter)
|
||||||
action.forceRequest,
|
|
||||||
action.sortBy,
|
|
||||||
action.order,
|
|
||||||
action.name,
|
|
||||||
action.nameLike,
|
|
||||||
action.descLike,
|
|
||||||
action.owner,
|
|
||||||
action.ownerLike,
|
|
||||||
action.type,
|
|
||||||
action.key,
|
|
||||||
action.keyLike,
|
|
||||||
action.requiredPermission,
|
|
||||||
action.allPages
|
|
||||||
)
|
|
||||||
.pipe(
|
.pipe(
|
||||||
take(1),
|
take(1),
|
||||||
tap((paginatedWorkbasketsSummary) => {
|
tap((paginatedWorkbasketsSummary) => {
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { asUrlQueryString } from './query-parameters-v2';
|
||||||
|
|
||||||
|
describe('asUrlQueryString', () => {
|
||||||
|
it('should create a empty query', () => {
|
||||||
|
expect(asUrlQueryString({})).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a query string with one argument', () => {
|
||||||
|
expect(asUrlQueryString({ foo: 'bar' })).toBe('?foo=bar');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a query string with multiple argument', () => {
|
||||||
|
expect(asUrlQueryString({ foo1: 'bar1', foo2: 'bar2' })).toBe('?foo1=bar1&foo2=bar2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should expand any array argument', () => {
|
||||||
|
expect(asUrlQueryString({ foo: ['bar1', 'bar2'] })).toBe('?foo=bar1&foo=bar2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should skip undefined values', () => {
|
||||||
|
expect(asUrlQueryString({ foo: 'bar', foo1: undefined })).toBe('?foo=bar');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should skip undefined values in array', () => {
|
||||||
|
expect(asUrlQueryString({ foo: ['bar1', undefined, 'bar2'] })).toBe('?foo=bar1&foo=bar2');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,11 @@
|
||||||
|
export function asUrlQueryString(params: Object): string {
|
||||||
|
let query = '';
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(params)) {
|
||||||
|
if (value) {
|
||||||
|
let values: any[] = value instanceof Array ? value : [value];
|
||||||
|
values.filter((v) => v !== undefined).forEach((v) => (query += (query ? '&' : '?') + `${key}=${v}`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
|
@ -1,36 +0,0 @@
|
||||||
import { Direction } from 'app/shared/models/sorting';
|
|
||||||
import { QueryParameters } from 'app/shared/models/query-parameters';
|
|
||||||
import { TaskanaQueryParameters } from './query-parameters';
|
|
||||||
|
|
||||||
describe('TaskanaQueryParameters', () => {
|
|
||||||
beforeAll(() => {
|
|
||||||
TaskanaQueryParameters.page = 1;
|
|
||||||
TaskanaQueryParameters.pageSize = 9;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a empty query', () => {
|
|
||||||
delete TaskanaQueryParameters.page;
|
|
||||||
delete TaskanaQueryParameters.pageSize;
|
|
||||||
expect(TaskanaQueryParameters.getQueryParameters(new QueryParameters())).toBe('?');
|
|
||||||
TaskanaQueryParameters.page = 1;
|
|
||||||
TaskanaQueryParameters.pageSize = 9;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a query with pagin information', () => {
|
|
||||||
expect(TaskanaQueryParameters.getQueryParameters(new QueryParameters())).toBe('?page=1&page-size=9');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a query separated with &', () => {
|
|
||||||
const parameters = new QueryParameters();
|
|
||||||
parameters.SORTBY = TaskanaQueryParameters.parameters.KEY;
|
|
||||||
parameters.SORTDIRECTION = Direction.ASC;
|
|
||||||
expect(TaskanaQueryParameters.getQueryParameters(parameters).split('&').length).toBe(4);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove last & from query', () => {
|
|
||||||
const parameters = new QueryParameters();
|
|
||||||
parameters.SORTBY = TaskanaQueryParameters.parameters.KEY;
|
|
||||||
parameters.SORTDIRECTION = Direction.ASC;
|
|
||||||
expect(TaskanaQueryParameters.getQueryParameters(parameters).endsWith('?')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { QueryParameters } from 'app/shared/models/query-parameters';
|
|
||||||
|
|
||||||
export class TaskanaQueryParameters {
|
export class TaskanaQueryParameters {
|
||||||
static parameters = {
|
static parameters = {
|
||||||
// Sorting
|
// Sorting
|
||||||
|
@ -56,26 +54,4 @@ export class TaskanaQueryParameters {
|
||||||
|
|
||||||
static page = 1;
|
static page = 1;
|
||||||
static pageSize = 9;
|
static pageSize = 9;
|
||||||
|
|
||||||
public static getQueryParameters(queryParametersModel: QueryParameters): string {
|
|
||||||
let query = '?';
|
|
||||||
|
|
||||||
Object.keys(queryParametersModel).forEach((key) => {
|
|
||||||
const value = queryParametersModel[key];
|
|
||||||
query += value ? `${TaskanaQueryParameters.parameters[key]}=${value}&` : '';
|
|
||||||
});
|
|
||||||
|
|
||||||
query += this.page ? `${TaskanaQueryParameters.parameters.PAGE}=${this.page}&` : '';
|
|
||||||
query += this.pageSize ? `${TaskanaQueryParameters.parameters.PAGESIZE}=${this.pageSize}&` : '';
|
|
||||||
|
|
||||||
query = TaskanaQueryParameters.removeLastChar(query);
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static removeLastChar(query: string): string {
|
|
||||||
if (query.lastIndexOf('&') === query.length - 1) {
|
|
||||||
return query.slice(0, query.lastIndexOf('&'));
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
placeholder="Search by value ..." />
|
placeholder="Search by value ..." />
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="searched" class="pull-right margin-right btn-group">
|
<div *ngIf="searched" class="pull-right margin-right btn-group">
|
||||||
<taskana-shared-sort [sortingFields]="sortingFields" (performSorting)="sorting($event)" class="btn-group" [defaultSortBy] = "taskDefaultSortBy"> </taskana-shared-sort>
|
<taskana-shared-sort class="btn-group" [sortingFields]="sortingFields" [defaultSortBy]="taskDefaultSortBy"
|
||||||
|
(performSorting)="sorting($event)"> </taskana-shared-sort>
|
||||||
<button class="btn btn-default collapsed" type="button" id="collapsedMenufilterWb" aria-expanded="false" (click)="toolbarState=!toolbarState">
|
<button class="btn btn-default collapsed" type="button" id="collapsedMenufilterWb" aria-expanded="false" (click)="toolbarState=!toolbarState">
|
||||||
<span class="material-icons md-20 blue">search</span>
|
<span class="material-icons md-20 blue">search</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -61,7 +62,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div [@toggleDown]="toolbarState" class="row no-overflow">
|
<div [@toggleDown]="toolbarState" class="row no-overflow">
|
||||||
<taskana-shared-filter [filterParams]="filterParams" [filterType]="filterType" (performFilter)="filtering($event)">
|
<taskana-shared-task-filter (performFilter)="filtering($event)"></taskana-shared-task-filter>
|
||||||
</taskana-shared-filter>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -3,13 +3,12 @@ import { Task } from 'app/workplace/models/task';
|
||||||
import { Workbasket } from 'app/shared/models/workbasket';
|
import { Workbasket } from 'app/shared/models/workbasket';
|
||||||
import { TaskService } from 'app/workplace/services/task.service';
|
import { TaskService } from 'app/workplace/services/task.service';
|
||||||
import { WorkbasketService } from 'app/shared/services/workbasket/workbasket.service';
|
import { WorkbasketService } from 'app/shared/services/workbasket/workbasket.service';
|
||||||
import { Sorting } from 'app/shared/models/sorting';
|
import { Sorting, TASK_SORT_PARAMETER_NAMING, TaskQuerySortParameter } from 'app/shared/models/sorting';
|
||||||
import { Filter } from 'app/shared/models/filter';
|
|
||||||
import { TaskanaType } from 'app/shared/models/taskana-type';
|
|
||||||
import { expandDown } from 'app/shared/animations/expand.animation';
|
import { expandDown } from 'app/shared/animations/expand.animation';
|
||||||
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
|
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
|
||||||
import { WorkplaceService } from 'app/workplace/services/workplace.service';
|
import { WorkplaceService } from 'app/workplace/services/workplace.service';
|
||||||
import { ObjectReference } from 'app/workplace/models/object-reference';
|
import { ObjectReference } from 'app/workplace/models/object-reference';
|
||||||
|
import { TaskQueryFilterParameter } from '../../../shared/models/task-query-filter-parameter';
|
||||||
|
|
||||||
export enum Search {
|
export enum Search {
|
||||||
byWorkbasket = 'workbasket',
|
byWorkbasket = 'workbasket',
|
||||||
|
@ -23,20 +22,14 @@ export enum Search {
|
||||||
styleUrls: ['./task-list-toolbar.component.scss']
|
styleUrls: ['./task-list-toolbar.component.scss']
|
||||||
})
|
})
|
||||||
export class TaskListToolbarComponent implements OnInit {
|
export class TaskListToolbarComponent implements OnInit {
|
||||||
@Input() taskDefaultSortBy: string;
|
@Input() taskDefaultSortBy: TaskQuerySortParameter;
|
||||||
@Output() performSorting = new EventEmitter<Sorting>();
|
@Output() performSorting = new EventEmitter<Sorting<TaskQuerySortParameter>>();
|
||||||
@Output() performFilter = new EventEmitter<Filter>();
|
@Output() performFilter = new EventEmitter<TaskQueryFilterParameter>();
|
||||||
@Output() selectSearchType = new EventEmitter();
|
@Output() selectSearchType = new EventEmitter();
|
||||||
|
|
||||||
sortingFields = new Map([
|
sortingFields: Map<TaskQuerySortParameter, string> = TASK_SORT_PARAMETER_NAMING;
|
||||||
['name', 'Name'],
|
|
||||||
['priority', 'Priority'],
|
|
||||||
['due', 'Due'],
|
|
||||||
['planned', 'Planned']
|
|
||||||
]);
|
|
||||||
filterParams = { name: '', key: '', owner: '', priority: '', state: '' };
|
|
||||||
tasks: Task[] = [];
|
|
||||||
|
|
||||||
|
tasks: Task[] = [];
|
||||||
workbasketNames: string[] = [];
|
workbasketNames: string[] = [];
|
||||||
resultName = '';
|
resultName = '';
|
||||||
resultId = '';
|
resultId = '';
|
||||||
|
@ -44,7 +37,6 @@ export class TaskListToolbarComponent implements OnInit {
|
||||||
currentBasket: Workbasket;
|
currentBasket: Workbasket;
|
||||||
workbasketSelected = false;
|
workbasketSelected = false;
|
||||||
toolbarState = false;
|
toolbarState = false;
|
||||||
filterType = TaskanaType.TASKS;
|
|
||||||
searched = false;
|
searched = false;
|
||||||
|
|
||||||
search = Search;
|
search = Search;
|
||||||
|
@ -116,11 +108,11 @@ export class TaskListToolbarComponent implements OnInit {
|
||||||
this.router.navigate(['']);
|
this.router.navigate(['']);
|
||||||
}
|
}
|
||||||
|
|
||||||
sorting(sort: Sorting) {
|
sorting(sort: Sorting<TaskQuerySortParameter>) {
|
||||||
this.performSorting.emit(sort);
|
this.performSorting.emit(sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
filtering(filterBy: Filter) {
|
filtering(filterBy: TaskQueryFilterParameter) {
|
||||||
this.performFilter.emit(filterBy);
|
this.performFilter.emit(filterBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,9 @@ import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/co
|
||||||
import { Task } from 'app/workplace/models/task';
|
import { Task } from 'app/workplace/models/task';
|
||||||
import { TaskService } from 'app/workplace/services/task.service';
|
import { TaskService } from 'app/workplace/services/task.service';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { Sorting } from 'app/shared/models/sorting';
|
import { Direction, Sorting, TaskQuerySortParameter } from 'app/shared/models/sorting';
|
||||||
import { Workbasket } from 'app/shared/models/workbasket';
|
import { Workbasket } from 'app/shared/models/workbasket';
|
||||||
import { Filter } from 'app/shared/models/filter';
|
|
||||||
import { WorkplaceService } from 'app/workplace/services/workplace.service';
|
import { WorkplaceService } from 'app/workplace/services/workplace.service';
|
||||||
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
|
||||||
import { OrientationService } from 'app/shared/services/orientation/orientation.service';
|
import { OrientationService } from 'app/shared/services/orientation/orientation.service';
|
||||||
import { Page } from 'app/shared/models/page';
|
import { Page } from 'app/shared/models/page';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
@ -14,6 +12,8 @@ import { ObjectReference } from '../../models/object-reference';
|
||||||
import { Search } from '../task-list-toolbar/task-list-toolbar.component';
|
import { Search } from '../task-list-toolbar/task-list-toolbar.component';
|
||||||
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
||||||
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
|
||||||
|
import { QueryPagingParameter } from '../../../shared/models/query-paging-parameter';
|
||||||
|
import { TaskQueryFilterParameter } from '../../../shared/models/task-query-filter-parameter';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-task-master',
|
selector: 'taskana-task-master',
|
||||||
|
@ -26,17 +26,16 @@ export class TaskMasterComponent implements OnInit, OnDestroy {
|
||||||
type = 'tasks';
|
type = 'tasks';
|
||||||
currentBasket: Workbasket;
|
currentBasket: Workbasket;
|
||||||
selectedId = '';
|
selectedId = '';
|
||||||
taskDefaultSortBy: string = 'priority';
|
taskDefaultSortBy: TaskQuerySortParameter = TaskQuerySortParameter.PRIORITY;
|
||||||
sort: Sorting = new Sorting(this.taskDefaultSortBy);
|
sort: Sorting<TaskQuerySortParameter> = {
|
||||||
filterBy: Filter = new Filter({
|
'sort-by': this.taskDefaultSortBy,
|
||||||
name: '',
|
order: Direction.ASC
|
||||||
owner: '',
|
};
|
||||||
priority: '',
|
paging: QueryPagingParameter = {
|
||||||
state: '',
|
page: 1,
|
||||||
classificationKey: '',
|
'page-size': 9
|
||||||
workbasketId: '',
|
};
|
||||||
workbasketKey: ''
|
filterBy: TaskQueryFilterParameter = undefined;
|
||||||
});
|
|
||||||
|
|
||||||
requestInProgress = false;
|
requestInProgress = false;
|
||||||
selectedSearchType: Search = Search.byWorkbasket;
|
selectedSearchType: Search = Search.byWorkbasket;
|
||||||
|
@ -79,27 +78,33 @@ export class TaskMasterComponent implements OnInit, OnDestroy {
|
||||||
this.refreshWorkbasketList();
|
this.refreshWorkbasketList();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.workplaceService.workbasketSelectedStream.pipe(takeUntil(this.destroy$)).subscribe((workbasket) => {
|
this.workplaceService
|
||||||
this.currentBasket = workbasket;
|
.getSelectedWorkbasket()
|
||||||
if (this.selectedSearchType === Search.byWorkbasket) {
|
.pipe(takeUntil(this.destroy$))
|
||||||
this.getTasks();
|
.subscribe((workbasket) => {
|
||||||
}
|
this.currentBasket = workbasket;
|
||||||
});
|
if (this.selectedSearchType === Search.byWorkbasket) {
|
||||||
|
this.getTasks();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.workplaceService.objectReferenceSelectedStream.pipe(takeUntil(this.destroy$)).subscribe((objectReference) => {
|
this.workplaceService
|
||||||
if (objectReference) {
|
.getSelectedObjectReference()
|
||||||
delete this.currentBasket;
|
.pipe(takeUntil(this.destroy$))
|
||||||
this.getTasks(objectReference);
|
.subscribe((objectReference) => {
|
||||||
}
|
if (objectReference) {
|
||||||
});
|
delete this.currentBasket;
|
||||||
|
this.getTasks(objectReference);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
performSorting(sort: Sorting) {
|
performSorting(sort: Sorting<TaskQuerySortParameter>) {
|
||||||
this.sort = sort;
|
this.sort = sort;
|
||||||
this.getTasks();
|
this.getTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
performFilter(filterBy: Filter) {
|
performFilter(filterBy: TaskQueryFilterParameter) {
|
||||||
this.filterBy = filterBy;
|
this.filterBy = filterBy;
|
||||||
this.getTasks();
|
this.getTasks();
|
||||||
}
|
}
|
||||||
|
@ -110,7 +115,7 @@ export class TaskMasterComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
changePage(page) {
|
changePage(page) {
|
||||||
TaskanaQueryParameters.page = page;
|
this.paging.page = page;
|
||||||
this.getTasks();
|
this.getTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,8 +131,7 @@ export class TaskMasterComponent implements OnInit, OnDestroy {
|
||||||
const unusedHeight = 150;
|
const unusedHeight = 150;
|
||||||
const totalHeight = window.innerHeight;
|
const totalHeight = window.innerHeight;
|
||||||
const cards = Math.round((totalHeight - (unusedHeight + toolbarSize)) / cardHeight);
|
const cards = Math.round((totalHeight - (unusedHeight + toolbarSize)) / cardHeight);
|
||||||
TaskanaQueryParameters.page = TaskanaQueryParameters.page ? TaskanaQueryParameters.page : 1;
|
this.paging['page-size'] = cards > 0 ? cards : 1;
|
||||||
TaskanaQueryParameters.pageSize = cards > 0 ? cards : 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,17 +143,7 @@ export class TaskMasterComponent implements OnInit, OnDestroy {
|
||||||
} else {
|
} else {
|
||||||
this.calculateHeightCard();
|
this.calculateHeightCard();
|
||||||
this.taskService
|
this.taskService
|
||||||
.findTasksWithWorkbasket(
|
.findTasksWithWorkbasket(this.filterBy, this.sort, this.paging)
|
||||||
this.currentBasket ? this.currentBasket.workbasketId : '',
|
|
||||||
this.sort.sortBy,
|
|
||||||
this.sort.sortDirection,
|
|
||||||
this.filterBy.filterParams.name,
|
|
||||||
this.filterBy.filterParams.owner,
|
|
||||||
this.filterBy.filterParams.priority,
|
|
||||||
this.filterBy.filterParams.state,
|
|
||||||
objectReference ? objectReference.type : '',
|
|
||||||
objectReference ? objectReference.value : ''
|
|
||||||
)
|
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe((taskResource) => {
|
.subscribe((taskResource) => {
|
||||||
this.requestInProgress = false;
|
this.requestInProgress = false;
|
||||||
|
|
|
@ -102,14 +102,15 @@ export class TaskdetailsGeneralFieldsComponent implements OnInit, OnChanges, OnD
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this is currently called for every selected task and is only necessary when we switch the workbasket -> can be optimized.
|
||||||
private getClassificationByDomain() {
|
private getClassificationByDomain() {
|
||||||
this.requestInProgress = true;
|
this.requestInProgress = true;
|
||||||
this.classificationService
|
this.classificationService
|
||||||
.getClassificationsByDomain(this.domainService.getSelectedDomainValue())
|
.getClassifications({ domain: [this.task.workbasketSummary.domain] })
|
||||||
.then((classificationPagingList) => {
|
.subscribe((classificationPagingList) => {
|
||||||
this.classifications = classificationPagingList.classifications;
|
this.classifications = classificationPagingList.classifications;
|
||||||
|
this.requestInProgress = false;
|
||||||
});
|
});
|
||||||
this.requestInProgress = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
|
|
@ -45,7 +45,6 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.currentWorkbasket = this.workplaceService.currentWorkbasket;
|
|
||||||
this.workbasketSubscription = this.workplaceService.getSelectedWorkbasket().subscribe((workbasket) => {
|
this.workbasketSubscription = this.workplaceService.getSelectedWorkbasket().subscribe((workbasket) => {
|
||||||
this.currentWorkbasket = workbasket;
|
this.currentWorkbasket = workbasket;
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,10 +3,11 @@ import { Observable, Subject } from 'rxjs';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { TaskResource } from 'app/workplace/models/task-resource';
|
import { TaskResource } from 'app/workplace/models/task-resource';
|
||||||
import { Direction } from 'app/shared/models/sorting';
|
import { Sorting, TaskQuerySortParameter } from 'app/shared/models/sorting';
|
||||||
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
|
|
||||||
import { QueryParameters } from 'app/shared/models/query-parameters';
|
|
||||||
import { StartupService } from '../../shared/services/startup/startup.service';
|
import { StartupService } from '../../shared/services/startup/startup.service';
|
||||||
|
import { asUrlQueryString } from '../../shared/util/query-parameters-v2';
|
||||||
|
import { TaskQueryFilterParameter } from '../../shared/models/task-query-filter-parameter';
|
||||||
|
import { QueryPagingParameter } from '../../shared/models/query-paging-parameter';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TaskService {
|
export class TaskService {
|
||||||
|
@ -40,31 +41,11 @@ export class TaskService {
|
||||||
}
|
}
|
||||||
|
|
||||||
findTasksWithWorkbasket(
|
findTasksWithWorkbasket(
|
||||||
basketId: string,
|
filterParameter: TaskQueryFilterParameter,
|
||||||
sortBy: string,
|
sortParameter: Sorting<TaskQuerySortParameter>,
|
||||||
sortDirection: string,
|
pagingParameter: QueryPagingParameter
|
||||||
nameLike: string,
|
|
||||||
ownerLike: string,
|
|
||||||
priority: string,
|
|
||||||
state: string,
|
|
||||||
objRefTypeLike: string,
|
|
||||||
objRefValueLike: string,
|
|
||||||
allPages: boolean = false
|
|
||||||
): Observable<TaskResource> {
|
): Observable<TaskResource> {
|
||||||
const url = `${this.url}${TaskanaQueryParameters.getQueryParameters(
|
const url = `${this.url}${asUrlQueryString({ ...filterParameter, ...sortParameter, ...pagingParameter })}`;
|
||||||
TaskService.accessIdsParameters(
|
|
||||||
basketId,
|
|
||||||
sortBy,
|
|
||||||
sortDirection,
|
|
||||||
nameLike,
|
|
||||||
ownerLike,
|
|
||||||
priority,
|
|
||||||
state,
|
|
||||||
objRefTypeLike,
|
|
||||||
objRefValueLike,
|
|
||||||
allPages
|
|
||||||
)
|
|
||||||
)}`;
|
|
||||||
return this.httpClient.get<TaskResource>(url);
|
return this.httpClient.get<TaskResource>(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,34 +91,4 @@ export class TaskService {
|
||||||
});
|
});
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static accessIdsParameters(
|
|
||||||
basketId: string,
|
|
||||||
sortBy = 'priority',
|
|
||||||
sortDirection: string = Direction.ASC,
|
|
||||||
nameLike: string,
|
|
||||||
ownerLike: string,
|
|
||||||
priority: string,
|
|
||||||
state: string,
|
|
||||||
objRefTypeLike: string,
|
|
||||||
objRefValueLike: string,
|
|
||||||
allPages: boolean = false
|
|
||||||
): QueryParameters {
|
|
||||||
const parameters = new QueryParameters();
|
|
||||||
parameters.WORKBASKET_ID = basketId;
|
|
||||||
parameters.SORTBY = sortBy;
|
|
||||||
parameters.SORTDIRECTION = sortDirection;
|
|
||||||
parameters.NAMELIKE = nameLike;
|
|
||||||
parameters.OWNERLIKE = ownerLike;
|
|
||||||
parameters.PRIORITY = priority;
|
|
||||||
parameters.STATE = state;
|
|
||||||
parameters.TASK_PRIMARY_OBJ_REF_TYPE_LIKE = objRefTypeLike;
|
|
||||||
parameters.TASK_PRIMARY_OBJ_REF_VALUE_LIKE = objRefValueLike;
|
|
||||||
if (allPages) {
|
|
||||||
delete TaskanaQueryParameters.page;
|
|
||||||
delete TaskanaQueryParameters.pageSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameters;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,26 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable, Subject } from 'rxjs';
|
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||||
import { Workbasket } from 'app/shared/models/workbasket';
|
import { Workbasket } from 'app/shared/models/workbasket';
|
||||||
import { ObjectReference } from '../models/object-reference';
|
import { ObjectReference } from '../models/object-reference';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkplaceService {
|
export class WorkplaceService {
|
||||||
// necessary because the TaskdetailsComponent is not always initialized when the first workbasket was selected.
|
private workbasketSelected = new BehaviorSubject<Workbasket>(undefined);
|
||||||
currentWorkbasket: Workbasket;
|
private objectReferenceSelected = new BehaviorSubject<ObjectReference>(undefined);
|
||||||
objectReference: ObjectReference;
|
|
||||||
private workbasketSelectedSource = new Subject<Workbasket>();
|
|
||||||
workbasketSelectedStream = this.workbasketSelectedSource.asObservable();
|
|
||||||
private objectReferenceSource = new Subject<ObjectReference>();
|
|
||||||
objectReferenceSelectedStream = this.objectReferenceSource.asObservable();
|
|
||||||
|
|
||||||
selectWorkbasket(workbasket?: Workbasket) {
|
selectWorkbasket(workbasket?: Workbasket): void {
|
||||||
this.currentWorkbasket = workbasket;
|
this.workbasketSelected.next(workbasket);
|
||||||
this.workbasketSelectedSource.next(workbasket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getSelectedWorkbasket(): Observable<Workbasket> {
|
getSelectedWorkbasket(): Observable<Workbasket> {
|
||||||
return this.workbasketSelectedStream;
|
return this.workbasketSelected.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectObjectReference(objectReference?: ObjectReference) {
|
selectObjectReference(objectReference?: ObjectReference): void {
|
||||||
this.objectReference = new ObjectReference();
|
this.objectReferenceSelected.next(objectReference);
|
||||||
if (objectReference) {
|
|
||||||
this.objectReference.type = objectReference.type;
|
|
||||||
this.objectReference.value = objectReference.value;
|
|
||||||
}
|
|
||||||
this.objectReferenceSource.next(objectReference);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getObjectReference() {
|
getSelectedObjectReference(): Observable<ObjectReference> {
|
||||||
return this.objectReferenceSelectedStream;
|
return this.objectReferenceSelected.asObservable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue