Merge pull request #4487 from CatoTH/OS3-Bugfix-Amendment-Status-Handling
Bugfix: Amendment statuses
This commit is contained in:
commit
0419ea629f
@ -485,32 +485,36 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
|
||||
return this.diff.getTextWithChanges(targetMotion.text, changes, lineLength, highlightLine);
|
||||
case ChangeRecoMode.Diff:
|
||||
let text = '';
|
||||
changes.forEach((change: ViewUnifiedChange, idx: number) => {
|
||||
if (idx === 0) {
|
||||
text += this.extractMotionLineRange(
|
||||
id,
|
||||
{
|
||||
from: 1,
|
||||
to: change.getLineFrom()
|
||||
},
|
||||
true,
|
||||
lineLength,
|
||||
highlightLine
|
||||
);
|
||||
} else if (changes[idx - 1].getLineTo() < change.getLineFrom()) {
|
||||
text += this.extractMotionLineRange(
|
||||
id,
|
||||
{
|
||||
from: changes[idx - 1].getLineTo(),
|
||||
to: change.getLineFrom()
|
||||
},
|
||||
true,
|
||||
lineLength,
|
||||
highlightLine
|
||||
);
|
||||
}
|
||||
text += this.diff.getChangeDiff(targetMotion.text, change, lineLength, highlightLine);
|
||||
});
|
||||
changes
|
||||
.filter(change => {
|
||||
return change.showInDiffView();
|
||||
})
|
||||
.forEach((change: ViewUnifiedChange, idx: number) => {
|
||||
if (idx === 0) {
|
||||
text += this.extractMotionLineRange(
|
||||
id,
|
||||
{
|
||||
from: 1,
|
||||
to: change.getLineFrom()
|
||||
},
|
||||
true,
|
||||
lineLength,
|
||||
highlightLine
|
||||
);
|
||||
} else if (changes[idx - 1].getLineTo() < change.getLineFrom()) {
|
||||
text += this.extractMotionLineRange(
|
||||
id,
|
||||
{
|
||||
from: changes[idx - 1].getLineTo(),
|
||||
to: change.getLineFrom()
|
||||
},
|
||||
true,
|
||||
lineLength,
|
||||
highlightLine
|
||||
);
|
||||
}
|
||||
text += this.diff.getChangeDiff(targetMotion.text, change, lineLength, highlightLine);
|
||||
});
|
||||
text += this.diff.getTextRemainderAfterLastChange(
|
||||
targetMotion.text,
|
||||
changes,
|
||||
@ -519,7 +523,7 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
|
||||
);
|
||||
return text;
|
||||
case ChangeRecoMode.Final:
|
||||
const appliedChanges: ViewUnifiedChange[] = changes.filter(change => change.isAccepted());
|
||||
const appliedChanges: ViewUnifiedChange[] = changes.filter(change => change.showInFinalView());
|
||||
return this.diff.getTextWithChanges(targetMotion.text, appliedChanges, lineLength, highlightLine);
|
||||
case ChangeRecoMode.ModifiedFinal:
|
||||
if (targetMotion.modified_final_version) {
|
||||
|
@ -43,4 +43,19 @@ export interface ViewUnifiedChange {
|
||||
* True, if rejected. False, if accepted or undecided.
|
||||
*/
|
||||
isRejected(): boolean;
|
||||
|
||||
/**
|
||||
* If this object is to be shown in the Diff view.
|
||||
*/
|
||||
showInDiffView(): boolean;
|
||||
|
||||
/**
|
||||
* If this object is to be shown in the Diff view.
|
||||
*/
|
||||
showInDiffView(): boolean;
|
||||
|
||||
/**
|
||||
* If this object is to be shown in the Final view.
|
||||
*/
|
||||
showInFinalView(): boolean;
|
||||
}
|
||||
|
@ -105,4 +105,12 @@ export class ViewMotionChangeRecommendation extends BaseViewModel implements Vie
|
||||
public isRejected(): boolean {
|
||||
return this.rejected;
|
||||
}
|
||||
|
||||
public showInDiffView(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
public showInFinalView(): boolean {
|
||||
return !this.rejected;
|
||||
}
|
||||
}
|
||||
|
@ -79,4 +79,32 @@ export class ViewMotionAmendedParagraph implements ViewUnifiedChange {
|
||||
public getIdentifier(): string {
|
||||
return this.amendment.identifier;
|
||||
}
|
||||
|
||||
public showInDiffView(): boolean {
|
||||
const mergeState = this.amendment.state
|
||||
? this.amendment.state.merge_amendment_into_final
|
||||
: MergeAmendment.UNDEFINED;
|
||||
switch (mergeState) {
|
||||
case MergeAmendment.YES:
|
||||
return true;
|
||||
case MergeAmendment.NO:
|
||||
return false;
|
||||
default:
|
||||
const mergeRecommendation = this.amendment.recommendation
|
||||
? this.amendment.recommendation.merge_amendment_into_final
|
||||
: MergeAmendment.UNDEFINED;
|
||||
switch (mergeRecommendation) {
|
||||
case MergeAmendment.YES:
|
||||
return true;
|
||||
case MergeAmendment.NO:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public showInFinalView(): boolean {
|
||||
return this.amendment.state && this.amendment.state.merge_amendment_into_final === MergeAmendment.YES;
|
||||
}
|
||||
}
|
||||
|
@ -28,8 +28,8 @@
|
||||
-->
|
||||
</span>
|
||||
<span class="status">
|
||||
<ng-container *ngIf="change.isRejected()"><span translate>Rejected</span></ng-container>
|
||||
<ng-container *ngIf="change.isAccepted() && isAmendment(change)"><span translate>Accepted</span></ng-container>
|
||||
<ng-container *ngIf="change.isRejected()"> – <span translate>Rejected</span></ng-container>
|
||||
<ng-container *ngIf="change.isAccepted() && isAmendment(change)"> – {{ change.amendment.state.name | translate }}</ng-container>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -93,14 +93,6 @@
|
||||
.status {
|
||||
color: gray;
|
||||
font-style: italic;
|
||||
|
||||
& > *:before {
|
||||
content: '(';
|
||||
}
|
||||
|
||||
& > *:after {
|
||||
content: ')';
|
||||
}
|
||||
}
|
||||
|
||||
.no-changes {
|
||||
|
@ -201,21 +201,6 @@ export class MotionDetailDiffComponent extends BaseViewComponent implements Afte
|
||||
return this.lineNumberingMode === LineNumberingMode.Outside;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns accepted, rejected or an empty string depending on the state of this change.
|
||||
*
|
||||
* @param change
|
||||
*/
|
||||
public getAcceptanceValue(change: ViewUnifiedChange): string {
|
||||
if (change.isAccepted()) {
|
||||
return 'accepted';
|
||||
}
|
||||
if (change.isRejected()) {
|
||||
return 'rejected';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the change is an Amendment
|
||||
*
|
||||
|
@ -608,7 +608,7 @@
|
||||
<os-motion-detail-diff
|
||||
*ngIf="isRecoMode(ChangeRecoMode.Diff)"
|
||||
[motion]="motion"
|
||||
[changes]="allChangingObjects"
|
||||
[changes]="getChangesForDiffMode()"
|
||||
[scrollToChange]="scrollToChange"
|
||||
[highlightedLine]="highlightedLine"
|
||||
[lineNumberingMode]="lnMode"
|
||||
|
@ -838,6 +838,18 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
||||
return this.sanitizer.bypassSecurityTrustHtml(diffHtml);
|
||||
}
|
||||
|
||||
public getChangesForDiffMode(): ViewUnifiedChange[] {
|
||||
return this.allChangingObjects.filter(change => {
|
||||
return change.showInDiffView();
|
||||
});
|
||||
}
|
||||
|
||||
public getChangesForFinalMode(): ViewUnifiedChange[] {
|
||||
return this.allChangingObjects.filter(change => {
|
||||
return change.showInFinalView();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger to delete the motion.
|
||||
*/
|
||||
@ -975,7 +987,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
||||
*/
|
||||
public async createModifiedFinalVersion(): Promise<void> {
|
||||
// Get the final version and remove line numbers
|
||||
const changes: ViewUnifiedChange[] = Object.assign([], this.allChangingObjects);
|
||||
const changes: ViewUnifiedChange[] = Object.assign([], this.getChangesForFinalMode());
|
||||
let finalVersion = this.repo.formatMotion(
|
||||
this.motion.id,
|
||||
ChangeRecoMode.Final,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { ChangeRecoMode, LineNumberingMode } from '../../../site/motions/models/view-motion';
|
||||
import { MergeAmendment } from '../../../shared/models/motions/workflow-state';
|
||||
import { ReferencedMotions } from '../base/base-motion-slide';
|
||||
|
||||
/**
|
||||
@ -10,7 +9,8 @@ export interface MotionSlideDataAmendment {
|
||||
id: number;
|
||||
title: string;
|
||||
amendment_paragraphs: string[];
|
||||
merge_amendment_into_final: MergeAmendment;
|
||||
merge_amendment_into_final: number;
|
||||
merge_amendment_into_diff: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { ViewUnifiedChange, ViewUnifiedChangeType } from '../../../shared/models/motions/view-unified-change';
|
||||
import { MotionSlideDataAmendment } from './motion-slide-data';
|
||||
import { MergeAmendment } from '../../../shared/models/motions/workflow-state';
|
||||
import { LineRange } from '../../../core/ui-services/diff.service';
|
||||
|
||||
/**
|
||||
@ -10,7 +9,8 @@ import { LineRange } from '../../../core/ui-services/diff.service';
|
||||
export class MotionSlideObjAmendmentParagraph implements ViewUnifiedChange {
|
||||
public id: number;
|
||||
public type: number;
|
||||
public merge_amendment_into_final: MergeAmendment;
|
||||
public merge_amendment_into_final: number;
|
||||
public merge_amendment_into_diff: number;
|
||||
|
||||
public constructor(
|
||||
data: MotionSlideDataAmendment,
|
||||
@ -20,6 +20,7 @@ export class MotionSlideObjAmendmentParagraph implements ViewUnifiedChange {
|
||||
) {
|
||||
this.id = data.id;
|
||||
this.merge_amendment_into_final = data.merge_amendment_into_final;
|
||||
this.merge_amendment_into_diff = data.merge_amendment_into_diff;
|
||||
}
|
||||
|
||||
public getChangeId(): string {
|
||||
@ -43,10 +44,18 @@ export class MotionSlideObjAmendmentParagraph implements ViewUnifiedChange {
|
||||
}
|
||||
|
||||
public isAccepted(): boolean {
|
||||
return this.merge_amendment_into_final === MergeAmendment.YES;
|
||||
return this.merge_amendment_into_final === 1;
|
||||
}
|
||||
|
||||
public isRejected(): boolean {
|
||||
return this.merge_amendment_into_final === MergeAmendment.NO;
|
||||
return this.merge_amendment_into_final === 0;
|
||||
}
|
||||
|
||||
public showInDiffView(): boolean {
|
||||
return this.merge_amendment_into_diff === 1;
|
||||
}
|
||||
|
||||
public showInFinalView(): boolean {
|
||||
return this.merge_amendment_into_final === 1;
|
||||
}
|
||||
}
|
||||
|
@ -48,4 +48,12 @@ export class MotionSlideObjChangeReco implements MotionSlideDataChangeReco, View
|
||||
public isRejected(): boolean {
|
||||
return this.rejected;
|
||||
}
|
||||
|
||||
public showInDiffView(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
public showInFinalView(): boolean {
|
||||
return !this.rejected;
|
||||
}
|
||||
}
|
||||
|
@ -275,13 +275,16 @@ export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideDa
|
||||
);
|
||||
case ChangeRecoMode.Diff:
|
||||
let text = '';
|
||||
this.allChangingObjects.forEach((change: ViewUnifiedChange, idx: number) => {
|
||||
const changes = this.allChangingObjects.filter(change => {
|
||||
return change.showInDiffView();
|
||||
});
|
||||
changes.forEach((change: ViewUnifiedChange, idx: number) => {
|
||||
if (idx === 0) {
|
||||
const lineRange = { from: 1, to: change.getLineFrom() };
|
||||
text += this.extractMotionLineRange(motion.text, lineRange, true, this.lineLength);
|
||||
} else if (this.allChangingObjects[idx - 1].getLineTo() < change.getLineFrom()) {
|
||||
} else if (changes[idx - 1].getLineTo() < change.getLineFrom()) {
|
||||
const lineRange = {
|
||||
from: this.allChangingObjects[idx - 1].getLineTo(),
|
||||
from: changes[idx - 1].getLineTo(),
|
||||
to: change.getLineFrom()
|
||||
};
|
||||
text += this.extractMotionLineRange(motion.text, lineRange, true, this.lineLength);
|
||||
@ -290,14 +293,14 @@ export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideDa
|
||||
});
|
||||
text += this.diff.getTextRemainderAfterLastChange(
|
||||
motion.text,
|
||||
this.allChangingObjects,
|
||||
changes,
|
||||
this.lineLength,
|
||||
this.highlightedLine
|
||||
);
|
||||
return text;
|
||||
case ChangeRecoMode.Final:
|
||||
const appliedChanges: ViewUnifiedChange[] = this.allChangingObjects.filter(change =>
|
||||
change.isAccepted()
|
||||
change.showInFinalView()
|
||||
);
|
||||
return this.diff.getTextWithChanges(motion.text, appliedChanges, this.lineLength, this.highlightedLine);
|
||||
case ChangeRecoMode.ModifiedFinal:
|
||||
@ -312,7 +315,7 @@ export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideDa
|
||||
} else {
|
||||
// Use the final version as fallback, if the modified does not exist.
|
||||
const appliedChangeObjects: ViewUnifiedChange[] = this.allChangingObjects.filter(change =>
|
||||
change.isAccepted()
|
||||
change.showInFinalView()
|
||||
);
|
||||
return this.diff.getTextWithChanges(
|
||||
motion.text,
|
||||
|
@ -35,31 +35,50 @@ def get_state(
|
||||
)
|
||||
|
||||
|
||||
def get_amendment_merge_into_motion(all_data, motion, amendment):
|
||||
def get_amendment_merge_into_motion_diff(all_data, motion, amendment):
|
||||
"""
|
||||
HINT: This implementation should be consistent to isAccepted() in ViewMotionAmendedParagraph.ts
|
||||
HINT: This implementation should be consistent to showInDiffView() in ViewMotionAmendedParagraph.ts
|
||||
"""
|
||||
if amendment["state_id"] is None:
|
||||
return 0
|
||||
|
||||
state = get_state(all_data, motion, amendment["state_id"])
|
||||
if (
|
||||
state["merge_amendment_into_final"] == -1
|
||||
or state["merge_amendment_into_final"] == 1
|
||||
):
|
||||
return state["merge_amendment_into_final"]
|
||||
if state["merge_amendment_into_final"] == -1:
|
||||
return 0
|
||||
if state["merge_amendment_into_final"] == 1:
|
||||
return 1
|
||||
|
||||
if amendment["recommendation_id"] is None:
|
||||
return 0
|
||||
recommendation = get_state(all_data, motion, amendment["recommendation_id"])
|
||||
return recommendation["merge_amendment_into_final"]
|
||||
if recommendation["merge_amendment_into_final"] == 1:
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def get_amendment_merge_into_motion_final(all_data, motion, amendment):
|
||||
"""
|
||||
HINT: This implementation should be consistent to showInFinalView() in ViewMotionAmendedParagraph.ts
|
||||
"""
|
||||
if amendment["state_id"] is None:
|
||||
return 0
|
||||
|
||||
state = get_state(all_data, motion, amendment["state_id"])
|
||||
if state["merge_amendment_into_final"] == 1:
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def get_amendments_for_motion(motion, all_data):
|
||||
amendment_data = []
|
||||
for amendment_id, amendment in all_data["motions/motion"].items():
|
||||
if amendment["parent_id"] == motion["id"]:
|
||||
merge_amendment_into_final = get_amendment_merge_into_motion(
|
||||
merge_amendment_into_final = get_amendment_merge_into_motion_final(
|
||||
all_data, motion, amendment
|
||||
)
|
||||
merge_amendment_into_diff = get_amendment_merge_into_motion_diff(
|
||||
all_data, motion, amendment
|
||||
)
|
||||
amendment_data.append(
|
||||
@ -68,6 +87,7 @@ def get_amendments_for_motion(motion, all_data):
|
||||
"identifier": amendment["identifier"],
|
||||
"title": amendment["title"],
|
||||
"amendment_paragraphs": amendment["amendment_paragraphs"],
|
||||
"merge_amendment_into_diff": merge_amendment_into_diff,
|
||||
"merge_amendment_into_final": merge_amendment_into_final,
|
||||
}
|
||||
)
|
||||
|
@ -269,6 +269,7 @@ def test_motion_slide(all_data):
|
||||
"amendment_paragraphs": ["New motion text"],
|
||||
"identifier": "Ä1",
|
||||
"merge_amendment_into_final": 0,
|
||||
"merge_amendment_into_diff": 0,
|
||||
}
|
||||
],
|
||||
"amendment_paragraphs": None,
|
||||
|
Loading…
Reference in New Issue
Block a user