Merge pull request #4974 from tsiegleauq/amendment-sort-by-line
Add sort service for amendments
This commit is contained in:
commit
5c83eb824a
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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> =
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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, {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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 => {
|
||||||
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
@ -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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -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>> {
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user