TSK-1279: Enable the creation of subclassifications
This commit is contained in:
parent
e352016584
commit
2760b9ee59
|
@ -23,7 +23,7 @@ taskana.schemaName=TASKANA
|
|||
########spring.jpa.generate-ddl=true
|
||||
########spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
|
||||
####### property that control rest api security deploy use true for no security.
|
||||
devMode=true
|
||||
devMode=false
|
||||
|
||||
####### property that control if the database is cleaned and sample data is generated
|
||||
generateSampleData=true
|
||||
|
|
|
@ -2,12 +2,10 @@ import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
|||
import { Select, Store } from '@ngxs/store';
|
||||
import { Observable, Subject, zip } from 'rxjs';
|
||||
|
||||
import { ClassificationDefinition,
|
||||
customFieldCount } from 'app/shared/models/classification-definition';
|
||||
import { ClassificationDefinition, customFieldCount } from 'app/shared/models/classification-definition';
|
||||
import { ACTION } from 'app/shared/models/action';
|
||||
|
||||
import { highlight } from 'theme/animations/validation.animation';
|
||||
import { TaskanaDate } from 'app/shared/util/taskana.date';
|
||||
|
||||
import { ClassificationsService } from 'app/shared/services/classifications/classifications.service';
|
||||
import { RequestInProgressService } from 'app/shared/services/request-in-progress/request-in-progress.service';
|
||||
|
@ -80,7 +78,9 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
|
|||
this.action$.pipe(takeUntil(this.destroy$)).subscribe(data => {
|
||||
this.action = data;
|
||||
if (this.action === ACTION.CREATE) {
|
||||
this.initClassificationOnCreation();
|
||||
this.selectedClassification$.pipe(take(1)).subscribe(initialClassification => {
|
||||
this.classification = { ...initialClassification };
|
||||
});
|
||||
this.badgeMessage = 'Creating new classification';
|
||||
} else {
|
||||
this.badgeMessage = '';
|
||||
|
@ -207,23 +207,6 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
|
|||
this.classification = { ...classificationSelected };
|
||||
}
|
||||
|
||||
private addDateToClassification(classification: ClassificationDefinition) {
|
||||
const date = TaskanaDate.getDate();
|
||||
classification.created = date;
|
||||
classification.modified = date;
|
||||
}
|
||||
|
||||
private initClassificationOnCreation() {
|
||||
zip(this.categories$, this.selectedClassificationType$).pipe(take(1)).subscribe(([categories, selectedType]: [string[], string]) => {
|
||||
const tempClassification: ClassificationDefinition = new ClassificationDefinition();
|
||||
[tempClassification.category] = categories;
|
||||
tempClassification.domain = this.domainService.getSelectedDomainValue();
|
||||
tempClassification.type = selectedType;
|
||||
this.addDateToClassification(tempClassification);
|
||||
this.classification = tempClassification;
|
||||
});
|
||||
}
|
||||
|
||||
private removeClassificationConfirmation() {
|
||||
if (!this.classification || !this.classification.classificationId) {
|
||||
this.notificationsService.triggerError(NOTIFICATION_TYPES.SELECT_ERR);
|
||||
|
@ -236,6 +219,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
|
|||
new Map<string, string>([['classificationKey', this.classification.key]]));
|
||||
this.afterRequest();
|
||||
});
|
||||
this.location.go(this.location.path().replace(/(classifications).*/g, 'classifications'));
|
||||
}
|
||||
|
||||
getClassificationCustom(customNumber: number): string {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Actions, ofActionCompleted, ofActionDispatched, Select, Store } from '@ngxs/store';
|
||||
|
||||
import { ImportExportService } from 'app/administration/services/import-export.service';
|
||||
|
@ -14,8 +13,6 @@ import { ClassificationSelectors } from 'app/shared/store/classification-store/c
|
|||
import { Location } from '@angular/common';
|
||||
import { ClassificationCategoryImages } from '../../../shared/models/customisation';
|
||||
|
||||
import { NotificationService } from '../../../shared/services/notifications/notification.service';
|
||||
|
||||
import { GetClassifications, SetActiveAction } from '../../../shared/store/classification-store/classification.actions';
|
||||
import { ACTION } from '../../../shared/models/action';
|
||||
import { TreeNodeModel } from '../../../shared/models/tree-node';
|
||||
|
@ -46,9 +43,7 @@ export class ClassificationListComponent implements OnInit, OnDestroy {
|
|||
constructor(
|
||||
private classificationService: ClassificationsService,
|
||||
private location: Location,
|
||||
private route: ActivatedRoute,
|
||||
private importExportService: ImportExportService,
|
||||
private notificationsService: NotificationService,
|
||||
private store: Store,
|
||||
private ngxsActions$: Actions
|
||||
) {
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
import { AfterViewChecked,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
Input,
|
||||
OnDestroy,
|
||||
import { AfterViewChecked, Component, ElementRef, EventEmitter, HostListener, Input, OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild } from '@angular/core';
|
||||
|
@ -12,8 +6,8 @@ import { TreeNodeModel } from 'app/shared/models/tree-node';
|
|||
|
||||
import { ITreeOptions, KEYS, TREE_ACTIONS, TreeComponent } from 'angular-tree-component';
|
||||
import { Pair } from 'app/shared/models/pair';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { Observable, Subject, combineLatest } from 'rxjs';
|
||||
import { map, takeUntil, filter, tap } from 'rxjs/operators';
|
||||
import { Select, Store } from '@ngxs/store';
|
||||
import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors';
|
||||
|
||||
|
@ -45,6 +39,7 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
|||
@Select(ClassificationSelectors.selectedClassificationId) selectedClassificationId$: Observable<string>;
|
||||
@Select(ClassificationSelectors.activeAction) activeAction$: Observable<ACTION>;
|
||||
@Select(ClassificationSelectors.classifications) classifications$: Observable<TreeNodeModel[]>;
|
||||
@Select(ClassificationSelectors.selectedClassificationType) classificationTypeSelected$: Observable<string>;
|
||||
|
||||
options: ITreeOptions = {
|
||||
displayField: 'name',
|
||||
|
@ -92,19 +87,24 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
|||
this.action = action;
|
||||
});
|
||||
|
||||
this.selectedClassificationId$.pipe(takeUntil(this.destroy$)).subscribe(selectedClassificationId => {
|
||||
this.selectNodeId = typeof selectedClassificationId !== 'undefined' ? selectedClassificationId : undefined;
|
||||
if (typeof this.tree.treeModel.getActiveNode() !== 'undefined') {
|
||||
if (this.tree.treeModel.getActiveNode().data.classificationId !== this.selectNodeId) {
|
||||
this.selectNode(this.selectNodeId);
|
||||
}
|
||||
}
|
||||
});
|
||||
const classificationCopy$: Observable<TreeNodeModel[]> = this.classifications$.pipe(
|
||||
filter(classifications => typeof (classifications) !== 'undefined'),
|
||||
map(classifications => classifications.map(this.classificationsDeepCopy.bind(this)))
|
||||
);
|
||||
|
||||
this.classifications$.pipe(takeUntil(this.destroy$)).subscribe(classifications => {
|
||||
if (typeof (classifications) !== 'undefined') {
|
||||
this.classifications = classifications.map(this.classificationsDeepCopy.bind(this));
|
||||
}
|
||||
combineLatest(this.selectedClassificationId$, classificationCopy$).pipe(takeUntil(this.destroy$))
|
||||
.subscribe(([selectedClassificationId, classifications]) => {
|
||||
this.classifications = classifications;
|
||||
this.selectNodeId = typeof selectedClassificationId !== 'undefined' ? selectedClassificationId : undefined;
|
||||
if (typeof this.tree.treeModel.getActiveNode() !== 'undefined') {
|
||||
if (this.tree.treeModel.getActiveNode().data.classificationId !== this.selectNodeId) {
|
||||
this.selectNode(this.selectNodeId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.classificationTypeSelected$.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
||||
if (this.tree.treeModel.getActiveNode()) { this.deselectActiveNode(); }
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,12 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked, OnDestroy
|
|||
this.selectNode(this.selectNodeId);
|
||||
}
|
||||
|
||||
if (typeof this.selectNodeId !== 'undefined') {
|
||||
if (typeof this.getNode(this.selectNodeId) !== 'undefined') {
|
||||
this.getNode(this.selectNodeId).ensureVisible();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.filterTextOld !== this.filterText
|
||||
|| this.filterIconOld !== this.filterIcon) {
|
||||
this.filterIconOld = this.filterIcon;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Action, NgxsAfterBootstrap, State, StateContext } from '@ngxs/store';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { take, tap } from 'rxjs/operators';
|
||||
import { TaskanaDate } from 'app/shared/util/taskana.date';
|
||||
import { CategoriesResponse,
|
||||
ClassificationCategoriesService } from '../../services/classification-categories/classification-categories.service';
|
||||
import { CreateClassification,
|
||||
|
@ -16,6 +17,7 @@ import { CreateClassification,
|
|||
import { ClassificationsService } from '../../services/classifications/classifications.service';
|
||||
import { ClassificationDefinition } from '../../models/classification-definition';
|
||||
import { ACTION } from '../../models/action';
|
||||
import { DomainService } from '../../services/domain/domain.service';
|
||||
|
||||
class InitializeStore {
|
||||
static readonly type = '[ClassificationState] Initializing state';
|
||||
|
@ -23,15 +25,21 @@ class InitializeStore {
|
|||
|
||||
@State<ClassificationStateModel>({ name: 'classification' })
|
||||
export class ClassificationState implements NgxsAfterBootstrap {
|
||||
constructor(private categoryService: ClassificationCategoriesService,
|
||||
private classificationsService: ClassificationsService) {
|
||||
constructor(
|
||||
private categoryService: ClassificationCategoriesService,
|
||||
private classificationsService: ClassificationsService,
|
||||
private domainService: DomainService
|
||||
) {
|
||||
}
|
||||
|
||||
@Action(SetSelectedClassificationType)
|
||||
setSelectedClassificationType(ctx: StateContext<ClassificationStateModel>, action: SetSelectedClassificationType): Observable<null> {
|
||||
const state: ClassificationStateModel = ctx.getState();
|
||||
if (state.classificationTypes[action.selectedType]) {
|
||||
ctx.patchState({ selectedClassificationType: action.selectedType });
|
||||
ctx.patchState({
|
||||
selectedClassificationType: action.selectedType,
|
||||
selectedClassification: undefined
|
||||
});
|
||||
}
|
||||
return of(null);
|
||||
}
|
||||
|
@ -141,7 +149,20 @@ export class ClassificationState implements NgxsAfterBootstrap {
|
|||
@Action(SetActiveAction)
|
||||
setActiveAction(ctx: StateContext<ClassificationStateModel>, action: SetActiveAction): Observable<null> {
|
||||
if (action.action === ACTION.CREATE) {
|
||||
ctx.patchState({ selectedClassification: new ClassificationDefinition(), action: action.action });
|
||||
// Initialization of a new classification
|
||||
const initialClassification: ClassificationDefinition = new ClassificationDefinition();
|
||||
const state: ClassificationStateModel = ctx.getState();
|
||||
initialClassification.type = state.selectedClassificationType;
|
||||
[initialClassification.category] = state.classificationTypes[initialClassification.type];
|
||||
const date = TaskanaDate.getDate();
|
||||
initialClassification.created = date;
|
||||
initialClassification.modified = date;
|
||||
initialClassification.domain = this.domainService.getSelectedDomainValue();
|
||||
if (state.selectedClassification) {
|
||||
initialClassification.parentId = state.selectedClassification.classificationId;
|
||||
initialClassification.parentKey = state.selectedClassification.key;
|
||||
}
|
||||
ctx.patchState({ selectedClassification: initialClassification, action: action.action });
|
||||
} else {
|
||||
ctx.patchState({ action: action.action });
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue