Merge pull request #4974 from tsiegleauq/amendment-sort-by-line

Add sort service for amendments
This commit is contained in:
Emanuel Schütze 2019-09-05 14:14:11 +02:00 committed by GitHub
commit 5c83eb824a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 245 additions and 87 deletions

View File

@ -82,12 +82,18 @@ export class RelationManagerService {
); );
viewModel['_' + relation.ownKey] = foreignViewModels; viewModel['_' + relation.ownKey] = foreignViewModels;
this.sortByRelation(relation, viewModel); this.sortByRelation(relation, viewModel);
if (relation.afterSetRelation) {
relation.afterSetRelation(viewModel, foreignViewModels);
}
} else if (relation.type === 'M2O') { } else if (relation.type === 'M2O') {
const foreignViewModel = this.viewModelStoreService.get( const foreignViewModel = this.viewModelStoreService.get(
relation.foreignViewModel, relation.foreignViewModel,
model[relation.ownIdKey] model[relation.ownIdKey]
); );
viewModel['_' + relation.ownKey] = foreignViewModel; viewModel['_' + relation.ownKey] = foreignViewModel;
if (relation.afterSetRelation) {
relation.afterSetRelation(viewModel, foreignViewModel);
}
} }
} else if (isReverseRelationDefinition(relation) && !initialLoading) { } else if (isReverseRelationDefinition(relation) && !initialLoading) {
if (relation.type === 'M2M') { if (relation.type === 'M2M') {
@ -203,12 +209,19 @@ export class RelationManagerService {
) { ) {
const foreignViewModel = <any>this.viewModelStoreService.get(collection, changedId); const foreignViewModel = <any>this.viewModelStoreService.get(collection, changedId);
this.setForeingViewModelInOwnViewModelArray(foreignViewModel, ownViewModel, relation.ownKey); this.setForeingViewModelInOwnViewModelArray(foreignViewModel, ownViewModel, relation.ownKey);
if (relation.afterDependencyChange) {
relation.afterDependencyChange(ownViewModel, foreignViewModel);
}
return true; return true;
} }
} else if (relation.type === 'M2O') { } else if (relation.type === 'M2O') {
if (ownViewModel[relation.ownIdKey] === <any>changedId) { if (ownViewModel[relation.ownIdKey] === <any>changedId) {
// Check, if this is the matching foreign view model. // Check, if this is the matching foreign view model.
ownViewModel['_' + relation.ownKey] = <any>this.viewModelStoreService.get(collection, changedId); const foreignViewModel = this.viewModelStoreService.get(collection, changedId);
ownViewModel['_' + relation.ownKey] = <any>foreignViewModel;
if (relation.afterDependencyChange) {
relation.afterDependencyChange(ownViewModel, foreignViewModel);
}
return true; return true;
} }
} }

View File

@ -39,6 +39,8 @@ interface BaseNormalRelationDefinition<VForeign extends BaseViewModel> extends B
* the model and view model. E.g. `category_id` in a motion. * the model and view model. E.g. `category_id` in a motion.
*/ */
ownIdKey: string; ownIdKey: string;
afterDependencyChange?: (ownViewModel: BaseViewModel, foreignViewModel: BaseViewModel) => void;
} }
/** /**
@ -56,16 +58,19 @@ interface NormalM2MRelationDefinition<VForeign extends BaseViewModel>
extends BaseNormalRelationDefinition<VForeign>, extends BaseNormalRelationDefinition<VForeign>,
BaseOrderedRelation<VForeign> { BaseOrderedRelation<VForeign> {
type: 'M2M'; type: 'M2M';
afterSetRelation?: (ownViewModel: BaseViewModel, foreignViewModels: BaseViewModel[]) => void;
} }
interface NormalO2MRelationDefinition<VForeign extends BaseViewModel> interface NormalO2MRelationDefinition<VForeign extends BaseViewModel>
extends BaseNormalRelationDefinition<VForeign>, extends BaseNormalRelationDefinition<VForeign>,
BaseOrderedRelation<VForeign> { BaseOrderedRelation<VForeign> {
type: 'O2M'; type: 'O2M';
afterSetRelation?: (ownViewModel: BaseViewModel, foreignViewModels: BaseViewModel[]) => void;
} }
interface NormalM2ORelationDefinition<VForeign extends BaseViewModel> extends BaseNormalRelationDefinition<VForeign> { interface NormalM2ORelationDefinition<VForeign extends BaseViewModel> extends BaseNormalRelationDefinition<VForeign> {
type: 'M2O'; type: 'M2O';
afterSetRelation?: (ownViewModel: BaseViewModel, foreignViewModel: BaseViewModel | null) => void;
} }
export type NormalRelationDefinition<VForeign extends BaseViewModel = BaseViewModel> = export type NormalRelationDefinition<VForeign extends BaseViewModel = BaseViewModel> =

View File

@ -133,12 +133,6 @@ const MotionRelations: RelationDefinition[] = [
ownKey: 'tags', ownKey: 'tags',
foreignViewModel: ViewTag foreignViewModel: ViewTag
}, },
{
type: 'M2O',
ownIdKey: 'parent_id',
ownKey: 'parent',
foreignViewModel: ViewMotion
},
{ {
type: 'M2M', type: 'M2M',
ownIdKey: 'change_recommendations_id', ownIdKey: 'change_recommendations_id',
@ -171,6 +165,11 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
*/ */
protected sortProperty: SortProperty; protected sortProperty: SortProperty;
/**
* Line length of a motion
*/
private motionLineLength: number;
/** /**
* Creates a MotionRepository * Creates a MotionRepository
* *
@ -206,10 +205,15 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
this.sortProperty = conf; this.sortProperty = conf;
this.setConfigSortFn(); this.setConfigSortFn();
}); });
config.get<number>('motions_line_length').subscribe(lineLength => {
this.motionLineLength = lineLength;
});
} }
/** /**
* Adds the personal note custom relation to the relation definitions. * Adds the personal note custom relation to the relation definitions.
* Also adds the parent relation here to get access to methods in this repo.
*/ */
protected groupRelationsByCollections(): void { protected groupRelationsByCollections(): void {
this.relationDefinitions.push({ this.relationDefinitions.push({
@ -228,6 +232,22 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
return true; return true;
} }
}); });
this.relationDefinitions.push({
type: 'M2O',
ownIdKey: 'parent_id',
ownKey: 'parent',
foreignViewModel: ViewMotion,
afterSetRelation: (motion: ViewMotion, foreignViewModel: ViewMotion | null) => {
if (foreignViewModel) {
motion.diffLines = this.getAmendmentParagraphs(motion, this.motionLineLength, false);
}
},
afterDependencyChange: (motion: ViewMotion, parent: ViewMotion) => {
if (motion.parent) {
motion.diffLines = this.getAmendmentParagraphs(motion, this.motionLineLength, false);
}
}
});
super.groupRelationsByCollections(); super.groupRelationsByCollections();
} }
@ -284,8 +304,10 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
protected createViewModelWithTitles(model: Motion, initialLoading: boolean): ViewMotion { protected createViewModelWithTitles(model: Motion, initialLoading: boolean): ViewMotion {
const viewModel = super.createViewModelWithTitles(model, initialLoading); const viewModel = super.createViewModelWithTitles(model, initialLoading);
viewModel.getIdentifierOrTitle = () => this.getIdentifierOrTitle(viewModel); viewModel.getIdentifierOrTitle = () => this.getIdentifierOrTitle(viewModel);
viewModel.getProjectorTitle = () => this.getAgendaSlideTitle(viewModel); viewModel.getProjectorTitle = () => this.getAgendaSlideTitle(viewModel);
return viewModel; return viewModel;
} }
@ -639,16 +661,6 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
return range.to; return range.to;
} }
/**
* Given an amendment, this returns the motion affected by this amendments
*
* @param {ViewMotion} amendment
* @returns {ViewMotion}
*/
public getAmendmentBaseMotion(amendment: ViewMotion): ViewMotion {
return this.getViewModel(amendment.parent_id);
}
/** /**
* Splits a motion into paragraphs, optionally adding line numbers * Splits a motion into paragraphs, optionally adding line numbers
* *
@ -700,7 +712,7 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
lineLength: number, lineLength: number,
includeUnchanged: boolean includeUnchanged: boolean
): DiffLinesInParagraph[] { ): DiffLinesInParagraph[] {
const motion = this.getAmendmentBaseMotion(amendment); const motion = amendment.parent;
const baseParagraphs = this.getTextParagraphs(motion, true, lineLength); const baseParagraphs = this.getTextParagraphs(motion, true, lineLength);
return amendment.amendment_paragraphs return amendment.amendment_paragraphs
@ -744,7 +756,7 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
* @returns {ViewMotionAmendedParagraph[]} * @returns {ViewMotionAmendedParagraph[]}
*/ */
public getAmendmentAmendedParagraphs(amendment: ViewMotion, lineLength: number): ViewMotionAmendedParagraph[] { public getAmendmentAmendedParagraphs(amendment: ViewMotion, lineLength: number): ViewMotionAmendedParagraph[] {
const motion = this.getAmendmentBaseMotion(amendment); const motion = amendment.parent;
const baseParagraphs = this.getTextParagraphs(motion, true, lineLength); const baseParagraphs = this.getTextParagraphs(motion, true, lineLength);
return amendment.amendment_paragraphs return amendment.amendment_paragraphs

View File

@ -243,8 +243,6 @@ export abstract class BaseFilterListService<V extends BaseViewModel> {
if (storedFilter && storedFilter.length && newDefinitions && newDefinitions.length) { if (storedFilter && storedFilter.length && newDefinitions && newDefinitions.length) {
for (const newDef of newDefinitions) { for (const newDef of newDefinitions) {
console.log('set filter');
// for some weird angular bugs, newDef can actually be undefined // for some weird angular bugs, newDef can actually be undefined
if (newDef) { if (newDef) {
let count = 0; let count = 0;

View File

@ -55,6 +55,11 @@ export abstract class BaseSortListService<V extends BaseViewModel> {
*/ */
private sortDefinition: OsSortingDefinition<V>; private sortDefinition: OsSortingDefinition<V>;
/**
* The key to access stored valued
*/
protected abstract readonly storageKey: string;
/** /**
* The sorting function according to current settings. * The sorting function according to current settings.
*/ */
@ -105,13 +110,15 @@ export abstract class BaseSortListService<V extends BaseViewModel> {
* @returns wether sorting is active or not * @returns wether sorting is active or not
*/ */
public get isActive(): boolean { public get isActive(): boolean {
return this.sortDefinition && this.sortOptions.length > 0; return this.sortOptions && this.sortOptions.length > 0;
} }
/** public get sortOptions(): OsSortingOption<V>[] {
* Enforce children to implement sortOptions const sortOptions = this.getSortOptions();
*/ if (sortOptions && sortOptions.length) {
public abstract sortOptions: OsSortingOption<V>[]; return sortOptions;
}
}
/** /**
* Constructor. * Constructor.
@ -121,12 +128,16 @@ export abstract class BaseSortListService<V extends BaseViewModel> {
* @param store to save and load sorting preferences * @param store to save and load sorting preferences
*/ */
public constructor( public constructor(
protected name: string,
protected translate: TranslateService, protected translate: TranslateService,
private store: StorageService, private store: StorageService,
private OSStatus: OpenSlidesStatusService private OSStatus: OpenSlidesStatusService
) {} ) {}
/**
* Enforce children to implement a function that returns their sorting options
*/
protected abstract getSortOptions(): OsSortingOption<V>[];
/** /**
* Enforce children to implement a method that returns the fault sorting * Enforce children to implement a method that returns the fault sorting
*/ */
@ -148,7 +159,7 @@ export abstract class BaseSortListService<V extends BaseViewModel> {
if (this.OSStatus.isInHistoryMode) { if (this.OSStatus.isInHistoryMode) {
this.sortDefinition = null; this.sortDefinition = null;
} else { } else {
this.sortDefinition = await this.store.get<OsSortingDefinition<V> | null>('sorting_' + this.name); this.sortDefinition = await this.store.get<OsSortingDefinition<V> | null>('sorting_' + this.storageKey);
} }
if (this.sortDefinition && this.sortDefinition.sortProperty) { if (this.sortDefinition && this.sortDefinition.sortProperty) {
@ -183,11 +194,15 @@ export abstract class BaseSortListService<V extends BaseViewModel> {
* @param option * @param option
* @returns the name of the sorting icon, fit to material icon ligatures * @returns the name of the sorting icon, fit to material icon ligatures
*/ */
public getSortIcon(option: OsSortingOption<V>): string { public getSortIcon(option: OsSortingOption<V>): string | null {
if (this.sortProperty !== option.property) { if (this.sortDefinition) {
if (this.sortProperty && this.sortProperty !== option.property) {
return ''; return '';
} }
return this.ascending ? 'arrow_upward' : 'arrow_downward'; return this.ascending ? 'arrow_upward' : 'arrow_downward';
} else {
return null;
}
} }
/** /**
@ -210,7 +225,7 @@ export abstract class BaseSortListService<V extends BaseViewModel> {
private updateSortDefinitions(): void { private updateSortDefinitions(): void {
this.updateSortedData(); this.updateSortedData();
if (!this.OSStatus.isInHistoryMode) { if (!this.OSStatus.isInHistoryMode) {
this.store.set('sorting_' + this.name, this.sortDefinition); this.store.set('sorting_' + this.storageKey, this.sortDefinition);
} }
} }
@ -227,7 +242,7 @@ export abstract class BaseSortListService<V extends BaseViewModel> {
* every time the sorting (property, ascending/descending) or the language changes * every time the sorting (property, ascending/descending) or the language changes
*/ */
protected updateSortedData(): void { protected updateSortedData(): void {
if (this.inputData) { if (this.inputData && this.sortDefinition) {
const property = this.sortProperty as string; const property = this.sortProperty as string;
const intl = new Intl.Collator(this.translate.currentLang, { const intl = new Intl.Collator(this.translate.currentLang, {

View File

@ -208,8 +208,9 @@ export class SortFilterBarComponent<V extends BaseViewModel> {
* Retrieves the currently active icon for an option. * Retrieves the currently active icon for an option.
* @param option * @param option
*/ */
public getSortIcon(option: OsSortingOption<V>): string { public getSortIcon(option: OsSortingOption<V>): string | null {
return this.sortService.getSortIcon(option); const icon = this.sortService.getSortIcon(option);
return icon ? icon : null;
} }
/** /**

View File

@ -14,10 +14,15 @@ import { ViewAssignment } from '../models/view-assignment';
providedIn: 'root' providedIn: 'root'
}) })
export class AssignmentSortListService extends BaseSortListService<ViewAssignment> { export class AssignmentSortListService extends BaseSortListService<ViewAssignment> {
/**
* set the storage key name
*/
protected storageKey = 'AssignmentList';
/** /**
* Define the sort options * Define the sort options
*/ */
public sortOptions: OsSortingOption<ViewAssignment>[] = [ private assignmentSortOptions: OsSortingOption<ViewAssignment>[] = [
{ property: 'title', label: 'Name' }, { property: 'title', label: 'Name' },
{ property: 'phase', label: 'Phase' }, { property: 'phase', label: 'Phase' },
{ property: 'candidateAmount', label: 'Number of candidates' }, { property: 'candidateAmount', label: 'Number of candidates' },
@ -31,7 +36,14 @@ export class AssignmentSortListService extends BaseSortListService<ViewAssignmen
* @param storage required by parent * @param storage required by parent
*/ */
public constructor(translate: TranslateService, storage: StorageService, OSStatus: OpenSlidesStatusService) { public constructor(translate: TranslateService, storage: StorageService, OSStatus: OpenSlidesStatusService) {
super('Assignment', translate, storage, OSStatus); super(translate, storage, OSStatus);
}
/**
* @override
*/
protected getSortOptions(): OsSortingOption<ViewAssignment>[] {
return this.assignmentSortOptions;
} }
/** /**

View File

@ -14,7 +14,12 @@ import { ViewMediafile } from '../models/view-mediafile';
providedIn: 'root' providedIn: 'root'
}) })
export class MediafilesSortListService extends BaseSortListService<ViewMediafile> { export class MediafilesSortListService extends BaseSortListService<ViewMediafile> {
public sortOptions: OsSortingOption<ViewMediafile>[] = [ /**
* set the storage key name
*/
protected storageKey = 'MediafileList';
private mediafilesSortOptions: OsSortingOption<ViewMediafile>[] = [
{ property: 'title' }, { property: 'title' },
{ {
property: 'type', property: 'type',
@ -33,7 +38,14 @@ export class MediafilesSortListService extends BaseSortListService<ViewMediafile
* @param store required by parent * @param store required by parent
*/ */
public constructor(translate: TranslateService, store: StorageService, OSStatus: OpenSlidesStatusService) { public constructor(translate: TranslateService, store: StorageService, OSStatus: OpenSlidesStatusService) {
super('Mediafiles', translate, store, OSStatus); super(translate, store, OSStatus);
}
/**
* @override
*/
protected getSortOptions(): OsSortingOption<ViewMediafile>[] {
return this.mediafilesSortOptions;
} }
/** /**

View File

@ -1,5 +1,6 @@
import { _ } from 'app/core/translate/translation-marker'; import { _ } from 'app/core/translate/translation-marker';
import { ConfigService } from 'app/core/ui-services/config.service'; import { ConfigService } from 'app/core/ui-services/config.service';
import { DiffLinesInParagraph } from 'app/core/ui-services/diff.service';
import { SearchProperty, SearchRepresentation } from 'app/core/ui-services/search.service'; import { SearchProperty, SearchRepresentation } from 'app/core/ui-services/search.service';
import { Motion, MotionComment } from 'app/shared/models/motions/motion'; import { Motion, MotionComment } from 'app/shared/models/motions/motion';
import { PersonalNoteContent } from 'app/shared/models/users/personal-note'; import { PersonalNoteContent } from 'app/shared/models/users/personal-note';
@ -76,6 +77,7 @@ export class ViewMotion extends BaseViewModelWithAgendaItemAndListOfSpeakers<Mot
protected _parent?: ViewMotion; protected _parent?: ViewMotion;
protected _amendments?: ViewMotion[]; protected _amendments?: ViewMotion[];
protected _changeRecommendations?: ViewMotionChangeRecommendation[]; protected _changeRecommendations?: ViewMotionChangeRecommendation[];
protected _diffLines?: DiffLinesInParagraph[];
public personalNote?: PersonalNoteContent; public personalNote?: PersonalNoteContent;
public get motion(): Motion { public get motion(): Motion {
@ -342,6 +344,31 @@ export class ViewMotion extends BaseViewModelWithAgendaItemAndListOfSpeakers<Mot
return this.state ? this.state.css_class : ''; return this.state ? this.state.css_class : '';
} }
/**
* getter to access diff lines
*/
public get diffLines(): DiffLinesInParagraph[] {
if (!this.parent_id) {
throw new Error('No parent No diff');
}
return this._diffLines;
}
public set diffLines(value: DiffLinesInParagraph[]) {
this._diffLines = value;
}
/**
* Get the number of the first diff line, in case a motion is an amendment
*/
public get parentAndLineNumber(): string | null {
if (this.isParagraphBasedAmendment() && this.parent && this.diffLines && this.diffLines.length) {
return `${this.parent.identifier} ${this.diffLines[0].diffLineFrom}`;
} else {
return null;
}
}
// This is set by the repository // This is set by the repository
public getIdentifierOrTitle: () => string; public getIdentifierOrTitle: () => string;

View File

@ -18,7 +18,7 @@
<os-list-view-table <os-list-view-table
[repo]="motionRepo" [repo]="motionRepo"
[sortService]="motionSortService" [sortService]="amendmentSortService"
[filterService]="amendmentFilterService" [filterService]="amendmentFilterService"
[columns]="tableColumnDefinition" [columns]="tableColumnDefinition"
[filterProps]="filterProps" [filterProps]="filterProps"
@ -70,6 +70,7 @@
<!-- Summary --> <!-- Summary -->
<div *pblNgridCellDef="'summary'; row as motion" class="cell-slot fill"> <div *pblNgridCellDef="'summary'; row as motion" class="cell-slot fill">
<a class="detail-link" [routerLink]="motion.getDetailStateURL()"></a>
<div class="innerTable"> <div class="innerTable">
<div class="motion-text" [innerHtml]="sanitizeText(getAmendmentSummary(motion))"></div> <div class="motion-text" [innerHtml]="sanitizeText(getAmendmentSummary(motion))"></div>
</div> </div>

View File

@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, Component, OnInit, ViewEncapsulation } from '@angular/core';
import { MatDialog, MatSnackBar } from '@angular/material'; import { MatDialog, MatSnackBar } from '@angular/material';
import { DomSanitizer, SafeHtml, Title } from '@angular/platform-browser'; import { DomSanitizer, SafeHtml, Title } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
@ -7,10 +7,9 @@ import { TranslateService } from '@ngx-translate/core';
import { PblColumnDefinition } from '@pebula/ngrid'; import { PblColumnDefinition } from '@pebula/ngrid';
import { AmendmentFilterListService } from '../../services/amendment-filter-list.service'; import { AmendmentFilterListService } from '../../services/amendment-filter-list.service';
import { AmendmentSortListService } from '../../services/amendment-sort-list.service';
import { StorageService } from 'app/core/core-services/storage.service'; import { StorageService } from 'app/core/core-services/storage.service';
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service'; import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
import { ConfigService } from 'app/core/ui-services/config.service';
import { DiffLinesInParagraph } from 'app/core/ui-services/diff.service';
import { LinenumberingService } from 'app/core/ui-services/linenumbering.service'; import { LinenumberingService } from 'app/core/ui-services/linenumbering.service';
import { ItemVisibilityChoices } from 'app/shared/models/agenda/item'; import { ItemVisibilityChoices } from 'app/shared/models/agenda/item';
import { largeDialogSettings } from 'app/shared/utils/dialog-settings'; import { largeDialogSettings } from 'app/shared/utils/dialog-settings';
@ -27,7 +26,8 @@ import { ViewMotion } from '../../models/view-motion';
selector: 'os-amendment-list', selector: 'os-amendment-list',
templateUrl: './amendment-list.component.html', templateUrl: './amendment-list.component.html',
styleUrls: ['./amendment-list.component.scss'], styleUrls: ['./amendment-list.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
}) })
export class AmendmentListComponent extends BaseListViewComponent<ViewMotion> implements OnInit { export class AmendmentListComponent extends BaseListViewComponent<ViewMotion> implements OnInit {
/** /**
@ -40,11 +40,6 @@ export class AmendmentListComponent extends BaseListViewComponent<ViewMotion> im
*/ */
public itemVisibility = ItemVisibilityChoices; public itemVisibility = ItemVisibilityChoices;
/**
* To hold the motions line length
*/
private motionLineLength: number;
/** /**
* Column defintiion * Column defintiion
*/ */
@ -88,9 +83,9 @@ export class AmendmentListComponent extends BaseListViewComponent<ViewMotion> im
route: ActivatedRoute, route: ActivatedRoute,
public motionRepo: MotionRepositoryService, public motionRepo: MotionRepositoryService,
public motionSortService: MotionSortListService, public motionSortService: MotionSortListService,
public amendmentSortService: AmendmentSortListService,
public amendmentFilterService: AmendmentFilterListService, public amendmentFilterService: AmendmentFilterListService,
private sanitizer: DomSanitizer, private sanitizer: DomSanitizer,
private configService: ConfigService,
private dialog: MatDialog, private dialog: MatDialog,
private motionExport: MotionExportService, private motionExport: MotionExportService,
private linenumberingService: LinenumberingService private linenumberingService: LinenumberingService
@ -106,32 +101,7 @@ export class AmendmentListComponent extends BaseListViewComponent<ViewMotion> im
} }
} }
/** public ngOnInit(): void {}
* Observe the line length
*/
public ngOnInit(): void {
this.configService.get<number>('motions_line_length').subscribe(lineLength => {
this.motionLineLength = lineLength;
});
if (!!this.parentMotionId) {
// this.amendmentFilterService.clearAllFilters();
}
}
/**
* Helper function to get amendment paragraphs of a given motion
*
* @param amendment the get the paragraphs from
* @returns DiffLinesInParagraph-List
*/
private getDiffLines(amendment: ViewMotion): DiffLinesInParagraph[] {
if (amendment.isParagraphBasedAmendment()) {
return this.motionRepo.getAmendmentParagraphs(amendment, this.motionLineLength, false);
} else {
return null;
}
}
/** /**
* Extract the lines of the amendments * Extract the lines of the amendments
@ -141,7 +111,7 @@ export class AmendmentListComponent extends BaseListViewComponent<ViewMotion> im
* @return The lines of the amendment * @return The lines of the amendment
*/ */
public getChangeLines(amendment: ViewMotion): string { public getChangeLines(amendment: ViewMotion): string {
const diffLines = this.getDiffLines(amendment); const diffLines = amendment.diffLines;
if (!!diffLines) { if (!!diffLines) {
return diffLines return diffLines
@ -163,7 +133,7 @@ export class AmendmentListComponent extends BaseListViewComponent<ViewMotion> im
* @returns the amendments as string, if they are multiple they gonna be separated by `[...]` * @returns the amendments as string, if they are multiple they gonna be separated by `[...]`
*/ */
public getAmendmentSummary(amendment: ViewMotion): string { public getAmendmentSummary(amendment: ViewMotion): string {
const diffLines = this.getDiffLines(amendment); const diffLines = amendment.diffLines;
if (!!diffLines) { if (!!diffLines) {
return diffLines return diffLines
.map(diffLine => { .map(diffLine => {

View File

@ -0,0 +1,12 @@
import { TestBed } from '@angular/core/testing';
import { AmendmentSortListService } from './amendment-sort-list.service';
describe('AmendmentSortListService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: AmendmentSortListService = TestBed.get(AmendmentSortListService);
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,47 @@
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { OpenSlidesStatusService } from 'app/core/core-services/openslides-status.service';
import { StorageService } from 'app/core/core-services/storage.service';
import { OsSortingDefinition, OsSortingOption } from 'app/core/ui-services/base-sort-list.service';
import { ConfigService } from 'app/core/ui-services/config.service';
import { MotionSortListService } from './motion-sort-list.service';
import { ViewMotion } from '../models/view-motion';
@Injectable({
providedIn: 'root'
})
export class AmendmentSortListService extends MotionSortListService {
/**
* set the storage key name
*/
protected storageKey = 'AmendmentList';
private amendmentSortOptions: OsSortingOption<ViewMotion>[] = [
{
property: 'parentAndLineNumber',
label: 'Main motion and line number'
}
];
public constructor(
translate: TranslateService,
store: StorageService,
OSStatus: OpenSlidesStatusService,
config: ConfigService
) {
super(translate, store, OSStatus, config);
}
protected getSortOptions(): OsSortingOption<ViewMotion>[] {
return this.amendmentSortOptions.concat(super.getSortOptions());
}
protected async getDefaultDefinition(): Promise<OsSortingDefinition<ViewMotion>> {
return {
sortProperty: 'parentAndLineNumber',
sortAscending: true
};
}
}

View File

@ -11,7 +11,12 @@ import { ViewMotionBlock } from '../models/view-motion-block';
providedIn: 'root' providedIn: 'root'
}) })
export class MotionBlockSortService extends BaseSortListService<ViewMotionBlock> { export class MotionBlockSortService extends BaseSortListService<ViewMotionBlock> {
public sortOptions: OsSortingOption<ViewMotionBlock>[] = [ /**
* set the storage key name
*/
protected storageKey = 'MotionBlockList';
private MotionBlockSortOptions: OsSortingOption<ViewMotionBlock>[] = [
{ property: 'title' }, { property: 'title' },
{ {
property: 'motions', property: 'motions',
@ -25,7 +30,14 @@ export class MotionBlockSortService extends BaseSortListService<ViewMotionBlock>
]; ];
public constructor(translate: TranslateService, store: StorageService, OSStatus: OpenSlidesStatusService) { public constructor(translate: TranslateService, store: StorageService, OSStatus: OpenSlidesStatusService) {
super('Motion block', translate, store, OSStatus); super(translate, store, OSStatus);
}
/**
* @override
*/
protected getSortOptions(): OsSortingOption<ViewMotionBlock>[] {
return this.MotionBlockSortOptions;
} }
protected async getDefaultDefinition(): Promise<OsSortingDefinition<ViewMotionBlock>> { protected async getDefaultDefinition(): Promise<OsSortingDefinition<ViewMotionBlock>> {

View File

@ -17,6 +17,11 @@ import { ViewMotion } from '../models/view-motion';
providedIn: 'root' providedIn: 'root'
}) })
export class MotionSortListService extends BaseSortListService<ViewMotion> { export class MotionSortListService extends BaseSortListService<ViewMotion> {
/**
* set the storage key name
*/
protected storageKey = 'MotionList';
/** /**
* Hold the default motion sorting * Hold the default motion sorting
*/ */
@ -30,7 +35,7 @@ export class MotionSortListService extends BaseSortListService<ViewMotion> {
/** /**
* Define the sort options * Define the sort options
*/ */
public sortOptions: OsSortingOption<ViewMotion>[] = [ protected motionSortOptions: OsSortingOption<ViewMotion>[] = [
{ property: 'weight', label: 'Call list' }, { property: 'weight', label: 'Call list' },
{ property: 'identifier' }, { property: 'identifier' },
{ property: 'title' }, { property: 'title' },
@ -53,11 +58,11 @@ export class MotionSortListService extends BaseSortListService<ViewMotion> {
translate: TranslateService, translate: TranslateService,
store: StorageService, store: StorageService,
OSStatus: OpenSlidesStatusService, OSStatus: OpenSlidesStatusService,
private config: ConfigService config: ConfigService
) { ) {
super('Motion', translate, store, OSStatus); super(translate, store, OSStatus);
this.config.get<string>('motions_motions_sorting').subscribe(defSortProp => { config.get<string>('motions_motions_sorting').subscribe(defSortProp => {
if (defSortProp) { if (defSortProp) {
this.defaultMotionSorting = defSortProp; this.defaultMotionSorting = defSortProp;
this.defaultSortingLoaded.resolve(); this.defaultSortingLoaded.resolve();
@ -65,6 +70,10 @@ export class MotionSortListService extends BaseSortListService<ViewMotion> {
}); });
} }
protected getSortOptions(): OsSortingOption<ViewMotion>[] {
return this.motionSortOptions;
}
/** /**
* Required by parent * Required by parent
* *

View File

@ -14,10 +14,15 @@ import { ViewUser } from '../models/view-user';
providedIn: 'root' providedIn: 'root'
}) })
export class UserSortListService extends BaseSortListService<ViewUser> { export class UserSortListService extends BaseSortListService<ViewUser> {
/**
* set the storage key name
*/
protected storageKey = 'UserList';
/** /**
* Define the sort options * Define the sort options
*/ */
public sortOptions: OsSortingOption<ViewUser>[] = [ private userSortOptions: OsSortingOption<ViewUser>[] = [
{ property: 'first_name', label: 'Given name' }, { property: 'first_name', label: 'Given name' },
{ property: 'last_name', label: 'Surname' }, { property: 'last_name', label: 'Surname' },
{ property: 'is_present', label: 'Presence' }, { property: 'is_present', label: 'Presence' },
@ -36,7 +41,14 @@ export class UserSortListService extends BaseSortListService<ViewUser> {
* @param store requires by parent * @param store requires by parent
*/ */
public constructor(translate: TranslateService, store: StorageService, OSStatus: OpenSlidesStatusService) { public constructor(translate: TranslateService, store: StorageService, OSStatus: OpenSlidesStatusService) {
super('User', translate, store, OSStatus); super(translate, store, OSStatus);
}
/**
* @override
*/
protected getSortOptions(): OsSortingOption<ViewUser>[] {
return this.userSortOptions;
} }
/** /**