Merge pull request #3809 from tsiegleauq/MotionStates
Read the Workflow by state_id in Motion
This commit is contained in:
commit
95c6628732
@ -37,9 +37,7 @@ export class Motion extends BaseModel {
|
|||||||
agenda_item_id: number;
|
agenda_item_id: number;
|
||||||
log_messages: MotionLog[];
|
log_messages: MotionLog[];
|
||||||
|
|
||||||
// read from config
|
// dynamic values
|
||||||
workflow_id: number;
|
|
||||||
// by the config above
|
|
||||||
workflow: Workflow;
|
workflow: Workflow;
|
||||||
|
|
||||||
// for request
|
// for request
|
||||||
@ -100,31 +98,31 @@ export class Motion extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the workflow_id and the workflow
|
* sets the and the workflow from either dataStore or WebSocket
|
||||||
*/
|
*/
|
||||||
initDataStoreValues() {
|
initDataStoreValues() {
|
||||||
const motionsWorkflowConfig = this.DS.filter(Config, config => config.key === 'motions_workflow')[0] as Config;
|
// check the containing Workflows in DataStore
|
||||||
if (motionsWorkflowConfig) {
|
const allWorkflows = this.DS.get(Workflow) as Workflow[];
|
||||||
this.workflow_id = +motionsWorkflowConfig.value;
|
allWorkflows.forEach(localWorkflow => {
|
||||||
} else {
|
if (localWorkflow.isStateContained(this.state_id)) {
|
||||||
this.DS.getObservable().subscribe(newConfig => {
|
this.workflow = localWorkflow as Workflow;
|
||||||
if (newConfig instanceof Config && newConfig.key === 'motions_workflow') {
|
|
||||||
this.workflow_id = +newConfig.value;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
this.workflow = this.DS.get(Workflow, this.workflow_id) as Workflow;
|
// observe for new models
|
||||||
if (!this.workflow.id) {
|
|
||||||
this.DS.getObservable().subscribe(newModel => {
|
this.DS.getObservable().subscribe(newModel => {
|
||||||
if (newModel instanceof Workflow && newModel.id === this.workflow_id) {
|
if (newModel instanceof Workflow) {
|
||||||
this.workflow = newModel;
|
if (newModel.isStateContained(this.state_id)) {
|
||||||
|
this.workflow = newModel as Workflow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/** add a new motionSubmitter from user-object */
|
/**
|
||||||
|
* add a new motionSubmitter from user-object
|
||||||
|
* @param user the user
|
||||||
|
*/
|
||||||
addSubmitter(user: User) {
|
addSubmitter(user: User) {
|
||||||
const newSubmitter = new MotionSubmitter(null, user.id);
|
const newSubmitter = new MotionSubmitter(null, user.id);
|
||||||
this.submitters.push(newSubmitter);
|
this.submitters.push(newSubmitter);
|
||||||
@ -142,6 +140,11 @@ export class Motion extends BaseModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch the current version
|
||||||
|
*
|
||||||
|
* TODO: Altering the current version should be avoided.
|
||||||
|
*/
|
||||||
set currentTitle(newTitle: string) {
|
set currentTitle(newTitle: string) {
|
||||||
if (this.versions[0]) {
|
if (this.versions[0]) {
|
||||||
this.versions[0].title = newTitle;
|
this.versions[0].title = newTitle;
|
||||||
@ -221,9 +224,8 @@ export class Motion extends BaseModel {
|
|||||||
* return the workflow state
|
* return the workflow state
|
||||||
*/
|
*/
|
||||||
get state(): any {
|
get state(): any {
|
||||||
if (this.state_id && this.workflow && this.workflow.id) {
|
if (this.workflow) {
|
||||||
const state = this.workflow.state_by_id(this.state_id);
|
return this.workflow.state_by_id(this.state_id);
|
||||||
return state;
|
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -232,8 +234,12 @@ export class Motion extends BaseModel {
|
|||||||
/**
|
/**
|
||||||
* returns possible states for the motion
|
* returns possible states for the motion
|
||||||
*/
|
*/
|
||||||
get possible_states(): WorkflowState[] {
|
get nextStates(): WorkflowState[] {
|
||||||
return this.workflow.states;
|
if (this.workflow && this.state) {
|
||||||
|
return this.state.getNextStates(this.workflow);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { Deserializable } from '../deserializable.model';
|
import { Deserializable } from '../deserializable.model';
|
||||||
|
import { Workflow } from './workflow';
|
||||||
|
import { MotionLog } from './motion-log';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representation of a workflow state
|
* Representation of a workflow state
|
||||||
@ -79,6 +81,20 @@ export class WorkflowState implements Deserializable {
|
|||||||
this.workflow_id = workflow_id;
|
this.workflow_id = workflow_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a list of the next possible states.
|
||||||
|
* Also adds the current state.
|
||||||
|
*/
|
||||||
|
getNextStates(workflow: Workflow): WorkflowState[] {
|
||||||
|
const nextStates = [];
|
||||||
|
workflow.states.forEach(state => {
|
||||||
|
if (this.next_states_id.includes(state.id)) {
|
||||||
|
nextStates.push(state as WorkflowState);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return nextStates;
|
||||||
|
}
|
||||||
|
|
||||||
deserialize(input: any): this {
|
deserialize(input: any): this {
|
||||||
Object.assign(this, input);
|
Object.assign(this, input);
|
||||||
return this;
|
return this;
|
||||||
|
@ -21,6 +21,25 @@ export class Workflow extends BaseModel {
|
|||||||
this.first_state = first_state;
|
this.first_state = first_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the containing @link{WorkflowState}s contain a given ID
|
||||||
|
* @param id The State ID
|
||||||
|
*/
|
||||||
|
isStateContained(obj: number | WorkflowState): boolean {
|
||||||
|
let id: number;
|
||||||
|
if (obj instanceof WorkflowState) {
|
||||||
|
id = obj.id;
|
||||||
|
} else {
|
||||||
|
id = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.states.some(state => {
|
||||||
|
if (state.id === id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
state_by_id(id: number): WorkflowState {
|
state_by_id(id: number): WorkflowState {
|
||||||
let targetState;
|
let targetState;
|
||||||
this.states.forEach(state => {
|
this.states.forEach(state => {
|
||||||
|
@ -73,18 +73,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- State -->
|
<!-- State -->
|
||||||
<div *ngIf='motion && motion.state_id || editMotion'>
|
<div *ngIf='!newMotion && motion && motion.workflow && motion.state_id || editMotion'>
|
||||||
<div *ngIf='!editMotion'>
|
<div *ngIf='!editMotion'>
|
||||||
<h3 translate>State</h3>
|
<h3 translate>State</h3>
|
||||||
{{motion.state.name}}
|
{{motion.state}}
|
||||||
</div>
|
</div>
|
||||||
<mat-form-field *ngIf="editMotion">
|
<mat-form-field *ngIf="editMotion && !newMotion">
|
||||||
<mat-select placeholder='State' formControlName='state_id'>
|
<mat-select placeholder='State' formControlName='state_id'>
|
||||||
<mat-option *ngFor="let state of motion.possible_states" [value]="state.id">{{state}}</mat-option>
|
<mat-option [value]="motion.state.id">{{motion.state}}</mat-option>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
<mat-option *ngFor="let state of motion.nextStates" [value]="state.id">{{state}}</mat-option>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<mat-option>
|
<mat-option>
|
||||||
<fa-icon icon='exclamation-triangle'></fa-icon>
|
<fa-icon icon='exclamation-triangle'></fa-icon> <span translate>Reset State</span>
|
||||||
<span translate>Reset State</span>
|
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@ -99,7 +100,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<mat-form-field *ngIf="motion && editMotion">
|
<mat-form-field *ngIf="motion && editMotion">
|
||||||
<mat-select placeholder='Recommendation' formControlName='recommendation_id'>
|
<mat-select placeholder='Recommendation' formControlName='recommendation_id'>
|
||||||
<mat-option *ngFor="let state of motion.possible_states" [value]="state.id">{{state}}</mat-option>
|
<mat-option *ngFor="let state of motion.nextStates" [value]="state.id">{{state}}</mat-option>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<mat-option>
|
<mat-option>
|
||||||
<fa-icon icon='exclamation-triangle'></fa-icon>
|
<fa-icon icon='exclamation-triangle'></fa-icon>
|
||||||
|
@ -133,6 +133,8 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
|
|||||||
* http:post the motion to the server.
|
* http:post the motion to the server.
|
||||||
* The AutoUpdate-Service should see a change once it arrives and show it
|
* The AutoUpdate-Service should see a change once it arrives and show it
|
||||||
* in the list view automatically
|
* in the list view automatically
|
||||||
|
*
|
||||||
|
* TODO: state is not yet saved. Need a special "put" command
|
||||||
*/
|
*/
|
||||||
saveMotion() {
|
saveMotion() {
|
||||||
const newMotionValues = { ...this.metaInfoForm.value, ...this.contentForm.value };
|
const newMotionValues = { ...this.metaInfoForm.value, ...this.contentForm.value };
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
<ng-container matColumnDef="state">
|
<ng-container matColumnDef="state">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header> State </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header> State </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let motion">
|
<mat-cell *matCellDef="let motion">
|
||||||
<div *ngIf='motion.state && motion.state.name !== "submitted"' class='innerTable'>
|
<div *ngIf='isDisplayIcon(motion.state) && motion.state' class='innerTable'>
|
||||||
<fa-icon icon={{getStateIcon(motion.state)}}></fa-icon>
|
<fa-icon icon={{getStateIcon(motion.state)}}></fa-icon>
|
||||||
</div>
|
</div>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
|
@ -121,6 +121,10 @@ export class MotionListComponent extends BaseComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isDisplayIcon(state): boolean {
|
||||||
|
return state.name === 'accepted' || state.name === 'rejected' || state.name === 'not decided';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download all motions As PDF and DocX
|
* Download all motions As PDF and DocX
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user