Motion Attachments + Restructure
This commit is contained in:
parent
574fde5f6d
commit
00db199947
@ -24,6 +24,15 @@ export class Mediafile extends ProjectableBaseModel {
|
|||||||
this.mediafile = new File(input.mediafile);
|
this.mediafile = new File(input.mediafile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the downloadURL
|
||||||
|
*
|
||||||
|
* @returns the download URL for the specific file as string
|
||||||
|
*/
|
||||||
|
public getDownloadUrl(): string {
|
||||||
|
return `${this.media_url_prefix}${this.mediafile.name}`;
|
||||||
|
}
|
||||||
|
|
||||||
public getTitle(): string {
|
public getTitle(): string {
|
||||||
return this.title;
|
return this.title;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
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';
|
||||||
@ -12,6 +14,7 @@ import { ViewSpeaker } from '../models/view-speaker';
|
|||||||
import { Speaker } from 'app/shared/models/agenda/speaker';
|
import { Speaker } from 'app/shared/models/agenda/speaker';
|
||||||
import { User } from 'app/shared/models/users/user';
|
import { User } from 'app/shared/models/users/user';
|
||||||
import { HttpService } from 'app/core/services/http.service';
|
import { HttpService } from 'app/core/services/http.service';
|
||||||
|
import { ConfigService } from 'app/core/services/config.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository service for users
|
* Repository service for users
|
||||||
@ -27,11 +30,13 @@ export class AgendaRepositoryService extends BaseRepository<ViewItem, Item> {
|
|||||||
* @param DS The DataStore
|
* @param DS The DataStore
|
||||||
* @param httpService OpenSlides own HttpService
|
* @param httpService OpenSlides own HttpService
|
||||||
* @param mapperService OpenSlides mapping service for collection strings
|
* @param mapperService OpenSlides mapping service for collection strings
|
||||||
|
* @param config Read config variables
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
protected DS: DataStoreService,
|
protected DS: DataStoreService,
|
||||||
private httpService: HttpService,
|
private httpService: HttpService,
|
||||||
mapperService: CollectionStringModelMapperService
|
mapperService: CollectionStringModelMapperService,
|
||||||
|
private config: ConfigService
|
||||||
) {
|
) {
|
||||||
super(DS, mapperService, Item);
|
super(DS, mapperService, Item);
|
||||||
}
|
}
|
||||||
@ -179,4 +184,13 @@ export class AgendaRepositoryService extends BaseRepository<ViewItem, Item> {
|
|||||||
const contentObject = this.getContentObject(item);
|
const contentObject = this.getContentObject(item);
|
||||||
return new ViewItem(item, contentObject);
|
return new ViewItem(item, contentObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get agenda visibility from the config
|
||||||
|
*
|
||||||
|
* @return An observable to the default agenda visibility
|
||||||
|
*/
|
||||||
|
public getDefaultAgendaVisibility(): Observable<number> {
|
||||||
|
return this.config.get('agenda_new_items_default_visibility').pipe(map(key => +key));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,8 +92,7 @@ export abstract class ListViewBaseComponent<V extends BaseViewModel> extends Bas
|
|||||||
* Should be overridden by implementations. Currently there is no default action.
|
* Should be overridden by implementations. Currently there is no default action.
|
||||||
* @param row a ViewModel
|
* @param row a ViewModel
|
||||||
*/
|
*/
|
||||||
public singleSelectAction(row: V) : void {
|
public singleSelectAction(row: V): void {}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enables/disables the multiSelect Mode
|
* enables/disables the multiSelect Mode
|
||||||
@ -107,6 +106,13 @@ export abstract class ListViewBaseComponent<V extends BaseViewModel> extends Bas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select all files in the current data source
|
||||||
|
*/
|
||||||
|
public selectAll(): void {
|
||||||
|
this.selectedRows = this.dataSource.data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current state of the multiSelect modus
|
* Returns the current state of the multiSelect modus
|
||||||
*/
|
*/
|
||||||
|
@ -168,6 +168,10 @@
|
|||||||
<mat-icon>library_add</mat-icon>
|
<mat-icon>library_add</mat-icon>
|
||||||
<span translate>Exit multiselect</span>
|
<span translate>Exit multiselect</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-menu-item (click)="selectAll()">
|
||||||
|
<mat-icon>done_all</mat-icon>
|
||||||
|
<span translate>Select all</span>
|
||||||
|
</button>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<button mat-menu-item *osPerms="'mediafiles.can_manage'" (click)="deleteSelected()">
|
<button mat-menu-item *osPerms="'mediafiles.can_manage'" (click)="deleteSelected()">
|
||||||
<mat-icon>delete</mat-icon>
|
<mat-icon>delete</mat-icon>
|
||||||
|
@ -43,7 +43,7 @@ export class ViewMediafile extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get downloadUrl(): string {
|
public get downloadUrl(): string {
|
||||||
return this.mediafile && this.mediafile.mediafile ? `${this.prefix}${this.fileName}` : null;
|
return this.mediafile ? this.mediafile.getDownloadUrl() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public constructor(mediafile?: Mediafile, uploader?: User) {
|
public constructor(mediafile?: Mediafile, uploader?: User) {
|
||||||
@ -100,7 +100,7 @@ export class ViewMediafile extends BaseViewModel {
|
|||||||
'video/3gpp',
|
'video/3gpp',
|
||||||
'video/x-msvideo',
|
'video/x-msvideo',
|
||||||
'video/x-ms-wmv',
|
'video/x-ms-wmv',
|
||||||
'video/x-matroska',
|
'video/x-matroska'
|
||||||
].includes(this.type);
|
].includes(this.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,14 +3,6 @@
|
|||||||
<button class="small-button" type="button" mat-icon-button disableRipple *ngIf="!isEditMode" (click)="onEdit()">
|
<button class="small-button" type="button" mat-icon-button disableRipple *ngIf="!isEditMode" (click)="onEdit()">
|
||||||
<mat-icon>edit</mat-icon>
|
<mat-icon>edit</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<span *ngIf="isEditMode">
|
|
||||||
<button class="small-button" type="button" mat-icon-button disableRipple (click)="onSave()">
|
|
||||||
<mat-icon>save</mat-icon>
|
|
||||||
</button>
|
|
||||||
<button class="small-button" type="button" mat-icon-button disableRipple (click)="onCancel()">
|
|
||||||
<mat-icon>close</mat-icon>
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
<div *ngIf="!isEditMode">
|
<div *ngIf="!isEditMode">
|
||||||
@ -32,7 +24,13 @@
|
|||||||
></os-search-value-selector>
|
></os-search-value-selector>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<os-sorting-list class="testclass" [input]="editSubmitterObservable" [live]="true" [count]="true" (sortEvent)="onSortingChange($event)">
|
<os-sorting-list
|
||||||
|
class="testclass"
|
||||||
|
[input]="editSubmitterObservable"
|
||||||
|
[live]="true"
|
||||||
|
[count]="true"
|
||||||
|
(sortEvent)="onSortingChange($event)"
|
||||||
|
>
|
||||||
<!-- implicit user references into the component using ng-template slot -->
|
<!-- implicit user references into the component using ng-template slot -->
|
||||||
<ng-template let-user>
|
<ng-template let-user>
|
||||||
<button type="button" mat-icon-button matTooltip="{{ 'Remove' | translate }}" (click)="onRemove(user)">
|
<button type="button" mat-icon-button matTooltip="{{ 'Remove' | translate }}" (click)="onRemove(user)">
|
||||||
@ -40,6 +38,9 @@
|
|||||||
</button>
|
</button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</os-sorting-list>
|
</os-sorting-list>
|
||||||
|
<mat-card-actions>
|
||||||
|
<button type="button" mat-button (click)="onSave()"><span translate>Save</span></button>
|
||||||
|
<button type="button" mat-button (click)="onCancel()"><span translate>Cancel</span></button>
|
||||||
|
</mat-card-actions>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import { Item, itemVisibilityChoices } from 'app/shared/models/agenda/item';
|
|||||||
import { DataStoreService } from 'app/core/services/data-store.service';
|
import { DataStoreService } from 'app/core/services/data-store.service';
|
||||||
import { MotionBlockRepositoryService } from '../../services/motion-block-repository.service';
|
import { MotionBlockRepositoryService } from '../../services/motion-block-repository.service';
|
||||||
import { ViewMotionBlock } from '../../models/view-motion-block';
|
import { ViewMotionBlock } from '../../models/view-motion-block';
|
||||||
|
import { AgendaRepositoryService } from 'app/site/agenda/services/agenda-repository.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table for the motion blocks
|
* Table for the motion blocks
|
||||||
@ -57,6 +58,7 @@ export class MotionBlockListComponent extends ListViewBaseComponent<ViewMotionBl
|
|||||||
* @param router routing to children
|
* @param router routing to children
|
||||||
* @param route determine the local route
|
* @param route determine the local route
|
||||||
* @param repo the motion block repository
|
* @param repo the motion block repository
|
||||||
|
* @param agendaRepo the agenda repository service
|
||||||
* @param DS the dataStore
|
* @param DS the dataStore
|
||||||
* @param formBuilder creates forms
|
* @param formBuilder creates forms
|
||||||
*/
|
*/
|
||||||
@ -67,6 +69,7 @@ export class MotionBlockListComponent extends ListViewBaseComponent<ViewMotionBl
|
|||||||
private router: Router,
|
private router: Router,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private repo: MotionBlockRepositoryService,
|
private repo: MotionBlockRepositoryService,
|
||||||
|
private agendaRepo: AgendaRepositoryService,
|
||||||
private DS: DataStoreService,
|
private DS: DataStoreService,
|
||||||
private formBuilder: FormBuilder
|
private formBuilder: FormBuilder
|
||||||
) {
|
) {
|
||||||
@ -98,7 +101,7 @@ export class MotionBlockListComponent extends ListViewBaseComponent<ViewMotionBl
|
|||||||
this.dataSource.data = newMotionblocks;
|
this.dataSource.data = newMotionblocks;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.repo.getDefaultAgendaVisibility().subscribe(visibility => (this.defaultVisibility = visibility));
|
this.agendaRepo.getDefaultAgendaVisibility().subscribe(visibility => (this.defaultVisibility = visibility));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<span translate>Motion</span>
|
<span translate>Motion</span>
|
||||||
<!-- Whitespace between "Motion" and identifier -->
|
<!-- Whitespace between "Motion" and identifier -->
|
||||||
<span> </span> <span *ngIf="!editMotion">{{ motion.identifier }}</span>
|
<span> </span> <span *ngIf="!editMotion">{{ motion.identifier }}</span>
|
||||||
<span *ngIf="editMotion">{{ metaInfoForm.get('identifier').value }}</span>
|
<span *ngIf="editMotion">{{ contentForm.get('identifier').value }}</span>
|
||||||
</h2>
|
</h2>
|
||||||
<h2 *ngIf="newMotion" translate>New motion</h2>
|
<h2 *ngIf="newMotion" translate>New motion</h2>
|
||||||
</div>
|
</div>
|
||||||
@ -21,14 +21,32 @@
|
|||||||
<div *ngIf="!editMotion" class="extra-controls-slot on-transition-fade">
|
<div *ngIf="!editMotion" class="extra-controls-slot on-transition-fade">
|
||||||
<div *ngIf="previousMotion">
|
<div *ngIf="previousMotion">
|
||||||
<button mat-button (click)="navigateToMotion(previousMotion)">
|
<button mat-button (click)="navigateToMotion(previousMotion)">
|
||||||
<mat-icon>navigate_before</mat-icon>
|
<!-- possible icons:
|
||||||
|
arrow_left
|
||||||
|
chevron_left
|
||||||
|
first_page
|
||||||
|
arrow_back
|
||||||
|
arrow_back_ios
|
||||||
|
navigate_before
|
||||||
|
fast_rewind
|
||||||
|
-->
|
||||||
|
<mat-icon>chevron_left</mat-icon>
|
||||||
<span>{{ previousMotion.identifier }}</span>
|
<span>{{ previousMotion.identifier }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="nextMotion">
|
<div *ngIf="nextMotion">
|
||||||
<button mat-button (click)="navigateToMotion(nextMotion)">
|
<button mat-button (click)="navigateToMotion(nextMotion)">
|
||||||
<span>{{ nextMotion.identifier }}</span>
|
<span>{{ nextMotion.identifier }}</span>
|
||||||
<mat-icon>navigate_next</mat-icon>
|
<!-- possible icons:
|
||||||
|
arrow_right
|
||||||
|
chevron_right
|
||||||
|
last_page
|
||||||
|
arrow_forward
|
||||||
|
arrow_forward_ios
|
||||||
|
navigate_next
|
||||||
|
fast_forward
|
||||||
|
-->
|
||||||
|
<mat-icon>chevron_right</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -87,18 +105,16 @@
|
|||||||
</os-head-bar>
|
</os-head-bar>
|
||||||
|
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<div *ngIf="motion" class="motion-title on-transition-fade">
|
<div class="motion-title on-transition-fade" *ngIf="motion && !editMotion">
|
||||||
<h2 *ngIf="!editMotion">{{ motion.title }}</h2>
|
<h2>{{ motion.title }}</h2>
|
||||||
<h2 *ngIf="editMotion">{{ contentForm.get('title').value }}</h2>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-container *ngIf="vp.isMobile; then: mobileView; else: desktopView"></ng-container>
|
<ng-container *ngIf="vp.isMobile; then mobileView; else desktopView"></ng-container>
|
||||||
|
|
||||||
<ng-template #mobileView>
|
<ng-template #mobileView>
|
||||||
<mat-accordion multi='true' class='on-transition-fade'>
|
<mat-accordion multi="true" class="on-transition-fade">
|
||||||
|
|
||||||
<!-- MetaInfo Panel-->
|
<!-- MetaInfo Panel-->
|
||||||
<mat-expansion-panel #metaInfoPanel [expanded]="true" class='meta-info-block meta-info-panel'>
|
<mat-expansion-panel #metaInfoPanel [expanded]="true" class="meta-info-block meta-info-panel">
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>
|
<mat-panel-title>
|
||||||
<mat-icon>info</mat-icon>
|
<mat-icon>info</mat-icon>
|
||||||
@ -126,8 +142,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
|
|
||||||
<os-motion-comments *ngIf="!newMotion" [motion]="motion"></os-motion-comments>
|
<os-motion-comments *ngIf="!editMotion" [motion]="motion"></os-motion-comments>
|
||||||
<os-personal-note *ngIf="!newMotion" [motion]="motion"></os-personal-note>
|
<os-personal-note *ngIf="!editMotion" [motion]="motion"></os-personal-note>
|
||||||
</mat-accordion>
|
</mat-accordion>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
@ -139,8 +155,8 @@
|
|||||||
<ng-container *ngTemplateOutlet="metaInfoTemplate"></ng-container>
|
<ng-container *ngTemplateOutlet="metaInfoTemplate"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<os-motion-comments *ngIf="!newMotion" [motion]="motion"></os-motion-comments>
|
<os-motion-comments *ngIf="!editMotion" [motion]="motion"></os-motion-comments>
|
||||||
<os-personal-note *ngIf="!newMotion" [motion]="motion"></os-personal-note>
|
<os-personal-note *ngIf="!editMotion" [motion]="motion"></os-personal-note>
|
||||||
</div>
|
</div>
|
||||||
<div class="desktop-right ">
|
<div class="desktop-right ">
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
@ -150,71 +166,41 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template #metaInfoTemplate>
|
<ng-template #metaInfoTemplate>
|
||||||
<form [formGroup]="metaInfoForm" (keydown)="onKeyDown($event)" (ngSubmit)="saveMotion()">
|
<div *ngIf="motion">
|
||||||
<!-- Identifier -->
|
|
||||||
<div *ngIf="editMotion && !newMotion">
|
|
||||||
<!-- <div *ngIf="editMotion"> -->
|
|
||||||
<div *ngIf="!editMotion">
|
|
||||||
<h4 translate>Identifier</h4>
|
|
||||||
{{ motion.identifier }}
|
|
||||||
</div>
|
|
||||||
<mat-form-field *ngIf="editMotion">
|
|
||||||
<input
|
|
||||||
matInput
|
|
||||||
placeholder="{{ "Identifier" | translate }}"
|
|
||||||
formControlName="identifier"
|
|
||||||
[value]="motionCopy.identifier"
|
|
||||||
/>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Submitters -->
|
<!-- Submitters -->
|
||||||
<div *ngIf="motion && motion.submitters || newMotion">
|
<div *ngIf="motion.submitters || newMotion">
|
||||||
<div *ngIf="newMotion">
|
<div *ngIf="!editMotion"><os-manage-submitters [motion]="motion"></os-manage-submitters></div>
|
||||||
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
|
||||||
<os-search-value-selector
|
|
||||||
ngDefaultControl
|
|
||||||
[form]="metaInfoForm"
|
|
||||||
[formControl]="metaInfoForm.get('submitters_id')"
|
|
||||||
[multiple]="true"
|
|
||||||
listname="{{ 'Submitters' | translate }}"
|
|
||||||
[InputListValues]="submitterObserver"
|
|
||||||
></os-search-value-selector>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!editMotion && !newMotion">
|
|
||||||
<os-manage-submitters [motion]="motion"></os-manage-submitters>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Supporters -->
|
<!-- do Support -->
|
||||||
<div *ngIf='motion && minSupporters'>
|
<div *ngIf="minSupporters && !editMotion">
|
||||||
<div *ngIf="editMotion">
|
|
||||||
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
|
||||||
<os-search-value-selector
|
|
||||||
ngDefaultControl
|
|
||||||
[form]="metaInfoForm"
|
|
||||||
[formControl]="metaInfoForm.get('supporters_id')"
|
|
||||||
[multiple]="true"
|
|
||||||
listname="{{ 'Supporters' | translate }}"
|
|
||||||
[InputListValues]="supporterObserver"
|
|
||||||
></os-search-value-selector>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!editMotion">
|
|
||||||
<h4 *ngIf="perms.isAllowed('support', motion) || motion.hasSupporters()" translate>Supporters</h4>
|
<h4 *ngIf="perms.isAllowed('support', motion) || motion.hasSupporters()" translate>Supporters</h4>
|
||||||
|
|
||||||
<!-- support button -->
|
<!-- support button -->
|
||||||
<button type="button" *ngIf="perms.isAllowed('support', motion)" (click)=support() mat-raised-button color="primary">
|
<button
|
||||||
|
type="button"
|
||||||
|
mat-raised-button
|
||||||
|
color="primary"
|
||||||
|
(click)="support()"
|
||||||
|
*ngIf="perms.isAllowed('support', motion)"
|
||||||
|
>
|
||||||
<mat-icon>thumb_up</mat-icon>
|
<mat-icon>thumb_up</mat-icon>
|
||||||
{{ 'Support' | translate }}
|
{{ 'Support' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- unsupport button -->
|
<!-- unsupport button -->
|
||||||
<button type="button" *ngIf="perms.isAllowed('unsupport', motion)" (click)=unsupport() mat-raised-button color="primary">
|
<button
|
||||||
|
type="button"
|
||||||
|
*ngIf="perms.isAllowed('unsupport', motion)"
|
||||||
|
(click)="unsupport()"
|
||||||
|
mat-raised-button
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
<mat-icon>thumb_down</mat-icon>
|
<mat-icon>thumb_down</mat-icon>
|
||||||
{{ 'Unsupport' | translate }}
|
{{ 'Unsupport' | translate }}
|
||||||
</button>
|
</button>
|
||||||
<!-- show supporters (TODO: open in dialog) -->
|
<!-- show supporters (TODO: open in dialog) -->
|
||||||
<button type="button" *ngIf="motion.hasSupporters()" (click)=openSupportersDialog() mat-button>
|
<button type="button" *ngIf="motion.hasSupporters()" (click)="openSupportersDialog()" mat-button>
|
||||||
{{ motion.supporters.length }} {{ 'supporters' | translate }}
|
{{ motion.supporters.length }} {{ 'supporters' | translate }}
|
||||||
</button>
|
</button>
|
||||||
<p *ngIf="showSupporters">
|
<p *ngIf="showSupporters">
|
||||||
@ -224,25 +210,28 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
<!-- Set State -->
|
||||||
|
<div *ngIf="!editMotion">
|
||||||
<!-- State -->
|
|
||||||
<div *ngIf='motion && !editMotion'>
|
|
||||||
<h4 translate>State</h4>
|
<h4 translate>State</h4>
|
||||||
<mat-menu #stateMenu='matMenu'>
|
<mat-menu #stateMenu="matMenu">
|
||||||
<button *ngFor='let state of motion.nextStates' mat-menu-item
|
<button *ngFor="let state of motion.nextStates" mat-menu-item (click)="setState(state.id)">
|
||||||
(click)=setState(state.id)>{{ state.name | translate }}
|
{{ state.name | translate }}
|
||||||
</button>
|
</button>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<button mat-menu-item (click)=setState(null)>
|
<button mat-menu-item (click)="setState(null)">
|
||||||
<mat-icon>replay</mat-icon> {{ 'Reset state' | translate }}
|
<mat-icon>replay</mat-icon> {{ 'Reset state' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
<mat-basic-chip [matMenuTriggerFor]='stateMenu' [ngClass]="{
|
<mat-basic-chip
|
||||||
'green': motion.state.css_class === 'success',
|
*ngIf="motion.state"
|
||||||
'red': motion.state.css_class === 'danger',
|
[matMenuTriggerFor]="stateMenu"
|
||||||
'grey': motion.state.css_class === 'default',
|
[ngClass]="{
|
||||||
'lightblue': motion.state.css_class === 'primary' }">
|
green: motion.state.css_class === 'success',
|
||||||
|
red: motion.state.css_class === 'danger',
|
||||||
|
grey: motion.state.css_class === 'default',
|
||||||
|
lightblue: motion.state.css_class === 'primary'
|
||||||
|
}"
|
||||||
|
>
|
||||||
{{ motion.state.name | translate }}
|
{{ motion.state.name | translate }}
|
||||||
</mat-basic-chip>
|
</mat-basic-chip>
|
||||||
|
|
||||||
@ -250,27 +239,35 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Recommendation -->
|
<!-- Recommendation -->
|
||||||
<div *ngIf='motion && recommender && !editMotion'>
|
<div *ngIf="recommender && !editMotion">
|
||||||
<h4>{{ recommender }}</h4>
|
<h4>{{ recommender }}</h4>
|
||||||
<mat-menu #recommendationMenu='matMenu'>
|
<mat-menu #recommendationMenu="matMenu">
|
||||||
<button *ngFor='let recommendation of motion.possibleRecommendations' mat-menu-item
|
<button
|
||||||
(click)=setRecommendation(recommendation.id)>{{ recommendation.recommendation_label | translate }}
|
*ngFor="let recommendation of motion.possibleRecommendations"
|
||||||
|
mat-menu-item
|
||||||
|
(click)="setRecommendation(recommendation.id)"
|
||||||
|
>
|
||||||
|
{{ recommendation.recommendation_label | translate }}
|
||||||
</button>
|
</button>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<button mat-menu-item (click)=setRecommendation(null)>
|
<button mat-menu-item (click)="setRecommendation(null)">
|
||||||
<mat-icon>replay</mat-icon> {{ 'Reset recommendation' | translate }}
|
<mat-icon>replay</mat-icon> {{ 'Reset recommendation' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
<mat-basic-chip [matMenuTriggerFor]='recommendationMenu' class="bluegrey">
|
<mat-basic-chip [matMenuTriggerFor]="recommendationMenu" class="bluegrey">
|
||||||
{{ motion.recommendation ? (motion.recommendation.recommendation_label | translate) : ('not set' | translate) }}
|
{{
|
||||||
|
motion.recommendation
|
||||||
|
? (motion.recommendation.recommendation_label | translate)
|
||||||
|
: ('not set' | translate)
|
||||||
|
}}
|
||||||
</mat-basic-chip>
|
</mat-basic-chip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Category -->
|
<!-- Category -->
|
||||||
<!-- Disabled during "new motion" since changing has no effect -->
|
<!-- Disabled during "new motion" since changing has no effect -->
|
||||||
<div *ngIf="motion && !editMotion">
|
<div *ngIf="!editMotion">
|
||||||
<h4 translate>Category</h4>
|
<h4 translate>Category</h4>
|
||||||
<mat-menu #categoryMenu='matMenu'>
|
<mat-menu #categoryMenu="matMenu">
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
*ngFor="let category of categoryObserver.value"
|
*ngFor="let category of categoryObserver.value"
|
||||||
@ -278,75 +275,34 @@
|
|||||||
>
|
>
|
||||||
{{ category }}
|
{{ category }}
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item (click)=setCategory(null)>
|
<button mat-menu-item (click)="setCategory(null)">---</button>
|
||||||
---
|
|
||||||
</button>
|
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
<mat-basic-chip [matMenuTriggerFor]='categoryMenu' class="grey">
|
<mat-basic-chip [matMenuTriggerFor]="categoryMenu" class="grey">
|
||||||
{{ motion.category ? motion.category : ('not set' | translate) }}
|
{{ motion.category ? motion.category : ('not set' | translate) }}
|
||||||
</mat-basic-chip>
|
</mat-basic-chip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Block -->
|
<!-- Block -->
|
||||||
<div *ngIf="motion && !editMotion">
|
<div *ngIf="!editMotion">
|
||||||
<h4 translate>Motion block</h4>
|
<h4 translate>Motion block</h4>
|
||||||
|
|
||||||
<mat-menu #blockMenu='matMenu'>
|
<mat-menu #blockMenu="matMenu">
|
||||||
<button
|
<button mat-menu-item *ngFor="let block of blockObserver.value" (click)="setBlock(block.id)">
|
||||||
mat-menu-item
|
|
||||||
*ngFor="let block of blockObserver.value"
|
|
||||||
(click)="setBlock(block.id)"
|
|
||||||
>
|
|
||||||
{{ block }}
|
{{ block }}
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item (click)="setBlock(null)">
|
<button mat-menu-item (click)="setBlock(null)">---</button>
|
||||||
---
|
|
||||||
</button>
|
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
<mat-basic-chip [matMenuTriggerFor]='blockMenu' class="grey">
|
<mat-basic-chip [matMenuTriggerFor]="blockMenu" class="grey">
|
||||||
{{ motion.motion_block ? motion.motion_block : ('not set' | translate) }}
|
{{ motion.motion_block ? motion.motion_block : ('not set' | translate) }}
|
||||||
</mat-basic-chip>
|
</mat-basic-chip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Workflow -->
|
<!-- Origin - display only -->
|
||||||
<div *ngIf="editMotion">
|
<div *ngIf="!editMotion && motion.origin">
|
||||||
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
|
||||||
<os-search-value-selector
|
|
||||||
ngDefaultControl
|
|
||||||
[form]="metaInfoForm"
|
|
||||||
[formControl]="metaInfoForm.get('workflow_id')"
|
|
||||||
[multiple]="false"
|
|
||||||
listname="{{ 'Workflow' | translate }}"
|
|
||||||
[InputListValues]="workflowObserver"
|
|
||||||
></os-search-value-selector>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Origin -->
|
|
||||||
<div *ngIf="(motion && motion.origin) || editMotion">
|
|
||||||
<div *ngIf="!editMotion">
|
|
||||||
<h4 translate>Origin</h4>
|
<h4 translate>Origin</h4>
|
||||||
{{ motion.origin }}
|
{{ motion.origin }}
|
||||||
</div>
|
</div>
|
||||||
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
|
||||||
<mat-form-field *ngIf="editMotion">
|
|
||||||
<input
|
|
||||||
matInput
|
|
||||||
placeholder="{{ 'Origin' | translate}}"
|
|
||||||
formControlName="origin"
|
|
||||||
[value]="motionCopy.origin"
|
|
||||||
/>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Voting -->
|
|
||||||
<!--
|
|
||||||
<div *ngIf='motion.polls && motion.polls.length > 0 || editMotion'>
|
|
||||||
<h4 translate>Voting</h4>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
</form>
|
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template #contentTemplate>
|
<ng-template #contentTemplate>
|
||||||
@ -356,9 +312,10 @@
|
|||||||
(clickdown)="onKeyDown($event)"
|
(clickdown)="onKeyDown($event)"
|
||||||
(keydown)="onKeyDown($event)"
|
(keydown)="onKeyDown($event)"
|
||||||
(ngSubmit)="saveMotion()"
|
(ngSubmit)="saveMotion()"
|
||||||
|
*ngIf="motion"
|
||||||
>
|
>
|
||||||
<!-- Line Number and Diff buttons -->
|
<!-- Line Number and Diff buttons -->
|
||||||
<div *ngIf="motion && !editMotion && !motion.isStatuteAmendment()" class="motion-text-controls">
|
<div *ngIf="!editMotion && !motion.isStatuteAmendment()" class="motion-text-controls">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
@ -397,13 +354,36 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Title -->
|
<!-- Submitter -->
|
||||||
<div *ngIf="(motion && motion.title) || editMotion">
|
<div *ngIf="newMotion" class="content-field form100">
|
||||||
<div *ngIf="!editMotion">
|
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
||||||
<h4>{{ motion.title }}</h4>
|
<os-search-value-selector
|
||||||
|
ngDefaultControl
|
||||||
|
[form]="contentForm"
|
||||||
|
[formControl]="contentForm.get('submitters_id')"
|
||||||
|
[multiple]="true"
|
||||||
|
listname="{{ 'Submitters' | translate }}"
|
||||||
|
[InputListValues]="submitterObserver"
|
||||||
|
></os-search-value-selector>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-form-field *ngIf="editMotion" class="wide-form">
|
<div class="form-id-title">
|
||||||
|
<!-- Identifier -->
|
||||||
|
<div *ngIf="editMotion && !newMotion" class="content-field form-identifier">
|
||||||
|
<mat-form-field *ngIf="editMotion">
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
placeholder="{{ 'Identifier' | translate }}"
|
||||||
|
formControlName="identifier"
|
||||||
|
[value]="motionCopy.identifier"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<div *ngIf="editMotion" class="content-field form-title">
|
||||||
|
<mat-form-field *ngIf="editMotion">
|
||||||
<input
|
<input
|
||||||
matInput
|
matInput
|
||||||
osAutofocus
|
osAutofocus
|
||||||
@ -414,14 +394,13 @@
|
|||||||
/>
|
/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Text -->
|
<!-- Text -->
|
||||||
<span class="text-prefix-label">{{ preamble | translate }}</span>
|
<span class="text-prefix-label">{{ preamble | translate }}</span>
|
||||||
|
|
||||||
<!-- Regular motions or traditional amendments -->
|
<!-- Regular motions or traditional amendments -->
|
||||||
<ng-container
|
<ng-container *ngIf="!editMotion && !motion.isStatuteAmendment() && !motion.isParagraphBasedAmendment()">
|
||||||
*ngIf="motion && !editMotion && !motion.isStatuteAmendment() && !motion.isParagraphBasedAmendment()"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
*ngIf="!isRecoModeDiff()"
|
*ngIf="!isRecoModeDiff()"
|
||||||
class="motion-text"
|
class="motion-text"
|
||||||
@ -451,7 +430,7 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
<div
|
<div
|
||||||
class="motion-text line-numbers-none"
|
class="motion-text line-numbers-none"
|
||||||
*ngIf="motion && !editMotion && motion.isStatuteAmendment()"
|
*ngIf="!editMotion && motion.isStatuteAmendment()"
|
||||||
[innerHTML]="getFormattedStatuteAmendment()"
|
[innerHTML]="getFormattedStatuteAmendment()"
|
||||||
></div>
|
></div>
|
||||||
|
|
||||||
@ -459,21 +438,120 @@
|
|||||||
<editor formControlName="text" [init]="tinyMceSettings" *ngIf="motion && editMotion"></editor>
|
<editor formControlName="text" [init]="tinyMceSettings" *ngIf="motion && editMotion"></editor>
|
||||||
|
|
||||||
<!-- Paragraph-based amendments -->
|
<!-- Paragraph-based amendments -->
|
||||||
<ng-container *ngIf="motion && !editMotion && motion.isParagraphBasedAmendment()">
|
<ng-container *ngIf="!editMotion && motion.isParagraphBasedAmendment()">
|
||||||
<ng-container *ngTemplateOutlet="paragraphBasedAmendment"></ng-container>
|
<ng-container *ngTemplateOutlet="paragraphBasedAmendment"></ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- Reason -->
|
<!-- Reason -->
|
||||||
<div *ngIf="motion || editMotion">
|
<div *ngIf="motion.reason || editMotion">
|
||||||
<h5 *ngIf="motion.reason || editMotion" translate>Reason</h5>
|
<h3 translate>Reason</h3>
|
||||||
<div class="motion-text" *ngIf="!editMotion"><div [innerHtml]="motion.reason"></div></div>
|
<div class="motion-text" *ngIf="!editMotion"><div [innerHtml]="motion.reason"></div></div>
|
||||||
|
|
||||||
<!-- The HTML Editor -->
|
<!-- The HTML Editor -->
|
||||||
<editor
|
<editor formControlName="reason" [init]="tinyMceSettings" *ngIf="editMotion"></editor>
|
||||||
formControlName='reason'
|
</div>
|
||||||
[init]="tinyMceSettings"
|
|
||||||
*ngIf="editMotion"
|
<div class="extra-data">
|
||||||
></editor>
|
<!-- Attachments -->
|
||||||
|
<div *ngIf="motion.hasAttachments() || editMotion" class="content-field form100">
|
||||||
|
<div *ngIf="!editMotion">
|
||||||
|
<h4 translate>Attachments</h4>
|
||||||
|
<mat-list dense>
|
||||||
|
<mat-list-item *ngFor="let file of motion.attachments">
|
||||||
|
<a [routerLink]="" (click)="onClickAttacment(file)">{{ file.title }}</a>
|
||||||
|
</mat-list-item>
|
||||||
|
</mat-list>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="editMotion">
|
||||||
|
<os-search-value-selector
|
||||||
|
ngDefaultControl
|
||||||
|
[form]="contentForm"
|
||||||
|
[formControl]="contentForm.get('attachments_id')"
|
||||||
|
[multiple]="true"
|
||||||
|
listname="{{ 'Attachments' | translate }}"
|
||||||
|
[InputListValues]="mediafilesObserver"
|
||||||
|
></os-search-value-selector>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Category form -->
|
||||||
|
<div class="content-field form100" *ngIf="newMotion && categoryObserver.value.length > 0">
|
||||||
|
<os-search-value-selector
|
||||||
|
ngDefaultControl
|
||||||
|
[form]="contentForm"
|
||||||
|
[formControl]="contentForm.get('category_id')"
|
||||||
|
[multiple]="false"
|
||||||
|
[includeNone]="true"
|
||||||
|
listname="{{ 'Category' | translate }}"
|
||||||
|
[InputListValues]="categoryObserver"
|
||||||
|
></os-search-value-selector>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Parent item -->
|
||||||
|
<div class="content-field form100" *ngIf="newMotion && agendaItemObserver.value.length > 0">
|
||||||
|
<os-search-value-selector
|
||||||
|
ngDefaultControl
|
||||||
|
[form]="contentForm"
|
||||||
|
[formControl]="contentForm.get('parent_id')"
|
||||||
|
[multiple]="false"
|
||||||
|
[includeNone]="true"
|
||||||
|
listname="{{ 'Parent Item' | translate }}"
|
||||||
|
[InputListValues]="agendaItemObserver"
|
||||||
|
></os-search-value-selector>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Visibility -->
|
||||||
|
<div class="content-field form100" *ngIf="newMotion">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-select formControlName="agenda_type" placeholder="{{ 'Agenda visibility' | translate }}">
|
||||||
|
<mat-option *ngFor="let type of itemVisibility" [value]="type.key">
|
||||||
|
<span>{{ type.name | translate }}</span>
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Supporter form -->
|
||||||
|
<div class="content-field form100" *ngIf="editMotion && minSupporters">
|
||||||
|
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
||||||
|
<os-search-value-selector
|
||||||
|
ngDefaultControl
|
||||||
|
[form]="contentForm"
|
||||||
|
[formControl]="contentForm.get('supporters_id')"
|
||||||
|
[multiple]="true"
|
||||||
|
listname="{{ 'Supporters' | translate }}"
|
||||||
|
[InputListValues]="supporterObserver"
|
||||||
|
></os-search-value-selector>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Workflow -->
|
||||||
|
<div class="content-field form100" *ngIf="editMotion && workflowObserver.value.length > 1">
|
||||||
|
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
||||||
|
<os-search-value-selector
|
||||||
|
ngDefaultControl
|
||||||
|
[form]="contentForm"
|
||||||
|
[formControl]="contentForm.get('workflow_id')"
|
||||||
|
[multiple]="false"
|
||||||
|
listname="{{ 'Workflow' | translate }}"
|
||||||
|
[InputListValues]="workflowObserver"
|
||||||
|
></os-search-value-selector>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Origin form -->
|
||||||
|
<div class="content-field form100" *ngIf="editMotion">
|
||||||
|
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
||||||
|
<mat-form-field>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
placeholder="{{ 'Origin' | translate }}"
|
||||||
|
formControlName="origin"
|
||||||
|
[value]="motionCopy.origin"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
@ -522,9 +600,15 @@
|
|||||||
<!-- 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 }">none</button>
|
<button mat-menu-item translate (click)="setLineNumberingMode(0)" [ngClass]="{ selected: motion.lnMode === 0 }">
|
||||||
<button mat-menu-item translate (click)=setLineNumberingMode(1) [ngClass]="{ 'selected': motion.lnMode === 1 }">inline</button>
|
none
|
||||||
<button mat-menu-item translate (click)=setLineNumberingMode(2) [ngClass]="{ 'selected': motion.lnMode === 2 }">outside</button>
|
</button>
|
||||||
|
<button mat-menu-item translate (click)="setLineNumberingMode(1)" [ngClass]="{ selected: motion.lnMode === 1 }">
|
||||||
|
inline
|
||||||
|
</button>
|
||||||
|
<button mat-menu-item translate (click)="setLineNumberingMode(2)" [ngClass]="{ selected: motion.lnMode === 2 }">
|
||||||
|
outside
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ span {
|
|||||||
line-height: 180%;
|
line-height: 180%;
|
||||||
font-size: 120%;
|
font-size: 120%;
|
||||||
color: #317796; // TODO: put in theme as $primary
|
color: #317796; // TODO: put in theme as $primary
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
@ -41,58 +40,6 @@ span {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.motion-submitter {
|
|
||||||
display: inline;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.meta-info-block {
|
|
||||||
form {
|
|
||||||
div + div {
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
display: block;
|
|
||||||
// padding-top: 0;
|
|
||||||
margin-top: 0px; //distance between heading and text
|
|
||||||
margin-bottom: 3px; //distance between heading and text
|
|
||||||
font-size: 80%;
|
|
||||||
color: gray;
|
|
||||||
|
|
||||||
mat-icon {
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mat-form-field-label {
|
|
||||||
font-size: 12pt;
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mat-form-field-label-wrapper {
|
|
||||||
mat-icon {
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.wide-form {
|
|
||||||
textarea {
|
|
||||||
height: 25vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.meta-info-panel {
|
.meta-info-panel {
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
|
|
||||||
@ -143,6 +90,45 @@ span {
|
|||||||
display: block;
|
display: block;
|
||||||
margin: 0 10px 7px 0px;
|
margin: 0 10px 7px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.extra-data {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-field {
|
||||||
|
display: inline-block;
|
||||||
|
::ng-deep {
|
||||||
|
.mat-form-field {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form100 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form70 {
|
||||||
|
width: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form30 {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-id-title {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.form-identifier {
|
||||||
|
flex: 0 0 95px;
|
||||||
|
max-width: 95px;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-title {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.desktop-view {
|
.desktop-view {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { DomSanitizer, SafeHtml, Title } from '@angular/platform-browser';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
import { MatDialog, MatExpansionPanel, MatSnackBar, MatCheckboxChange } from '@angular/material';
|
import { MatDialog, MatExpansionPanel, MatSnackBar, MatCheckboxChange } from '@angular/material';
|
||||||
|
import { take, takeWhile, multicast, skipWhile } from 'rxjs/operators';
|
||||||
|
|
||||||
import { Category } from '../../../../shared/models/motions/category';
|
import { Category } from '../../../../shared/models/motions/category';
|
||||||
import { ViewportService } from '../../../../core/services/viewport.service';
|
import { ViewportService } from '../../../../core/services/viewport.service';
|
||||||
@ -19,7 +21,7 @@ import {
|
|||||||
} from '../motion-change-recommendation/motion-change-recommendation.component';
|
} from '../motion-change-recommendation/motion-change-recommendation.component';
|
||||||
import { ChangeRecommendationRepositoryService } from '../../services/change-recommendation-repository.service';
|
import { ChangeRecommendationRepositoryService } from '../../services/change-recommendation-repository.service';
|
||||||
import { ViewChangeReco } from '../../models/view-change-reco';
|
import { ViewChangeReco } from '../../models/view-change-reco';
|
||||||
import { DomSanitizer, SafeHtml, Title } from '@angular/platform-browser';
|
|
||||||
import { ViewUnifiedChange } from '../../models/view-unified-change';
|
import { ViewUnifiedChange } from '../../models/view-unified-change';
|
||||||
import { OperatorService } from '../../../../core/services/operator.service';
|
import { OperatorService } from '../../../../core/services/operator.service';
|
||||||
import { BaseViewComponent } from '../../../base/base-view';
|
import { BaseViewComponent } from '../../../base/base-view';
|
||||||
@ -27,11 +29,14 @@ import { ViewStatuteParagraph } from '../../models/view-statute-paragraph';
|
|||||||
import { StatuteParagraphRepositoryService } from '../../services/statute-paragraph-repository.service';
|
import { StatuteParagraphRepositoryService } from '../../services/statute-paragraph-repository.service';
|
||||||
import { ConfigService } from '../../../../core/services/config.service';
|
import { ConfigService } from '../../../../core/services/config.service';
|
||||||
import { Workflow } from 'app/shared/models/motions/workflow';
|
import { Workflow } from 'app/shared/models/motions/workflow';
|
||||||
import { take, takeWhile, multicast, skipWhile } from 'rxjs/operators';
|
|
||||||
import { LocalPermissionsService } from '../../services/local-permissions.service';
|
import { LocalPermissionsService } from '../../services/local-permissions.service';
|
||||||
import { ViewCreateMotion } from '../../models/view-create-motion';
|
import { ViewCreateMotion } from '../../models/view-create-motion';
|
||||||
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 { itemVisibilityChoices, Item } from 'app/shared/models/agenda/item';
|
||||||
|
import { PromptService } from 'app/core/services/prompt.service';
|
||||||
|
import { AgendaRepositoryService } from 'app/site/agenda/services/agenda-repository.service';
|
||||||
|
import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component for the motion detail view
|
* Component for the motion detail view
|
||||||
@ -56,11 +61,6 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
@ViewChild('contentPanel')
|
@ViewChild('contentPanel')
|
||||||
public contentPanel: MatExpansionPanel;
|
public contentPanel: MatExpansionPanel;
|
||||||
|
|
||||||
/**
|
|
||||||
* Motions meta-info
|
|
||||||
*/
|
|
||||||
public metaInfoForm: FormGroup;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Motion content. Can be a new version
|
* Motion content. Can be a new version
|
||||||
*/
|
*/
|
||||||
@ -184,6 +184,16 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
public blockObserver: BehaviorSubject<MotionBlock[]>;
|
public blockObserver: BehaviorSubject<MotionBlock[]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subject for mediafiles
|
||||||
|
*/
|
||||||
|
public mediafilesObserver: BehaviorSubject<Mediafile[]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subject for agenda items
|
||||||
|
*/
|
||||||
|
public agendaItemObserver: BehaviorSubject<Item[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the name of supporters are visible
|
* Determine if the name of supporters are visible
|
||||||
*/
|
*/
|
||||||
@ -209,6 +219,16 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
public showAmendmentContext = false;
|
public showAmendmentContext = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the default agenda item visibility
|
||||||
|
*/
|
||||||
|
public defaultVisibility: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine visibility states for the agenda that will be created implicitly
|
||||||
|
*/
|
||||||
|
public itemVisibility = itemVisibilityChoices;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constuct the detail view.
|
* Constuct the detail view.
|
||||||
*
|
*
|
||||||
@ -222,11 +242,13 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
* @param formBuilder For reactive forms. Form Group and Form Control
|
* @param formBuilder For reactive forms. Form Group and Form Control
|
||||||
* @param dialogService For opening dialogs
|
* @param dialogService For opening dialogs
|
||||||
* @param repo Motion Repository
|
* @param repo Motion Repository
|
||||||
|
* @param agendaRepo Read out agenda variables
|
||||||
* @param changeRecoRepo Change Recommendation Repository
|
* @param changeRecoRepo Change Recommendation Repository
|
||||||
* @param statuteRepo: Statute Paragraph Repository
|
* @param statuteRepo: Statute Paragraph Repository
|
||||||
* @param DS The DataStoreService
|
* @param DS The DataStoreService
|
||||||
* @param configService The configuration provider
|
* @param configService The configuration provider
|
||||||
* @param sanitizer For making HTML SafeHTML
|
* @param sanitizer For making HTML SafeHTML
|
||||||
|
* @param promptService ensure safe deletion
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
title: Title,
|
title: Title,
|
||||||
@ -240,15 +262,15 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private dialogService: MatDialog,
|
private dialogService: MatDialog,
|
||||||
private repo: MotionRepositoryService,
|
private repo: MotionRepositoryService,
|
||||||
|
private agendaRepo: AgendaRepositoryService,
|
||||||
private changeRecoRepo: ChangeRecommendationRepositoryService,
|
private changeRecoRepo: ChangeRecommendationRepositoryService,
|
||||||
private statuteRepo: StatuteParagraphRepositoryService,
|
private statuteRepo: StatuteParagraphRepositoryService,
|
||||||
private DS: DataStoreService,
|
private DS: DataStoreService,
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
private sanitizer: DomSanitizer
|
private sanitizer: DomSanitizer,
|
||||||
|
private promptService: PromptService
|
||||||
) {
|
) {
|
||||||
super(title, translate, matSnackBar);
|
super(title, translate, matSnackBar);
|
||||||
this.createForm();
|
|
||||||
this.getMotionByUrl();
|
|
||||||
|
|
||||||
// Initial Filling of the Subjects
|
// Initial Filling of the Subjects
|
||||||
this.submitterObserver = new BehaviorSubject(DS.getAll(User));
|
this.submitterObserver = new BehaviorSubject(DS.getAll(User));
|
||||||
@ -256,6 +278,8 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
this.categoryObserver = new BehaviorSubject(DS.getAll(Category));
|
this.categoryObserver = new BehaviorSubject(DS.getAll(Category));
|
||||||
this.workflowObserver = new BehaviorSubject(DS.getAll(Workflow));
|
this.workflowObserver = new BehaviorSubject(DS.getAll(Workflow));
|
||||||
this.blockObserver = new BehaviorSubject(DS.getAll(MotionBlock));
|
this.blockObserver = new BehaviorSubject(DS.getAll(MotionBlock));
|
||||||
|
this.mediafilesObserver = new BehaviorSubject(DS.getAll(Mediafile));
|
||||||
|
this.agendaItemObserver = new BehaviorSubject(DS.getAll(Item));
|
||||||
|
|
||||||
// Make sure the subjects are updated, when a new Model for the type arrives
|
// Make sure the subjects are updated, when a new Model for the type arrives
|
||||||
this.DS.changeObservable.subscribe(newModel => {
|
this.DS.changeObservable.subscribe(newModel => {
|
||||||
@ -268,8 +292,13 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
this.workflowObserver.next(DS.getAll(Workflow));
|
this.workflowObserver.next(DS.getAll(Workflow));
|
||||||
} else if (newModel instanceof MotionBlock) {
|
} else if (newModel instanceof MotionBlock) {
|
||||||
this.blockObserver.next(DS.getAll(MotionBlock));
|
this.blockObserver.next(DS.getAll(MotionBlock));
|
||||||
|
} else if (newModel instanceof Mediafile) {
|
||||||
|
this.mediafilesObserver.next(DS.getAll(Mediafile));
|
||||||
|
} else if (newModel instanceof Item) {
|
||||||
|
this.agendaItemObserver.next(DS.getAll(Item));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// load config variables
|
// load config variables
|
||||||
this.configService.get('motions_statutes_enabled').subscribe(enabled => (this.statutesEnabled = enabled));
|
this.configService.get('motions_statutes_enabled').subscribe(enabled => (this.statutesEnabled = enabled));
|
||||||
this.configService.get('motions_min_supporters').subscribe(supporters => (this.minSupporters = supporters));
|
this.configService.get('motions_min_supporters').subscribe(supporters => (this.minSupporters = supporters));
|
||||||
@ -277,6 +306,45 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
this.configService.get('motions_amendments_enabled').subscribe(enabled => (this.amendmentsEnabled = enabled));
|
this.configService.get('motions_amendments_enabled').subscribe(enabled => (this.amendmentsEnabled = enabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init.
|
||||||
|
* Sets the surrounding motions to navigate back and forth
|
||||||
|
*/
|
||||||
|
public ngOnInit(): void {
|
||||||
|
this.createForm();
|
||||||
|
this.getMotionByUrl();
|
||||||
|
|
||||||
|
this.repo.getViewModelListObservable().subscribe(newMotionList => {
|
||||||
|
if (newMotionList) {
|
||||||
|
this.allMotions = newMotionList;
|
||||||
|
this.setSurroundingMotions();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.statuteRepo.getViewModelListObservable().subscribe(newViewStatuteParagraphs => {
|
||||||
|
this.statuteParagraphs = newViewStatuteParagraphs;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set the default visibility using observers
|
||||||
|
this.agendaRepo.getDefaultAgendaVisibility().subscribe(visibility => {
|
||||||
|
if (visibility && this.newMotion) {
|
||||||
|
this.contentForm.get('agenda_type').setValue(visibility);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// disable the selector for attachments if there are none
|
||||||
|
this.mediafilesObserver.subscribe(files => {
|
||||||
|
if (this.createForm) {
|
||||||
|
const attachmentsCtrl = this.contentForm.get('attachments_id');
|
||||||
|
if (this.mediafilesObserver.value.length === 0) {
|
||||||
|
attachmentsCtrl.disable();
|
||||||
|
} else {
|
||||||
|
attachmentsCtrl.enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges amendments and change recommendations and sorts them by the line numbers.
|
* Merges amendments and change recommendations and sorts them by the line numbers.
|
||||||
* Called each time one of these arrays changes.
|
* Called each time one of these arrays changes.
|
||||||
@ -350,12 +418,6 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
* Async load the values of the motion in the Form.
|
* Async load the values of the motion in the Form.
|
||||||
*/
|
*/
|
||||||
public patchForm(formMotion: ViewMotion): void {
|
public patchForm(formMotion: ViewMotion): void {
|
||||||
const metaInfoPatch = {};
|
|
||||||
Object.keys(this.metaInfoForm.controls).forEach(ctrl => {
|
|
||||||
metaInfoPatch[ctrl] = formMotion[ctrl];
|
|
||||||
});
|
|
||||||
this.metaInfoForm.patchValue(metaInfoPatch);
|
|
||||||
|
|
||||||
const contentPatch: { [key: string]: any } = {};
|
const contentPatch: { [key: string]: any } = {};
|
||||||
Object.keys(this.contentForm.controls).forEach(ctrl => {
|
Object.keys(this.contentForm.controls).forEach(ctrl => {
|
||||||
contentPatch[ctrl] = formMotion[ctrl];
|
contentPatch[ctrl] = formMotion[ctrl];
|
||||||
@ -380,20 +442,19 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
* TODO: Build a custom form validator
|
* TODO: Build a custom form validator
|
||||||
*/
|
*/
|
||||||
public createForm(): void {
|
public createForm(): void {
|
||||||
this.metaInfoForm = this.formBuilder.group({
|
|
||||||
identifier: [''],
|
|
||||||
category_id: [''],
|
|
||||||
state_id: [''],
|
|
||||||
recommendation_id: [''],
|
|
||||||
submitters_id: [],
|
|
||||||
supporters_id: [[]],
|
|
||||||
workflow_id: [],
|
|
||||||
origin: ['']
|
|
||||||
});
|
|
||||||
this.contentForm = this.formBuilder.group({
|
this.contentForm = this.formBuilder.group({
|
||||||
|
identifier: [''],
|
||||||
title: ['', Validators.required],
|
title: ['', Validators.required],
|
||||||
text: ['', Validators.required],
|
text: ['', Validators.required],
|
||||||
reason: [''],
|
reason: [''],
|
||||||
|
category_id: [''],
|
||||||
|
attachments_id: [[]],
|
||||||
|
parent_id: [],
|
||||||
|
agenda_type: [''],
|
||||||
|
submitters_id: [],
|
||||||
|
supporters_id: [[]],
|
||||||
|
workflow_id: [],
|
||||||
|
origin: [''],
|
||||||
statute_amendment: [''], // Internal value for the checkbox, not saved to the model
|
statute_amendment: [''], // Internal value for the checkbox, not saved to the model
|
||||||
statute_paragraph_id: ['']
|
statute_paragraph_id: ['']
|
||||||
});
|
});
|
||||||
@ -417,6 +478,8 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
*
|
*
|
||||||
* @param motionValues valus for the new motion
|
* @param motionValues valus for the new motion
|
||||||
* @param ctor The motion constructor, so different motion types can be created.
|
* @param ctor The motion constructor, so different motion types can be created.
|
||||||
|
*
|
||||||
|
* @returns the motion to save
|
||||||
*/
|
*/
|
||||||
private prepareMotionForSave<T extends Motion>(motionValues: any, ctor: new (...args: any[]) => T): T {
|
private prepareMotionForSave<T extends Motion>(motionValues: any, ctor: new (...args: any[]) => T): T {
|
||||||
const motion = new ctor();
|
const motion = new ctor();
|
||||||
@ -440,7 +503,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
* Creates a motion. Calls the "patchValues" function in the MotionObject
|
* Creates a motion. Calls the "patchValues" function in the MotionObject
|
||||||
*/
|
*/
|
||||||
public async createMotion(): Promise<void> {
|
public async createMotion(): Promise<void> {
|
||||||
const newMotionValues = { ...this.metaInfoForm.value, ...this.contentForm.value };
|
const newMotionValues = { ...this.contentForm.value };
|
||||||
const motion = this.prepareMotionForSave(newMotionValues, CreateMotion);
|
const motion = this.prepareMotionForSave(newMotionValues, CreateMotion);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -455,7 +518,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
* Save a motion. Calls the "patchValues" function in the MotionObject
|
* Save a motion. Calls the "patchValues" function in the MotionObject
|
||||||
*/
|
*/
|
||||||
public async updateMotion(): Promise<void> {
|
public async updateMotion(): Promise<void> {
|
||||||
const newMotionValues = { ...this.metaInfoForm.value, ...this.contentForm.value };
|
const newMotionValues = { ...this.contentForm.value };
|
||||||
const motion = this.prepareMotionForSave(newMotionValues, Motion);
|
const motion = this.prepareMotionForSave(newMotionValues, Motion);
|
||||||
this.repo.update(motion, this.motionCopy).then(() => (this.editMotion = false), this.raiseError);
|
this.repo.update(motion, this.motionCopy).then(() => (this.editMotion = false), this.raiseError);
|
||||||
}
|
}
|
||||||
@ -473,6 +536,8 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* get the formated motion text from the repository.
|
* get the formated motion text from the repository.
|
||||||
|
*
|
||||||
|
* @returns formated motion texts
|
||||||
*/
|
*/
|
||||||
public getFormattedTextPlain(): string {
|
public getFormattedTextPlain(): string {
|
||||||
// Prevent this.allChangingObjects to be reordered from within formatMotion
|
// Prevent this.allChangingObjects to be reordered from within formatMotion
|
||||||
@ -510,9 +575,9 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
* If `this.motion` is an amendment, this returns a specified line range from the parent motion
|
* If `this.motion` is an amendment, this returns a specified line range from the parent motion
|
||||||
* (e.g. to show the contect in which this amendment is happening)
|
* (e.g. to show the contect in which this amendment is happening)
|
||||||
*
|
*
|
||||||
* @param {number} from
|
* @param from the line number to start
|
||||||
* @param {number} to
|
* @param to the line number to stop
|
||||||
* @returns {SafeHtml}
|
* @returns safe html strings
|
||||||
*/
|
*/
|
||||||
public getParentMotionRange(from: number, to: number): SafeHtml {
|
public getParentMotionRange(from: number, to: number): SafeHtml {
|
||||||
const str = this.repo.extractMotionLineRange(this.motion.parent_id, { from, to }, true);
|
const str = this.repo.extractMotionLineRange(this.motion.parent_id, { from, to }, true);
|
||||||
@ -521,7 +586,8 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* get the diff html from the statute amendment, as SafeHTML for [innerHTML]
|
* get the diff html from the statute amendment, as SafeHTML for [innerHTML]
|
||||||
* @returns {SafeHtml}
|
*
|
||||||
|
* @returns safe html strings
|
||||||
*/
|
*/
|
||||||
public getFormattedStatuteAmendment(): SafeHtml {
|
public getFormattedStatuteAmendment(): SafeHtml {
|
||||||
const diffHtml = this.repo.formatStatuteAmendment(this.statuteParagraphs, this.motion, this.motion.lineLength);
|
const diffHtml = this.repo.formatStatuteAmendment(this.statuteParagraphs, this.motion, this.motion.lineLength);
|
||||||
@ -530,17 +596,18 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger to delete the motion.
|
* Trigger to delete the motion.
|
||||||
* Sends a delete request over the repository and
|
|
||||||
* shows a "are you sure" dialog
|
|
||||||
*/
|
*/
|
||||||
public async deleteMotionButton(): Promise<void> {
|
public async deleteMotionButton(): Promise<void> {
|
||||||
this.repo.delete(this.motion).then(() => {
|
const content = this.translate.instant('Are you sure you want to delete this motion block?');
|
||||||
|
if (await this.promptService.open(this.motion.title, content)) {
|
||||||
|
await this.repo.delete(this.motion);
|
||||||
this.router.navigate(['./motions/']);
|
this.router.navigate(['./motions/']);
|
||||||
}, this.raiseError);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the motions line numbering mode
|
* Sets the motions line numbering mode
|
||||||
|
*
|
||||||
* @param mode Needs to got the enum defined in ViewMotion
|
* @param mode Needs to got the enum defined in ViewMotion
|
||||||
*/
|
*/
|
||||||
public setLineNumberingMode(mode: LineNumberingMode): void {
|
public setLineNumberingMode(mode: LineNumberingMode): void {
|
||||||
@ -549,6 +616,8 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if no line numbers are to be shown.
|
* Returns true if no line numbers are to be shown.
|
||||||
|
*
|
||||||
|
* @returns whether there are line numbers at all
|
||||||
*/
|
*/
|
||||||
public isLineNumberingNone(): boolean {
|
public isLineNumberingNone(): boolean {
|
||||||
return this.motion.lnMode === LineNumberingMode.None;
|
return this.motion.lnMode === LineNumberingMode.None;
|
||||||
@ -556,6 +625,8 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the line numbers are to be shown within the text with no line breaks.
|
* 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 {
|
public isLineNumberingInline(): boolean {
|
||||||
return this.motion.lnMode === LineNumberingMode.Inside;
|
return this.motion.lnMode === LineNumberingMode.Inside;
|
||||||
@ -563,6 +634,8 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the line numbers are to be shown to the left of the text.
|
* 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 {
|
public isLineNumberingOutside(): boolean {
|
||||||
return this.motion.lnMode === LineNumberingMode.Outside;
|
return this.motion.lnMode === LineNumberingMode.Outside;
|
||||||
@ -627,6 +700,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Comes from the head bar
|
* Comes from the head bar
|
||||||
|
*
|
||||||
* @param mode
|
* @param mode
|
||||||
*/
|
*/
|
||||||
public setEditMode(mode: boolean): void {
|
public setEditMode(mode: boolean): void {
|
||||||
@ -644,6 +718,9 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the default workflow ID during form creation
|
||||||
|
*/
|
||||||
public updateWorkflowIdForCreateForm(): void {
|
public updateWorkflowIdForCreateForm(): void {
|
||||||
const isStatuteAmendment = !!this.contentForm.get('statute_amendment').value;
|
const isStatuteAmendment = !!this.contentForm.get('statute_amendment').value;
|
||||||
const configKey = isStatuteAmendment ? 'motions_statute_amendments_workflow' : 'motions_workflow';
|
const configKey = isStatuteAmendment ? 'motions_statute_amendments_workflow' : 'motions_workflow';
|
||||||
@ -663,7 +740,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
skipWhile(id => !id)
|
skipWhile(id => !id)
|
||||||
)
|
)
|
||||||
.subscribe(id => {
|
.subscribe(id => {
|
||||||
this.metaInfoForm.patchValue({
|
this.contentForm.patchValue({
|
||||||
workflow_id: parseInt(id, 10)
|
workflow_id: parseInt(id, 10)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -671,6 +748,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* If the checkbox is deactivated, the statute_paragraph_id-field needs to be reset, as only that field is saved
|
* If the checkbox is deactivated, the statute_paragraph_id-field needs to be reset, as only that field is saved
|
||||||
|
*
|
||||||
* @param {MatCheckboxChange} $event
|
* @param {MatCheckboxChange} $event
|
||||||
*/
|
*/
|
||||||
public onStatuteAmendmentChange($event: MatCheckboxChange): void {
|
public onStatuteAmendmentChange($event: MatCheckboxChange): void {
|
||||||
@ -682,6 +760,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The paragraph of the statute to amend was changed -> change the input fields below
|
* The paragraph of the statute to amend was changed -> change the input fields below
|
||||||
|
*
|
||||||
* @param {number} newValue
|
* @param {number} newValue
|
||||||
*/
|
*/
|
||||||
public onStatuteParagraphChange(newValue: number): void {
|
public onStatuteParagraphChange(newValue: number): void {
|
||||||
@ -694,6 +773,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigates the user to the given ViewMotion
|
* Navigates the user to the given ViewMotion
|
||||||
|
*
|
||||||
* @param motion target
|
* @param motion target
|
||||||
*/
|
*/
|
||||||
public navigateToMotion(motion: ViewMotion): void {
|
public navigateToMotion(motion: ViewMotion): void {
|
||||||
@ -749,6 +829,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the state
|
* Sets the state
|
||||||
|
*
|
||||||
* @param id Motion state id
|
* @param id Motion state id
|
||||||
*/
|
*/
|
||||||
public setState(id: number): void {
|
public setState(id: number): void {
|
||||||
@ -757,6 +838,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the recommendation
|
* Sets the recommendation
|
||||||
|
*
|
||||||
* @param id Motion recommendation id
|
* @param id Motion recommendation id
|
||||||
*/
|
*/
|
||||||
public setRecommendation(id: number): void {
|
public setRecommendation(id: number): void {
|
||||||
@ -765,6 +847,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the category for current motion
|
* Sets the category for current motion
|
||||||
|
*
|
||||||
* @param id Motion category id
|
* @param id Motion category id
|
||||||
*/
|
*/
|
||||||
public setCategory(id: number): void {
|
public setCategory(id: number): void {
|
||||||
@ -797,32 +880,29 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the absolute path to the corresponding list of speakers
|
* Create the absolute path to the corresponding list of speakers
|
||||||
|
*
|
||||||
* @returns the link to the corresponding list of speakers as string
|
* @returns the link to the corresponding list of speakers as string
|
||||||
*/
|
*/
|
||||||
public getSpeakerLink(): string {
|
public getSpeakerLink(): string {
|
||||||
return `/agenda/${this.motion.agenda_item_id}/speakers`;
|
return `/agenda/${this.motion.agenda_item_id}/speakers`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Click handler for attachments
|
||||||
|
*
|
||||||
|
* @param attachment the selected file
|
||||||
|
*/
|
||||||
|
public onClickAttacment(attachment: Mediafile): void {
|
||||||
|
window.open(attachment.getDownloadUrl());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the user has the correct requirements to alter the motion
|
* Determine if the user has the correct requirements to alter the motion
|
||||||
|
* TODO: All views should probably have a "isAllowedTo" routine to simplify this process
|
||||||
|
*
|
||||||
|
* @returns whether or not the OP is allowed to edit the motion
|
||||||
*/
|
*/
|
||||||
public opCanEdit(): boolean {
|
public opCanEdit(): boolean {
|
||||||
return this.op.hasPerms('motions.can_manage', 'motions.can_manage_metadata');
|
return this.op.hasPerms('motions.can_manage', 'motions.can_manage_metadata');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Init.
|
|
||||||
* Sets the surrounding motions to navigate back and forth
|
|
||||||
*/
|
|
||||||
public ngOnInit(): void {
|
|
||||||
this.repo.getViewModelListObservable().subscribe(newMotionList => {
|
|
||||||
if (newMotionList) {
|
|
||||||
this.allMotions = newMotionList;
|
|
||||||
this.setSurroundingMotions();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.statuteRepo.getViewModelListObservable().subscribe(newViewStatuteParagraphs => {
|
|
||||||
this.statuteParagraphs = newViewStatuteParagraphs;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -41,13 +41,21 @@
|
|||||||
<mat-header-cell *matHeaderCellDef mat-sort-header>Title</mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header>Title</mat-header-cell>
|
||||||
<mat-cell *matCellDef="let motion">
|
<mat-cell *matCellDef="let motion">
|
||||||
<div class="innerTable">
|
<div class="innerTable">
|
||||||
<span class="motion-list-title">{{ motion.title }}</span> <br />
|
<span class="motion-list-title">{{ motion.title }}</span>
|
||||||
|
<!-- attachments -->
|
||||||
|
<span class="attached-files" *ngIf="motion.hasAttachments()">
|
||||||
|
<!-- <mat-basic-chip class="bluegrey"> <mat-icon>attach_file</mat-icon> </mat-basic-chip> -->
|
||||||
|
<mat-icon>attach_file</mat-icon>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<br />
|
||||||
<span class="motion-list-from" *ngIf="motion.submitters.length">
|
<span class="motion-list-from" *ngIf="motion.submitters.length">
|
||||||
<span translate>by</span> {{ motion.submitters }}
|
<span translate>by</span> {{ motion.submitters }}
|
||||||
</span>
|
</span>
|
||||||
<br *ngIf="motion.submitters.length" />
|
<br *ngIf="motion.submitters.length" />
|
||||||
<!-- state -->
|
<!-- state -->
|
||||||
<mat-basic-chip
|
<mat-basic-chip
|
||||||
|
*ngIf="motion.state"
|
||||||
[ngClass]="{
|
[ngClass]="{
|
||||||
green: motion.state.css_class === 'success',
|
green: motion.state.css_class === 'success',
|
||||||
red: motion.state.css_class === 'danger',
|
red: motion.state.css_class === 'danger',
|
||||||
|
@ -30,6 +30,17 @@
|
|||||||
color: rgba(0, 0, 0, 0.5);
|
color: rgba(0, 0, 0, 0.5);
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.attached-files {
|
||||||
|
.mat-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
vertical-align: middle;
|
||||||
|
$icon-size: 16px;
|
||||||
|
font-size: $icon-size;
|
||||||
|
height: $icon-size;
|
||||||
|
width: $icon-size;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** State */
|
/** State */
|
||||||
|
@ -9,6 +9,7 @@ import { ViewMotionCommentSection } from './view-motion-comment-section';
|
|||||||
import { MotionComment } from '../../../shared/models/motions/motion-comment';
|
import { MotionComment } from '../../../shared/models/motions/motion-comment';
|
||||||
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 { Mediafile } from 'app/shared/models/mediafiles/mediafile';
|
||||||
|
|
||||||
export enum LineNumberingMode {
|
export enum LineNumberingMode {
|
||||||
None,
|
None,
|
||||||
@ -39,6 +40,7 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
protected _state: WorkflowState;
|
protected _state: WorkflowState;
|
||||||
protected _item: Item;
|
protected _item: Item;
|
||||||
protected _block: MotionBlock;
|
protected _block: MotionBlock;
|
||||||
|
protected _attachments: Mediafile[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates the LineNumberingMode Mode.
|
* Indicates the LineNumberingMode Mode.
|
||||||
@ -79,7 +81,7 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get identifier(): string {
|
public get identifier(): string {
|
||||||
return this.motion ? this.motion.identifier : null;
|
return this.motion && this.motion.identifier ? this.motion.identifier : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get title(): string {
|
public get title(): string {
|
||||||
@ -188,6 +190,10 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
return this._item;
|
return this._item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get agenda_type(): number {
|
||||||
|
return this.item ? this.item.type : null;
|
||||||
|
}
|
||||||
|
|
||||||
public get motion_block_id(): number {
|
public get motion_block_id(): number {
|
||||||
return this.motion ? this.motion.motion_block_id : null;
|
return this.motion ? this.motion.motion_block_id : null;
|
||||||
}
|
}
|
||||||
@ -209,7 +215,15 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get tags_id(): number[] {
|
public get tags_id(): number[] {
|
||||||
return this._motion ? this._motion.tags_id : null;
|
return this.motion ? this.motion.tags_id : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get attachments_id(): number[] {
|
||||||
|
return this.motion ? this.motion.attachments_id : null
|
||||||
|
}
|
||||||
|
|
||||||
|
public get attachments(): Mediafile[] {
|
||||||
|
return this._attachments ? this._attachments : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
@ -220,10 +234,10 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
workflow?: Workflow,
|
workflow?: Workflow,
|
||||||
state?: WorkflowState,
|
state?: WorkflowState,
|
||||||
item?: Item,
|
item?: Item,
|
||||||
block?: MotionBlock
|
block?: MotionBlock,
|
||||||
|
attachments?: Mediafile[],
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this._motion = motion;
|
this._motion = motion;
|
||||||
this._category = category;
|
this._category = category;
|
||||||
this._submitters = submitters;
|
this._submitters = submitters;
|
||||||
@ -232,6 +246,7 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
this._state = state;
|
this._state = state;
|
||||||
this._item = item;
|
this._item = item;
|
||||||
this._block = block;
|
this._block = block;
|
||||||
|
this._attachments = attachments;
|
||||||
|
|
||||||
// TODO: Should be set using a a config variable
|
// TODO: Should be set using a a config variable
|
||||||
/*this._configService.get('motions_default_line_numbering').subscribe(
|
/*this._configService.get('motions_default_line_numbering').subscribe(
|
||||||
@ -255,6 +270,7 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the motion comment for the given section. Null, if no comment exist.
|
* Returns the motion comment for the given section. Null, if no comment exist.
|
||||||
|
*
|
||||||
* @param section The section to search the comment for.
|
* @param section The section to search the comment for.
|
||||||
*/
|
*/
|
||||||
public getCommentForSection(section: ViewMotionCommentSection): MotionComment {
|
public getCommentForSection(section: ViewMotionCommentSection): MotionComment {
|
||||||
@ -266,6 +282,7 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the local objects if required
|
* Updates the local objects if required
|
||||||
|
*
|
||||||
* @param update
|
* @param update
|
||||||
*/
|
*/
|
||||||
public updateValues(update: BaseModel): void {
|
public updateValues(update: BaseModel): void {
|
||||||
@ -279,11 +296,14 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
this.updateMotionBlock(update);
|
this.updateMotionBlock(update);
|
||||||
} else if (update instanceof User) {
|
} else if (update instanceof User) {
|
||||||
this.updateUser(update as User);
|
this.updateUser(update as User);
|
||||||
|
} else if (update instanceof Mediafile) {
|
||||||
|
this.updateAttachments(update as Mediafile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update routine for the category
|
* Update routine for the category
|
||||||
|
*
|
||||||
* @param category potentially the changed category. Needs manual verification
|
* @param category potentially the changed category. Needs manual verification
|
||||||
*/
|
*/
|
||||||
public updateCategory(category: Category): void {
|
public updateCategory(category: Category): void {
|
||||||
@ -294,6 +314,7 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update routine for the workflow
|
* Update routine for the workflow
|
||||||
|
*
|
||||||
* @param workflow potentially the changed workflow (state). Needs manual verification
|
* @param workflow potentially the changed workflow (state). Needs manual verification
|
||||||
*/
|
*/
|
||||||
public updateWorkflow(workflow: Workflow): void {
|
public updateWorkflow(workflow: Workflow): void {
|
||||||
@ -304,6 +325,7 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update routine for the agenda Item
|
* Update routine for the agenda Item
|
||||||
|
*
|
||||||
* @param item potentially the changed agenda Item. Needs manual verification
|
* @param item potentially the changed agenda Item. Needs manual verification
|
||||||
*/
|
*/
|
||||||
public updateItem(item: Item): void {
|
public updateItem(item: Item): void {
|
||||||
@ -314,6 +336,7 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update routine for the motion block
|
* Update routine for the motion block
|
||||||
|
*
|
||||||
* @param block potentially the changed motion block. Needs manual verification
|
* @param block potentially the changed motion block. Needs manual verification
|
||||||
*/
|
*/
|
||||||
public updateMotionBlock(block: MotionBlock): void {
|
public updateMotionBlock(block: MotionBlock): void {
|
||||||
@ -323,7 +346,8 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update routine for the agenda Item
|
* Update routine for supporters and submitters
|
||||||
|
*
|
||||||
* @param update potentially the changed agenda Item. Needs manual verification
|
* @param update potentially the changed agenda Item. Needs manual verification
|
||||||
*/
|
*/
|
||||||
public updateUser(update: User): void {
|
public updateUser(update: User): void {
|
||||||
@ -339,10 +363,28 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update routine for attachments
|
||||||
|
*
|
||||||
|
* @param update
|
||||||
|
*/
|
||||||
|
public updateAttachments(update: Mediafile): void {
|
||||||
|
if (this.motion) {
|
||||||
|
if (this.attachments_id && this.attachments_id.includes(update.id)) {
|
||||||
|
const attachmentIndex = this.attachments.findIndex(mediafile => mediafile.id === update.id);
|
||||||
|
this.attachments[attachmentIndex] = update as Mediafile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public hasSupporters(): boolean {
|
public hasSupporters(): boolean {
|
||||||
return !!(this.supporters && this.supporters.length > 0);
|
return !!(this.supporters && this.supporters.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public hasAttachments(): boolean {
|
||||||
|
return !!(this.attachments && this.attachments.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
public isStatuteAmendment(): boolean {
|
public isStatuteAmendment(): boolean {
|
||||||
return !!this.statute_paragraph_id;
|
return !!this.statute_paragraph_id;
|
||||||
}
|
}
|
||||||
@ -372,7 +414,10 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
this._submitters,
|
this._submitters,
|
||||||
this._supporters,
|
this._supporters,
|
||||||
this._workflow,
|
this._workflow,
|
||||||
this._state
|
this._state,
|
||||||
|
this._item,
|
||||||
|
this._block,
|
||||||
|
this._attachments
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import { ViewMotion } from '../models/view-motion';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { MotionRepositoryService } from './motion-repository.service';
|
import { MotionRepositoryService } from './motion-repository.service';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { ConfigService } from 'app/core/services/config.service';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository service for motion blocks
|
* Repository service for motion blocks
|
||||||
@ -28,14 +27,12 @@ export class MotionBlockRepositoryService extends BaseRepository<ViewMotionBlock
|
|||||||
* @param mapperService Mapping collection strings to classes
|
* @param mapperService Mapping collection strings to classes
|
||||||
* @param dataSend Send models to the server
|
* @param dataSend Send models to the server
|
||||||
* @param motionRepo Accessing the motion repository
|
* @param motionRepo Accessing the motion repository
|
||||||
* @param config To access config variables
|
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
DS: DataStoreService,
|
DS: DataStoreService,
|
||||||
mapperService: CollectionStringModelMapperService,
|
mapperService: CollectionStringModelMapperService,
|
||||||
private dataSend: DataSendService,
|
private dataSend: DataSendService,
|
||||||
private motionRepo: MotionRepositoryService,
|
private motionRepo: MotionRepositoryService,
|
||||||
private config: ConfigService
|
|
||||||
) {
|
) {
|
||||||
super(DS, mapperService, MotionBlock);
|
super(DS, mapperService, MotionBlock);
|
||||||
}
|
}
|
||||||
@ -103,15 +100,6 @@ export class MotionBlockRepositoryService extends BaseRepository<ViewMotionBlock
|
|||||||
return this.DS.filter(Motion, motion => motion.motion_block_id === block.id).length;
|
return this.DS.filter(Motion, motion => motion.motion_block_id === block.id).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get agenda visibility from the config
|
|
||||||
*
|
|
||||||
* @return An observable to the default agenda visibility
|
|
||||||
*/
|
|
||||||
public getDefaultAgendaVisibility(): Observable<number> {
|
|
||||||
return this.config.get('agenda_new_items_default_visibility').pipe(map(key => +key));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Observe the motion repository and return the motions belonging to the given
|
* Observe the motion repository and return the motions belonging to the given
|
||||||
* block as observable
|
* block as observable
|
||||||
|
@ -27,6 +27,7 @@ import { TreeService } from 'app/core/services/tree.service';
|
|||||||
import { ViewMotionAmendedParagraph } from '../models/view-motion-amended-paragraph';
|
import { ViewMotionAmendedParagraph } from '../models/view-motion-amended-paragraph';
|
||||||
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';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository Services for motions (and potentially categories)
|
* Repository Services for motions (and potentially categories)
|
||||||
@ -64,7 +65,7 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
|
|||||||
private readonly diff: DiffService,
|
private readonly diff: DiffService,
|
||||||
private treeService: TreeService
|
private treeService: TreeService
|
||||||
) {
|
) {
|
||||||
super(DS, mapperService, Motion, [Category, User, Workflow, Item, MotionBlock]);
|
super(DS, mapperService, Motion, [Category, User, Workflow, Item, MotionBlock, Mediafile]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,11 +83,12 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
|
|||||||
const workflow = this.DS.get(Workflow, motion.workflow_id);
|
const workflow = this.DS.get(Workflow, motion.workflow_id);
|
||||||
const item = this.DS.get(Item, motion.agenda_item_id);
|
const item = this.DS.get(Item, motion.agenda_item_id);
|
||||||
const block = this.DS.get(MotionBlock, motion.motion_block_id);
|
const block = this.DS.get(MotionBlock, motion.motion_block_id);
|
||||||
|
const attachments = this.DS.getMany(Mediafile, motion.attachments_id);
|
||||||
let state: WorkflowState = null;
|
let state: WorkflowState = null;
|
||||||
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);
|
return new ViewMotion(motion, category, submitters, supporters, workflow, state, item, block, attachments);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user