can_manage_metadata and categories on motion create
This commit is contained in:
parent
9692c2b92e
commit
b25b5dc928
@ -1,6 +1,6 @@
|
|||||||
import { Component, OnInit, Input, ViewChild } from '@angular/core';
|
import { Component, OnInit, Input, ViewChild, OnDestroy } from '@angular/core';
|
||||||
import { FormControl, FormGroup } from '@angular/forms';
|
import { FormControl, FormGroup } from '@angular/forms';
|
||||||
import { Subject, ReplaySubject, BehaviorSubject } from 'rxjs';
|
import { Subject, ReplaySubject, BehaviorSubject, Subscription } from 'rxjs';
|
||||||
import { MatSelect } from '@angular/material';
|
import { MatSelect } from '@angular/material';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
@ -35,7 +35,7 @@ import { Selectable } from '../selectable';
|
|||||||
templateUrl: './search-value-selector.component.html',
|
templateUrl: './search-value-selector.component.html',
|
||||||
styleUrls: ['./search-value-selector.component.scss']
|
styleUrls: ['./search-value-selector.component.scss']
|
||||||
})
|
})
|
||||||
export class SearchValueSelectorComponent implements OnInit {
|
export class SearchValueSelectorComponent implements OnInit, OnDestroy {
|
||||||
/**
|
/**
|
||||||
* ngModel variable - Deprecated with Angular 7
|
* ngModel variable - Deprecated with Angular 7
|
||||||
* DO NOT USE: READ AT remove() FUNCTION!
|
* DO NOT USE: READ AT remove() FUNCTION!
|
||||||
@ -52,6 +52,16 @@ export class SearchValueSelectorComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
public filteredItems: ReplaySubject<Selectable[]> = new ReplaySubject<Selectable[]>(1);
|
public filteredItems: ReplaySubject<Selectable[]> = new ReplaySubject<Selectable[]>(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The inputlist subject.
|
||||||
|
*/
|
||||||
|
private _inputListSubject: BehaviorSubject<Selectable[]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the current subscription to _inputListSubject.
|
||||||
|
*/
|
||||||
|
private _inputListSubscription: Subscription = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decide if this should be a single or multi-select-field
|
* Decide if this should be a single or multi-select-field
|
||||||
*/
|
*/
|
||||||
@ -59,10 +69,20 @@ export class SearchValueSelectorComponent implements OnInit {
|
|||||||
public multiple: boolean;
|
public multiple: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Input List Values
|
* The inputlist subject. Subscribes to it and updates the selector, if the subject
|
||||||
|
* changes its values.
|
||||||
*/
|
*/
|
||||||
@Input()
|
@Input()
|
||||||
public InputListValues: BehaviorSubject<Selectable[]>;
|
public set InputListValues(value: BehaviorSubject<Selectable[]>) {
|
||||||
|
// unsubscribe to old subscription.
|
||||||
|
if (this._inputListSubscription) {
|
||||||
|
this._inputListSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
this._inputListSubject = value;
|
||||||
|
this._inputListSubscription = this._inputListSubject.subscribe(values => {
|
||||||
|
this.filterItems();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Placeholder of the List
|
* Placeholder of the List
|
||||||
@ -111,31 +131,43 @@ export class SearchValueSelectorComponent implements OnInit {
|
|||||||
* onInit with filter ans subscription on filter
|
* onInit with filter ans subscription on filter
|
||||||
*/
|
*/
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.filteredItems.next(this.InputListValues.getValue());
|
if (this._inputListSubject) {
|
||||||
|
this.filteredItems.next(this._inputListSubject.getValue());
|
||||||
|
}
|
||||||
// listen to value changes
|
// listen to value changes
|
||||||
this.filterControl.valueChanges.pipe(takeUntil(this._onDestroy)).subscribe(() => {
|
this.filterControl.valueChanges.pipe(takeUntil(this._onDestroy)).subscribe(() => {
|
||||||
this.filterItems();
|
this.filterItems();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsubscribe on destroing.
|
||||||
|
*/
|
||||||
|
public ngOnDestroy(): void {
|
||||||
|
if (this._inputListSubscription) {
|
||||||
|
this._inputListSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
this._onDestroy.next();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the filter function itself
|
* the filter function itself
|
||||||
*/
|
*/
|
||||||
private filterItems(): void {
|
private filterItems(): void {
|
||||||
if (!this.InputListValues) {
|
if (!this._inputListSubject) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// get the search keyword
|
// get the search keyword
|
||||||
let search = this.filterControl.value;
|
let search = this.filterControl.value;
|
||||||
if (!search) {
|
if (!search) {
|
||||||
this.filteredItems.next(this.InputListValues.getValue());
|
this.filteredItems.next(this._inputListSubject.getValue());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
search = search.toLowerCase();
|
search = search.toLowerCase();
|
||||||
}
|
}
|
||||||
// filter the values
|
// filter the values
|
||||||
this.filteredItems.next(
|
this.filteredItems.next(
|
||||||
this.InputListValues.getValue().filter(
|
this._inputListSubject.getValue().filter(
|
||||||
selectedItem =>
|
selectedItem =>
|
||||||
selectedItem
|
selectedItem
|
||||||
.toString()
|
.toString()
|
||||||
|
@ -39,6 +39,13 @@ export class PermsDirective extends OpenSlidesComponent {
|
|||||||
*/
|
*/
|
||||||
private alternative: boolean;
|
private alternative: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switch, to invert the result of checkPermission. Usefull for using osPerms as if-else:
|
||||||
|
* For one element you can use `*osPerms="'perm'"` and for the else-element use
|
||||||
|
* `*osPerms="'perm';complement: true"`.
|
||||||
|
*/
|
||||||
|
private complement: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the directive once. Observes the operator for it's groups so the
|
* Constructs the directive once. Observes the operator for it's groups so the
|
||||||
* directive can perform changes dynamically
|
* directive can perform changes dynamically
|
||||||
@ -85,6 +92,15 @@ export class PermsDirective extends OpenSlidesComponent {
|
|||||||
this.updateView();
|
this.updateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* COmes from the view.
|
||||||
|
*/
|
||||||
|
@Input('osPermsComplement')
|
||||||
|
public set osPermsComplement(value: boolean) {
|
||||||
|
this.complement = value;
|
||||||
|
this.updateView();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows or hides certain content in the view.
|
* Shows or hides certain content in the view.
|
||||||
*/
|
*/
|
||||||
@ -108,6 +124,11 @@ export class PermsDirective extends OpenSlidesComponent {
|
|||||||
* Returns true if the users permissions fit.
|
* Returns true if the users permissions fit.
|
||||||
*/
|
*/
|
||||||
private checkPermissions(): boolean {
|
private checkPermissions(): boolean {
|
||||||
return this.permissions.length === 0 || this.operator.hasPerms(...this.permissions);
|
const hasPerms = this.permissions.length === 0 || this.operator.hasPerms(...this.permissions);
|
||||||
|
if (this.complement) {
|
||||||
|
return !hasPerms;
|
||||||
|
} else {
|
||||||
|
return hasPerms;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,8 +83,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
|
|
||||||
<os-motion-comments [motion]="motion"></os-motion-comments>
|
<os-motion-comments *ngIf="!newMotion" [motion]="motion"></os-motion-comments>
|
||||||
<os-personal-note [motion]="motion"></os-personal-note>
|
<os-personal-note *ngIf="!newMotion" [motion]="motion"></os-personal-note>
|
||||||
|
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
<mat-expansion-panel #contentPanel [expanded]='true'>
|
<mat-expansion-panel #contentPanel [expanded]='true'>
|
||||||
@ -111,8 +111,8 @@
|
|||||||
<ng-container *ngTemplateOutlet="metaInfoTemplate"></ng-container>
|
<ng-container *ngTemplateOutlet="metaInfoTemplate"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<os-motion-comments [motion]="motion"></os-motion-comments>
|
<os-motion-comments *ngIf="!newMotion" [motion]="motion"></os-motion-comments>
|
||||||
<os-personal-note [motion]="motion"></os-personal-note>
|
<os-personal-note *ngIf="!newMotion" [motion]="motion"></os-personal-note>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="desktop-right ">
|
<div class="desktop-right ">
|
||||||
@ -142,8 +142,8 @@
|
|||||||
|
|
||||||
<!-- Submitter -->
|
<!-- Submitter -->
|
||||||
<div *ngIf="motion && motion.submitters || editMotion">
|
<div *ngIf="motion && motion.submitters || editMotion">
|
||||||
<div *ngIf="editMotion && newMotion">
|
<div *ngIf="editMotion">
|
||||||
<div *ngIf="motion && editMotion">
|
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
||||||
<os-search-value-selector ngDefaultControl [form]="metaInfoForm" [formControl]="this.metaInfoForm.get('submitters_id')"
|
<os-search-value-selector ngDefaultControl [form]="metaInfoForm" [formControl]="this.metaInfoForm.get('submitters_id')"
|
||||||
[multiple]="true" listname="Submitter" [InputListValues]="this.submitterObserver"></os-search-value-selector>
|
[multiple]="true" listname="Submitter" [InputListValues]="this.submitterObserver"></os-search-value-selector>
|
||||||
</div>
|
</div>
|
||||||
@ -160,7 +160,7 @@
|
|||||||
<div *ngIf='motion && motion.hasSupporters() || editMotion'>
|
<div *ngIf='motion && motion.hasSupporters() || editMotion'>
|
||||||
<!-- print all motion supporters -->
|
<!-- print all motion supporters -->
|
||||||
<div *ngIf="editMotion">
|
<div *ngIf="editMotion">
|
||||||
<div *ngIf="motion && editMotion">
|
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
||||||
<os-search-value-selector ngDefaultControl [form]="metaInfoForm" [formControl]="this.metaInfoForm.get('supporters_id')"
|
<os-search-value-selector ngDefaultControl [form]="metaInfoForm" [formControl]="this.metaInfoForm.get('supporters_id')"
|
||||||
[multiple]="true" listname="Supporter" [InputListValues]="this.supporterObserver"></os-search-value-selector>
|
[multiple]="true" listname="Supporter" [InputListValues]="this.supporterObserver"></os-search-value-selector>
|
||||||
</div>
|
</div>
|
||||||
@ -168,24 +168,33 @@
|
|||||||
<div *ngIf="!editMotion && motion.hasSupporters()">
|
<div *ngIf="!editMotion && motion.hasSupporters()">
|
||||||
<h3 translate>Supporters</h3>
|
<h3 translate>Supporters</h3>
|
||||||
<ul *ngFor="let supporter of motion.supporters">
|
<ul *ngFor="let supporter of motion.supporters">
|
||||||
<li>{{supporter.full_name}}</li>
|
<li>{{ supporter.full_name }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- State -->
|
<!-- State -->
|
||||||
<div *ngIf='motion && motion.state'>
|
<div *ngIf='motion && motion.state'>
|
||||||
<mat-form-field *ngIf="!editMotion && !newMotion">
|
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata'];complement:true">
|
||||||
<mat-select placeholder='State' formControlName='state_id' (selectionChange)="onChangeState($event)">
|
<ng-container *ngIf="!newMotion">
|
||||||
<mat-option [value]="motion.state_id">{{motion.state}}</mat-option>
|
<h3 translate>State</h3>
|
||||||
<mat-divider></mat-divider>
|
{{ motion.state }}
|
||||||
<mat-option *ngFor="let state of motion.nextStates" [value]="state.id">{{state}}</mat-option>
|
</ng-container>
|
||||||
<mat-divider></mat-divider>
|
</div>
|
||||||
<mat-option [value]="null">
|
<div *ngIf="!editMotion">
|
||||||
<mat-icon>replay</mat-icon><span translate>Reset State</span>
|
<mat-form-field *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
||||||
</mat-option>
|
<mat-select placeholder='State' formControlName='state_id' (selectionChange)="onChangeState($event)">
|
||||||
</mat-select>
|
<mat-option [value]="motion.state_id">{{ motion.state }}</mat-option>
|
||||||
</mat-form-field>
|
<mat-divider></mat-divider>
|
||||||
|
<mat-option *ngFor="let state of motion.nextStates" [value]="state.id">{{ state }}</mat-option>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
<mat-option [value]="null">
|
||||||
|
<mat-icon>replay</mat-icon>
|
||||||
|
<span translate>Reset State</span>
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Recommendation -->
|
<!-- Recommendation -->
|
||||||
@ -193,7 +202,7 @@
|
|||||||
<div *ngIf='motion && motion.state && recommender'>
|
<div *ngIf='motion && motion.state && recommender'>
|
||||||
<mat-form-field *ngIf="!editMotion && !newMotion">
|
<mat-form-field *ngIf="!editMotion && !newMotion">
|
||||||
<mat-select [placeholder]=recommender formControlName='recommendation_id' (selectionChange)="onChangerRecommenderState($event)">
|
<mat-select [placeholder]=recommender formControlName='recommendation_id' (selectionChange)="onChangerRecommenderState($event)">
|
||||||
<mat-option *ngFor="let state of motion.possibleRecommendations" [value]="state.id">{{state}}</mat-option>
|
<mat-option *ngFor="let recommendation of motion.possibleRecommendations" [value]="recommendation.id">{{ recommendation }}</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
@ -204,7 +213,7 @@
|
|||||||
<h3 translate>Category</h3>
|
<h3 translate>Category</h3>
|
||||||
{{motion.category}}
|
{{motion.category}}
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="editMotion">
|
<div *ngIf="editMotion || newMotion">
|
||||||
<os-search-value-selector ngDefaultControl [form]="metaInfoForm" [formControl]="this.metaInfoForm.get('category_id')"
|
<os-search-value-selector ngDefaultControl [form]="metaInfoForm" [formControl]="this.metaInfoForm.get('category_id')"
|
||||||
[multiple]="false" listname="Category" [InputListValues]="this.categoryObserver"></os-search-value-selector>
|
[multiple]="false" listname="Category" [InputListValues]="this.categoryObserver"></os-search-value-selector>
|
||||||
</div>
|
</div>
|
||||||
@ -214,11 +223,13 @@
|
|||||||
<div *ngIf="motion && motion.origin || editMotion">
|
<div *ngIf="motion && motion.origin || editMotion">
|
||||||
<div *ngIf='!editMotion'>
|
<div *ngIf='!editMotion'>
|
||||||
<h3 translate> Origin</h3>
|
<h3 translate> Origin</h3>
|
||||||
{{motion.origin}}
|
{{ motion.origin }}
|
||||||
|
</div>
|
||||||
|
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
||||||
|
<mat-form-field *ngIf="editMotion">
|
||||||
|
<input matInput placeholder='Origin' formControlName='origin' [value]='motionCopy.origin'>
|
||||||
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
<mat-form-field *ngIf="editMotion">
|
|
||||||
<input matInput placeholder='Origin' formControlName='origin' [value]='motionCopy.origin'>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Voting -->
|
<!-- Voting -->
|
||||||
@ -247,7 +258,8 @@
|
|||||||
<h4>{{motion.title}}</h4>
|
<h4>{{motion.title}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<mat-form-field *ngIf="editMotion" class="wide-form">
|
<mat-form-field *ngIf="editMotion" class="wide-form">
|
||||||
<input matInput osAutofocus placeholder='Title' formControlName='title' [value]='motionCopy.title'>
|
<input matInput osAutofocus placeholder='Title' formControlName='title' [value]='motionCopy.title'
|
||||||
|
required>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -267,7 +279,7 @@
|
|||||||
[scrollToChange]="scrollToChange" (createChangeRecommendation)="createChangeRecommendation($event)"></os-motion-detail-diff>
|
[scrollToChange]="scrollToChange" (createChangeRecommendation)="createChangeRecommendation($event)"></os-motion-detail-diff>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<mat-form-field *ngIf="motion && editMotion" class="wide-form">
|
<mat-form-field *ngIf="motion && editMotion" class="wide-form">
|
||||||
<textarea matInput placeholder='Motion Text' formControlName='text' [value]='motionCopy.text'></textarea>
|
<textarea matInput placeholder='Motion Text' formControlName='text' [value]='motionCopy.text' required></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,17 +106,17 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
|
|||||||
/**
|
/**
|
||||||
* Subject for the Categories
|
* Subject for the Categories
|
||||||
*/
|
*/
|
||||||
public categoryObserver: BehaviorSubject<Array<Category>>;
|
public categoryObserver: BehaviorSubject<Category[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subject for the Submitters
|
* Subject for the Submitters
|
||||||
*/
|
*/
|
||||||
public submitterObserver: BehaviorSubject<Array<User>>;
|
public submitterObserver: BehaviorSubject<User[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subject for the Supporters
|
* Subject for the Supporters
|
||||||
*/
|
*/
|
||||||
public supporterObserver: BehaviorSubject<Array<User>>;
|
public supporterObserver: BehaviorSubject<User[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value for os-motion-detail-diff: when this is set, that component scrolls to the given change
|
* Value for os-motion-detail-diff: when this is set, that component scrolls to the given change
|
||||||
@ -489,7 +489,7 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
|
|||||||
* Determine if the user has the correct requirements to alter the motion
|
* Determine if the user has the correct requirements to alter the motion
|
||||||
*/
|
*/
|
||||||
public opCanEdit(): boolean {
|
public opCanEdit(): boolean {
|
||||||
return this.op.hasPerms('motions.can_manage');
|
return this.op.hasPerms('motions.can_manage', 'motions.can_manage_metadata');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,14 +134,15 @@ class MotionViewSet(ModelViewSet):
|
|||||||
'title',
|
'title',
|
||||||
'text',
|
'text',
|
||||||
'reason',
|
'reason',
|
||||||
|
'category_id',
|
||||||
]
|
]
|
||||||
if parent_motion is not None:
|
if parent_motion is not None:
|
||||||
# For creating amendments.
|
# For creating amendments.
|
||||||
whitelist.extend([
|
whitelist.extend([
|
||||||
'parent_id',
|
'parent_id',
|
||||||
'amendment_paragraphs',
|
'amendment_paragraphs',
|
||||||
'category_id', # This will be set to the matching
|
'motion_block_id', # This and the category_id will be set to the matching
|
||||||
'motion_block_id', # values from parent_motion.
|
# values from parent_motion.
|
||||||
])
|
])
|
||||||
request.data['category_id'] = parent_motion.category_id
|
request.data['category_id'] = parent_motion.category_id
|
||||||
request.data['motion_block_id'] = parent_motion.motion_block_id
|
request.data['motion_block_id'] = parent_motion.motion_block_id
|
||||||
|
Loading…
Reference in New Issue
Block a user