Allow motions to go a state back
This commit is contained in:
parent
392cb7fdaf
commit
3ba8636acf
@ -45,13 +45,15 @@ export class WorkflowState extends Deserializer {
|
|||||||
* Also adds the current state.
|
* Also adds the current state.
|
||||||
*/
|
*/
|
||||||
public getNextStates(workflow: Workflow): WorkflowState[] {
|
public getNextStates(workflow: Workflow): WorkflowState[] {
|
||||||
const nextStates = [];
|
return workflow.states.filter(state => {
|
||||||
workflow.states.forEach(state => {
|
return this.next_states_id.includes(state.id);
|
||||||
if (this.next_states_id.includes(state.id)) {
|
});
|
||||||
nextStates.push(state as WorkflowState);
|
}
|
||||||
}
|
|
||||||
|
public getPreviousStates(workflow: Workflow): WorkflowState[] {
|
||||||
|
return workflow.states.filter(state => {
|
||||||
|
return state.next_states_id.includes(this.id);
|
||||||
});
|
});
|
||||||
return nextStates;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public toString = (): string => {
|
public toString = (): string => {
|
||||||
|
@ -223,6 +223,9 @@
|
|||||||
</button>
|
</button>
|
||||||
<div *ngIf="perms.isAllowed('change_metadata', motion)">
|
<div *ngIf="perms.isAllowed('change_metadata', motion)">
|
||||||
<mat-divider *ngIf="motion.nextStates.length > 0"></mat-divider>
|
<mat-divider *ngIf="motion.nextStates.length > 0"></mat-divider>
|
||||||
|
<button *ngFor="let state of motion.previousStates" mat-menu-item (click)="setState(state.id)">
|
||||||
|
<mat-icon>arrow_back</mat-icon> {{ state.name | translate }} <span *ngIf="state.show_state_extension_field"> ...</span>
|
||||||
|
</button>
|
||||||
<button mat-menu-item (click)="setState(null)">
|
<button mat-menu-item (click)="setState(null)">
|
||||||
<mat-icon>replay</mat-icon> {{ 'Reset state' | translate }}
|
<mat-icon>replay</mat-icon> {{ 'Reset state' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
@ -1035,7 +1035,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
* @param id Motion state id
|
* @param id Motion state id
|
||||||
*/
|
*/
|
||||||
public setState(id: number): void {
|
public setState(id: number): void {
|
||||||
this.repo.setState(this.motion, id);
|
this.repo.setState(this.motion, id).then(null, this.raiseError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,6 +194,10 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
|||||||
return this.state && this.workflow ? this.state.getNextStates(this.workflow.workflow) : [];
|
return this.state && this.workflow ? this.state.getNextStates(this.workflow.workflow) : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get previousStates(): WorkflowState[] {
|
||||||
|
return this.state && this.workflow ? this.state.getPreviousStates(this.workflow.workflow) : [];
|
||||||
|
}
|
||||||
|
|
||||||
public get item(): ViewItem {
|
public get item(): ViewItem {
|
||||||
return this._item;
|
return this._item;
|
||||||
}
|
}
|
||||||
|
@ -1176,6 +1176,14 @@ class State(RESTModelMixin, models.Model):
|
|||||||
f"{state} can not be next state of {self} because it does not belong to the same workflow."
|
f"{state} can not be next state of {self} because it does not belong to the same workflow."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def is_next_or_previous_state_id(self, state_id):
|
||||||
|
""" Returns true, if the given state id is a valid next or previous state """
|
||||||
|
next_state_ids = [item.id for item in self.next_states.all()]
|
||||||
|
previous_state_ids = [
|
||||||
|
item.id for item in State.objects.filter(next_states__in=[self.id])
|
||||||
|
]
|
||||||
|
return state_id in next_state_ids or state_id in previous_state_ids
|
||||||
|
|
||||||
def get_root_rest_element(self):
|
def get_root_rest_element(self):
|
||||||
"""
|
"""
|
||||||
Returns the workflow to this instance which is the root REST element.
|
Returns the workflow to this instance which is the root REST element.
|
||||||
|
@ -552,6 +552,8 @@ class MotionViewSet(ModelViewSet):
|
|||||||
|
|
||||||
Send PUT {'state': <state_id>} to set and just PUT {} to reset the
|
Send PUT {'state': <state_id>} to set and just PUT {} to reset the
|
||||||
state. Only managers can use this view.
|
state. Only managers can use this view.
|
||||||
|
|
||||||
|
If a state is given, it must be a next or previous state.
|
||||||
"""
|
"""
|
||||||
# Retrieve motion and state.
|
# Retrieve motion and state.
|
||||||
motion = self.get_object()
|
motion = self.get_object()
|
||||||
@ -570,7 +572,7 @@ class MotionViewSet(ModelViewSet):
|
|||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
{"detail": "Invalid data. State must be an integer."}
|
{"detail": "Invalid data. State must be an integer."}
|
||||||
)
|
)
|
||||||
if state_id not in [item.id for item in motion.state.next_states.all()]:
|
if not motion.state.is_next_or_previous_state_id(state_id):
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
{"detail": f"You can not set the state to {state_id}."}
|
{"detail": f"You can not set the state to {state_id}."}
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user