Merge pull request #4080 from CatoTH/v3-LineNumbering-Config-Variables

Take motion configuration variables, some layout-fixes
This commit is contained in:
Emanuel Schütze 2019-01-07 09:52:09 +01:00 committed by GitHub
commit f9c4f01f06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 134 additions and 39 deletions

View File

@ -1,3 +1,11 @@
::ng-deep h3 {
margin-top: 0.3em;
margin-bottom: 0.3em;
font-size: 1em;
}
::ng-deep .mat-dialog-content {
overflow: visible;
}
.wide-form { .wide-form {
textarea { textarea {
height: 100px; height: 100px;

View File

@ -103,6 +103,10 @@ export class MotionChangeRecommendationComponent extends BaseViewComponent {
this.changeReco = data.changeRecommendation; this.changeReco = data.changeRecommendation;
this.lineRange = data.lineRange; this.lineRange = data.lineRange;
this.tinyMceSettings.height = 50;
this.tinyMceSettings.toolbar = `undo redo | bold italic underline strikethrough
| removeformat | bullist numlist | outdent indent | link charmap code`;
this.createForm(); this.createForm();
} }

View File

@ -50,7 +50,11 @@
<!-- The actual diff view --> <!-- The actual diff view -->
<div class="motion-text-with-diffs"> <div class="motion-text-with-diffs">
<div *ngFor="let change of changes; let i = index"> <div *ngFor="let change of changes; let i = index">
<div class="motion-text line-numbers-outside"> <div class="motion-text"
[class.line-numbers-none]="isLineNumberingNone()"
[class.line-numbers-inline]="isLineNumberingInline()"
[class.line-numbers-outside]="isLineNumberingOutside()"
>
<os-motion-detail-original-change-recommendations <os-motion-detail-original-change-recommendations
[html]="getTextBetweenChanges(changes[i - 1], change)" [html]="getTextBetweenChanges(changes[i - 1], change)"
[changeRecommendations]="[]" [changeRecommendations]="[]"
@ -90,14 +94,21 @@
</div> </div>
<div <div
class="motion-text motion-text-diff line-numbers-outside" class="motion-text motion-text-diff"
[class.line-numbers-none]="isLineNumberingNone()"
[class.line-numbers-inline]="isLineNumberingInline()"
[class.line-numbers-outside]="isLineNumberingOutside()"
[attr.data-change-id]="change.getChangeId()" [attr.data-change-id]="change.getChangeId()"
[innerHTML]="getDiff(change)" [innerHTML]="getDiff(change)"
></div> ></div>
</div> </div>
</div> </div>
<div class="motion-text line-numbers-outside"> <div class="motion-text"
[class.line-numbers-none]="isLineNumberingNone()"
[class.line-numbers-inline]="isLineNumberingInline()"
[class.line-numbers-outside]="isLineNumberingOutside()"
>
<os-motion-detail-original-change-recommendations <os-motion-detail-original-change-recommendations
[html]="getTextRemainderAfterLastChange()" [html]="getTextRemainderAfterLastChange()"
[changeRecommendations]="[]" [changeRecommendations]="[]"

View File

@ -1,5 +1,5 @@
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, Output } from '@angular/core'; import { AfterViewInit, Component, ElementRef, EventEmitter, Input, Output } from '@angular/core';
import { ViewMotion } from '../../models/view-motion'; import { LineNumberingMode, ViewMotion } from '../../models/view-motion';
import { ViewUnifiedChange, ViewUnifiedChangeType } from '../../models/view-unified-change'; import { ViewUnifiedChange, ViewUnifiedChangeType } from '../../models/view-unified-change';
import { DomSanitizer, SafeHtml, Title } from '@angular/platform-browser'; import { DomSanitizer, SafeHtml, Title } from '@angular/platform-browser';
import { MotionRepositoryService } from '../../services/motion-repository.service'; import { MotionRepositoryService } from '../../services/motion-repository.service';
@ -138,6 +138,33 @@ export class MotionDetailDiffComponent extends BaseViewComponent implements Afte
return change.getChangeType() === ViewUnifiedChangeType.TYPE_CHANGE_RECOMMENDATION; return change.getChangeType() === ViewUnifiedChangeType.TYPE_CHANGE_RECOMMENDATION;
} }
/**
* Returns true if no line numbers are to be shown.
*
* @returns whether there are line numbers at all
*/
public isLineNumberingNone(): boolean {
return this.motion.lnMode === LineNumberingMode.None;
}
/**
* Returns true if the line numbers are to be shown within the text with no line breaks.
*
* @returns whether the line numberings are inside
*/
public isLineNumberingInline(): boolean {
return this.motion.lnMode === LineNumberingMode.Inside;
}
/**
* Returns true if the line numbers are to be shown to the left of the text.
*
* @returns whether the line numberings are outside
*/
public isLineNumberingOutside(): boolean {
return this.motion.lnMode === LineNumberingMode.Outside;
}
/** /**
* Returns accepted, rejected or an empty string depending on the state of this change. * Returns accepted, rejected or an empty string depending on the state of this change.
* *

View File

@ -599,13 +599,16 @@
<!-- Line number Menu --> <!-- Line number Menu -->
<mat-menu #lineNumberingMenu="matMenu"> <mat-menu #lineNumberingMenu="matMenu">
<div *ngIf="motion"> <div *ngIf="motion">
<button mat-menu-item translate (click)="setLineNumberingMode(0)" [ngClass]="{ selected: motion.lnMode === 0 }"> <button mat-menu-item translate (click)="setLineNumberingMode(LineNumberingMode.None)"
[ngClass]="{ selected: motion.lnMode === LineNumberingMode.None }">
none none
</button> </button>
<button mat-menu-item translate (click)="setLineNumberingMode(1)" [ngClass]="{ selected: motion.lnMode === 1 }"> <button mat-menu-item translate (click)="setLineNumberingMode(LineNumberingMode.Inside)"
[ngClass]="{ selected: motion.lnMode === LineNumberingMode.Inside }">
inline inline
</button> </button>
<button mat-menu-item translate (click)="setLineNumberingMode(2)" [ngClass]="{ selected: motion.lnMode === 2 }"> <button mat-menu-item translate (click)="setLineNumberingMode(LineNumberingMode.Outside)"
[ngClass]="{ selected: motion.lnMode === LineNumberingMode.Outside }">
outside outside
</button> </button>
</div> </div>
@ -613,8 +616,12 @@
<!-- Diff View Menu --> <!-- Diff View Menu -->
<mat-menu #changeRecoMenu="matMenu"> <mat-menu #changeRecoMenu="matMenu">
<button mat-menu-item translate (click)="setChangeRecoMode(0)">Original version</button> <button mat-menu-item translate (click)="setChangeRecoMode(ChangeRecoMode.Original)"
<button mat-menu-item translate (click)="setChangeRecoMode(1)">Changed version</button> [ngClass]="{ selected: motion?.crMode === ChangeRecoMode.Original }">Original version</button>
<button mat-menu-item translate (click)="setChangeRecoMode(2)">Diff version</button> <button mat-menu-item translate (click)="setChangeRecoMode(ChangeRecoMode.Changed)"
<button mat-menu-item translate (click)="setChangeRecoMode(3)">Final version</button> [ngClass]="{ selected: motion?.crMode === ChangeRecoMode.Changed }">Changed version</button>
<button mat-menu-item translate (click)="setChangeRecoMode(ChangeRecoMode.Diff)"
[ngClass]="{ selected: motion?.crMode === ChangeRecoMode.Diff }">Diff version</button>
<button mat-menu-item translate (click)="setChangeRecoMode(ChangeRecoMode.Final)"
[ngClass]="{ selected: motion?.crMode === ChangeRecoMode.Final }">Final version</button>
</mat-menu> </mat-menu>

View File

@ -229,6 +229,16 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
*/ */
public itemVisibility = itemVisibilityChoices; public itemVisibility = itemVisibilityChoices;
/**
* For using the enum constants from the template
*/
public ChangeRecoMode = ChangeRecoMode;
/**
* For using the enum constants from the template
*/
public LineNumberingMode = LineNumberingMode;
/** /**
* Constuct the detail view. * Constuct the detail view.
* *
@ -651,7 +661,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
* Sets the motions change reco mode * Sets the motions change reco mode
* @param mode Needs to fot to the enum defined in ViewMotion * @param mode Needs to fot to the enum defined in ViewMotion
*/ */
public setChangeRecoMode(mode: number): void { public setChangeRecoMode(mode: ChangeRecoMode): void {
this.motion.crMode = mode; this.motion.crMode = mode;
} }
@ -659,14 +669,14 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
* Returns true if the original version (including change recommendation annotation) is to be shown * Returns true if the original version (including change recommendation annotation) is to be shown
*/ */
public isRecoModeOriginal(): boolean { public isRecoModeOriginal(): boolean {
return this.motion.crMode === ChangeRecoMode.Original; return this.motion.crMode === ChangeRecoMode.Original || this.allChangingObjects.length === 0;
} }
/** /**
* Returns true if the diff version is to be shown * Returns true if the diff version is to be shown
*/ */
public isRecoModeDiff(): boolean { public isRecoModeDiff(): boolean {
return this.motion.crMode === ChangeRecoMode.Diff; return this.motion.crMode === ChangeRecoMode.Diff && this.allChangingObjects.length > 0;
} }
/** /**

View File

@ -4,7 +4,7 @@ import { Workflow } from '../../../shared/models/motions/workflow';
import { WorkflowState } from '../../../shared/models/motions/workflow-state'; import { WorkflowState } from '../../../shared/models/motions/workflow-state';
import { Item } from 'app/shared/models/agenda/item'; import { Item } from 'app/shared/models/agenda/item';
import { MotionBlock } from 'app/shared/models/motions/motion-block'; import { MotionBlock } from 'app/shared/models/motions/motion-block';
import { ViewMotion } from './view-motion'; import { LineNumberingMode, ViewMotion } from './view-motion';
import { CreateMotion } from './create-motion'; import { CreateMotion } from './create-motion';
/** /**
@ -43,7 +43,7 @@ export class ViewCreateMotion extends ViewMotion {
item?: Item, item?: Item,
block?: MotionBlock block?: MotionBlock
) { ) {
super(motion, category, submitters, supporters, workflow, state, item, block); super(motion, category, submitters, supporters, workflow, state, item, block, null, 80, LineNumberingMode.None);
} }
/** /**

View File

@ -11,17 +11,24 @@ import { Item } from 'app/shared/models/agenda/item';
import { MotionBlock } from 'app/shared/models/motions/motion-block'; import { MotionBlock } from 'app/shared/models/motions/motion-block';
import { Mediafile } from 'app/shared/models/mediafiles/mediafile'; import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
/**
* The line numbering mode for the motion detail view.
* The constants need to be in sync with the values saved in the config store.
*/
export enum LineNumberingMode { export enum LineNumberingMode {
None, None = 'none',
Inside, Inside = 'inline',
Outside Outside = 'outside'
} }
/**
* The change recommendation mode for the motion detail view.
*/
export enum ChangeRecoMode { export enum ChangeRecoMode {
Original, Original = 'original',
Changed, Changed = 'changed',
Diff, Diff = 'diff',
Final Final = 'agreed'
} }
/** /**
@ -236,6 +243,9 @@ export class ViewMotion extends BaseViewModel {
item?: Item, item?: Item,
block?: MotionBlock, block?: MotionBlock,
attachments?: Mediafile[], attachments?: Mediafile[],
lineLength: number = 80,
lineNumberingMode?: LineNumberingMode,
crMode?: ChangeRecoMode
) { ) {
super(); super();
this._motion = motion; this._motion = motion;
@ -248,15 +258,9 @@ export class ViewMotion extends BaseViewModel {
this._block = block; this._block = block;
this._attachments = attachments; this._attachments = attachments;
// TODO: Should be set using a a config variable this.lnMode = lineNumberingMode;
/*this._configService.get('motions_default_line_numbering').subscribe( this.crMode = crMode;
(mode: string): void => { this.lineLength = lineLength;
this.lnMode = LineNumberingMode.Outside;
}
);*/
this.lnMode = LineNumberingMode.Outside;
this.crMode = ChangeRecoMode.Original;
this.lineLength = 80;
this.highlightedLine = null; this.highlightedLine = null;
} }
@ -417,7 +421,10 @@ export class ViewMotion extends BaseViewModel {
this._state, this._state,
this._item, this._item,
this._block, this._block,
this._attachments this._attachments,
this.lineLength,
this.lnMode,
this.crMode
); );
} }
} }

View File

@ -9,7 +9,7 @@ import { User } from '../../../shared/models/users/user';
import { Category } from '../../../shared/models/motions/category'; import { Category } from '../../../shared/models/motions/category';
import { Workflow } from '../../../shared/models/motions/workflow'; import { Workflow } from '../../../shared/models/motions/workflow';
import { WorkflowState } from '../../../shared/models/motions/workflow-state'; import { WorkflowState } from '../../../shared/models/motions/workflow-state';
import { ChangeRecoMode, ViewMotion } from '../models/view-motion'; import { ChangeRecoMode, LineNumberingMode, ViewMotion } from '../models/view-motion';
import { BaseRepository } from '../../base/base-repository'; import { BaseRepository } from '../../base/base-repository';
import { DataStoreService } from '../../../core/services/data-store.service'; import { DataStoreService } from '../../../core/services/data-store.service';
import { LinenumberingService } from './linenumbering.service'; import { LinenumberingService } from './linenumbering.service';
@ -28,6 +28,7 @@ import { ViewMotionAmendedParagraph } from '../models/view-motion-amended-paragr
import { CreateMotion } from '../models/create-motion'; import { CreateMotion } from '../models/create-motion';
import { MotionBlock } from 'app/shared/models/motions/motion-block'; import { MotionBlock } from 'app/shared/models/motions/motion-block';
import { Mediafile } from 'app/shared/models/mediafiles/mediafile'; import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
import { ConfigService } from "../../../core/services/config.service";
/** /**
* Repository Services for motions (and potentially categories) * Repository Services for motions (and potentially categories)
@ -43,6 +44,16 @@ import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
providedIn: 'root' providedIn: 'root'
}) })
export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion> { export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion> {
// The line length; comes from the config variable motions_line_length
private lineLength = 90;
// The default line numbering mode; comes from the config variable motions_default_line_numbering
private defaultLineNumbering = LineNumberingMode.Outside;
// The default line numbering mode; comes from the config variable motions_recommendation_text_mode
private defaultCrMode = ChangeRecoMode.Original;
/** /**
* Creates a MotionRepository * Creates a MotionRepository
* *
@ -55,6 +66,7 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
* @param httpService OpenSlides own Http service * @param httpService OpenSlides own Http service
* @param lineNumbering Line numbering for motion text * @param lineNumbering Line numbering for motion text
* @param diff Display changes in motion text as diff. * @param diff Display changes in motion text as diff.
* @param configService The configuration provider
*/ */
public constructor( public constructor(
DS: DataStoreService, DS: DataStoreService,
@ -63,9 +75,15 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
private httpService: HttpService, private httpService: HttpService,
private readonly lineNumbering: LinenumberingService, private readonly lineNumbering: LinenumberingService,
private readonly diff: DiffService, private readonly diff: DiffService,
private readonly configService: ConfigService,
private treeService: TreeService private treeService: TreeService
) { ) {
super(DS, mapperService, Motion, [Category, User, Workflow, Item, MotionBlock, Mediafile]); super(DS, mapperService, Motion, [Category, User, Workflow, Item, MotionBlock, Mediafile]);
// load config variables
this.configService.get('motions_line_length').subscribe(lineLength => this.lineLength = lineLength);
this.configService.get('motions_default_line_numbering').subscribe(mode => this.defaultLineNumbering = mode);
this.configService.get('motions_recommendation_text_mode').subscribe(mode => this.defaultCrMode = mode);
} }
/** /**
@ -88,7 +106,7 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
if (workflow) { if (workflow) {
state = workflow.getStateById(motion.state_id); state = workflow.getStateById(motion.state_id);
} }
return new ViewMotion(motion, category, submitters, supporters, workflow, state, item, block, attachments); return new ViewMotion(motion, category, submitters, supporters, workflow, state, item, block, attachments, this.lineLength, this.defaultLineNumbering, this.defaultCrMode);
} }
/** /**
@ -315,7 +333,7 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
const appliedChanges: ViewUnifiedChange[] = changes.filter(change => change.isAccepted()); const appliedChanges: ViewUnifiedChange[] = changes.filter(change => change.isAccepted());
return this.diff.getTextWithChanges(targetMotion, appliedChanges, lineLength, highlightLine); return this.diff.getTextWithChanges(targetMotion, appliedChanges, lineLength, highlightLine);
default: default:
console.error('unrecognized ChangeRecoMode option'); console.error('unrecognized ChangeRecoMode option (' + crMode + ')');
return null; return null;
} }
} else { } else {
@ -342,8 +360,7 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
* @param {boolean} lineNumbers - weather to add line numbers to the returned HTML string * @param {boolean} lineNumbers - weather to add line numbers to the returned HTML string
*/ */
public extractMotionLineRange(id: number, lineRange: LineRange, lineNumbers: boolean): string { public extractMotionLineRange(id: number, lineRange: LineRange, lineNumbers: boolean): string {
// @TODO flexible line numbers const origHtml = this.formatMotion(id, ChangeRecoMode.Original, [], this.lineLength);
const origHtml = this.formatMotion(id, ChangeRecoMode.Original, [], 80);
const extracted = this.diff.extractRangeByLineNumbers(origHtml, lineRange.from, lineRange.to); const extracted = this.diff.extractRangeByLineNumbers(origHtml, lineRange.from, lineRange.to);
let html = let html =
extracted.outerContextStart + extracted.outerContextStart +
@ -370,7 +387,7 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
changes: ViewUnifiedChange[], changes: ViewUnifiedChange[],
highlight?: number highlight?: number
): string { ): string {
let maxLine = 0; let maxLine = 1;
changes.forEach((change: ViewUnifiedChange) => { changes.forEach((change: ViewUnifiedChange) => {
if (change.getLineTo() > maxLine) { if (change.getLineTo() > maxLine) {
maxLine = change.getLineTo(); maxLine = change.getLineTo();
@ -378,6 +395,10 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
}, 0); }, 0);
const numberedHtml = this.lineNumbering.insertLineNumbers(motion.text, motion.lineLength); const numberedHtml = this.lineNumbering.insertLineNumbers(motion.text, motion.lineLength);
if (changes.length === 0) {
return numberedHtml;
}
let data; let data;
try { try {