add new Motion form
This commit is contained in:
parent
b808228b42
commit
133ecb4724
@ -1,7 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Observable, of, BehaviorSubject } from 'rxjs';
|
import { Observable, BehaviorSubject } from 'rxjs';
|
||||||
import { tap, map } from 'rxjs/operators';
|
import { tap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { ImproperlyConfiguredError } from 'app/core/exceptions';
|
import { ImproperlyConfiguredError } from 'app/core/exceptions';
|
||||||
import { BaseModel, ModelId } from 'app/shared/models/base.model';
|
import { BaseModel, ModelId } from 'app/shared/models/base.model';
|
||||||
|
@ -26,10 +26,10 @@ export class MotionVersion implements Deserializable {
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
this.version_number = version_number;
|
this.version_number = version_number;
|
||||||
this.creation_time = creation_time;
|
this.creation_time = creation_time;
|
||||||
this.title = title;
|
this.title = title || '';
|
||||||
this.text = text;
|
this.text = text || '';
|
||||||
this.amendment_paragraphs = amendment_paragraphs;
|
this.amendment_paragraphs = amendment_paragraphs || '';
|
||||||
this.reason = reason;
|
this.reason = reason || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
deserialize(input: any): this {
|
deserialize(input: any): this {
|
||||||
|
@ -66,24 +66,24 @@ export class Motion extends BaseModel {
|
|||||||
super();
|
super();
|
||||||
this._collectionString = 'motions/motion';
|
this._collectionString = 'motions/motion';
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.identifier = identifier;
|
this.identifier = identifier || '';
|
||||||
this.versions = versions;
|
this.versions = versions || [new MotionVersion()];
|
||||||
this.active_version = active_version;
|
this.active_version = active_version;
|
||||||
this.parent_id = parent_id;
|
this.parent_id = parent_id;
|
||||||
this.category_id = category_id;
|
this.category_id = category_id;
|
||||||
this.motion_block_id = motion_block_id;
|
this.motion_block_id = motion_block_id;
|
||||||
this.origin = origin;
|
this.origin = origin || '';
|
||||||
this.submitters = submitters;
|
this.submitters = submitters || [new MotionSubmitter()];
|
||||||
this.supporters_id = supporters_id;
|
this.supporters_id = supporters_id;
|
||||||
this.comments = comments;
|
this.comments = comments;
|
||||||
this.state_id = state_id;
|
this.state_id = state_id;
|
||||||
this.state_required_permission_to_see = state_required_permission_to_see;
|
this.state_required_permission_to_see = state_required_permission_to_see || '';
|
||||||
this.recommendation_id = recommendation_id;
|
this.recommendation_id = recommendation_id;
|
||||||
this.tags_id = tags_id;
|
this.tags_id = tags_id;
|
||||||
this.attachments_id = attachments_id;
|
this.attachments_id = attachments_id;
|
||||||
this.polls = polls;
|
this.polls = polls;
|
||||||
this.agenda_item_id = agenda_item_id;
|
this.agenda_item_id = agenda_item_id;
|
||||||
this.log_messages = log_messages;
|
this.log_messages = log_messages || [new MotionLog()];
|
||||||
|
|
||||||
this.initDataStoreValues();
|
this.initDataStoreValues();
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ export class Motion extends BaseModel {
|
|||||||
* returns the most current title from versions
|
* returns the most current title from versions
|
||||||
*/
|
*/
|
||||||
get currentTitle(): string {
|
get currentTitle(): string {
|
||||||
if (this.versions[0]) {
|
if (this.versions && this.versions[0]) {
|
||||||
return this.versions[0].title;
|
return this.versions[0].title;
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
@ -141,7 +141,11 @@ export class Motion extends BaseModel {
|
|||||||
* returns the most current motion text from versions
|
* returns the most current motion text from versions
|
||||||
*/
|
*/
|
||||||
get currentText() {
|
get currentText() {
|
||||||
return this.versions[0].text;
|
if (this.versions) {
|
||||||
|
return this.versions[0].text;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set currentText(newText: string) {
|
set currentText(newText: string) {
|
||||||
@ -152,9 +156,17 @@ export class Motion extends BaseModel {
|
|||||||
* returns the most current motion reason text from versions
|
* returns the most current motion reason text from versions
|
||||||
*/
|
*/
|
||||||
get currentReason() {
|
get currentReason() {
|
||||||
return this.versions[0].reason;
|
if (this.versions) {
|
||||||
|
return this.versions[0].reason;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the current reason.
|
||||||
|
* TODO: ignores motion versions. Should make a new one.
|
||||||
|
*/
|
||||||
set currentReason(newReason: string) {
|
set currentReason(newReason: string) {
|
||||||
this.versions[0].reason = newReason;
|
this.versions[0].reason = newReason;
|
||||||
}
|
}
|
||||||
@ -164,20 +176,24 @@ export class Motion extends BaseModel {
|
|||||||
*/
|
*/
|
||||||
get submitterAsUser() {
|
get submitterAsUser() {
|
||||||
const submitterIds = [];
|
const submitterIds = [];
|
||||||
this.submitters.forEach(submitter => {
|
if (this.submitters) {
|
||||||
submitterIds.push(submitter.user_id);
|
this.submitters.forEach(submitter => {
|
||||||
});
|
submitterIds.push(submitter.user_id);
|
||||||
const users = this.DS.get(User, ...submitterIds);
|
});
|
||||||
return users;
|
const users = this.DS.get(User, ...submitterIds);
|
||||||
|
return users;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the name of the first submitter
|
* returns the name of the first submitter
|
||||||
*/
|
*/
|
||||||
get submitterName() {
|
get submitterName() {
|
||||||
const mainSubmitter = this.DS.get(User, this.submitters[0].user_id) as User;
|
const submitters = this.submitterAsUser;
|
||||||
if (mainSubmitter) {
|
if (submitters) {
|
||||||
return mainSubmitter;
|
return submitters[0];
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -191,7 +207,7 @@ export class Motion extends BaseModel {
|
|||||||
const motionCategory = this.DS.get(Category, this.category_id);
|
const motionCategory = this.DS.get(Category, this.category_id);
|
||||||
return motionCategory as Category;
|
return motionCategory as Category;
|
||||||
} else {
|
} else {
|
||||||
return 'none';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,12 +221,12 @@ export class Motion extends BaseModel {
|
|||||||
/**
|
/**
|
||||||
* return the workflow state
|
* return the workflow state
|
||||||
*/
|
*/
|
||||||
get state() {
|
get state(): any {
|
||||||
if (this.workflow && this.workflow.id) {
|
if (this.state_id && this.workflow && this.workflow.id) {
|
||||||
const state = this.workflow.state_by_id(this.state_id);
|
const state = this.workflow.state_by_id(this.state_id);
|
||||||
return state;
|
return state;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,12 +242,12 @@ export class Motion extends BaseModel {
|
|||||||
*
|
*
|
||||||
* TODO: Motion workflow needs to be specific on the server
|
* TODO: Motion workflow needs to be specific on the server
|
||||||
*/
|
*/
|
||||||
get recommendation() {
|
get recommendation(): any {
|
||||||
if (this.workflow && this.workflow.id) {
|
if (this.recommendation_id && this.workflow && this.workflow.id) {
|
||||||
const state = this.workflow.state_by_id(this.recommendation_id);
|
const state = this.workflow.state_by_id(this.recommendation_id);
|
||||||
return state;
|
return state;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,8 +259,13 @@ export class Motion extends BaseModel {
|
|||||||
Config,
|
Config,
|
||||||
config => config.key === 'motions_recommendations_by'
|
config => config.key === 'motions_recommendations_by'
|
||||||
)[0] as Config;
|
)[0] as Config;
|
||||||
const recomByString = motionsRecommendationsByConfig.value;
|
|
||||||
return recomByString;
|
if (motionsRecommendationsByConfig) {
|
||||||
|
const recomByString = motionsRecommendationsByConfig.value;
|
||||||
|
return recomByString;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deserialize(input: any): this {
|
deserialize(input: any): this {
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
<mat-toolbar color='primary'>
|
<mat-toolbar color='primary'>
|
||||||
|
|
||||||
<button (click)='editMotionButton()' [ngClass]="{'save-button': editMotion}" class='generic-mini-button on-transition-fade save-button' mat-mini-fab>
|
<button (click)='editMotionButton()' [ngClass]="{'save-button': editMotion}" class='generic-mini-button on-transition-fade'
|
||||||
|
mat-mini-fab>
|
||||||
<fa-icon *ngIf="!editMotion" icon='pen'></fa-icon>
|
<fa-icon *ngIf="!editMotion" icon='pen'></fa-icon>
|
||||||
<fa-icon *ngIf="editMotion" icon='check'></fa-icon>
|
<fa-icon *ngIf="editMotion" icon='check'></fa-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class='motion-title on-transition-fade'>
|
<div class='motion-title on-transition-fade'>
|
||||||
|
<span *ngIf="newMotion">New </span>
|
||||||
<span translate>Motion</span>
|
<span translate>Motion</span>
|
||||||
<span *ngIf="!editMotion"> {{motion.identifier}}</span>
|
<span *ngIf="!editMotion"> {{motion.identifier}}</span>
|
||||||
<span *ngIf="editMotion"> {{metaInfoForm.get('identifier').value}}</span>
|
<span *ngIf="editMotion && !newMotion"> {{metaInfoForm.get('identifier').value}}</span>
|
||||||
<span>:</span>
|
<span>:</span>
|
||||||
<span *ngIf="!editMotion"> {{motion.currentTitle}}</span>
|
<span *ngIf="!editMotion"> {{motion.currentTitle}}</span>
|
||||||
<span *ngIf="editMotion"> {{contentForm.get('currentTitle').value}}</span>
|
<span *ngIf="editMotion"> {{contentForm.get('currentTitle').value}}</span>
|
||||||
@ -23,7 +25,7 @@
|
|||||||
|
|
||||||
<!-- MetaInfo -->
|
<!-- MetaInfo -->
|
||||||
<!-- <mat-expansion-panel #metaInfoPanel [expanded]='true' class='meta-info-panel'> -->
|
<!-- <mat-expansion-panel #metaInfoPanel [expanded]='true' class='meta-info-panel'> -->
|
||||||
<mat-expansion-panel #metaInfoPanel class='meta-info-panel'>
|
<mat-expansion-panel #metaInfoPanel [expanded]='this.editMotion && this.newMotion' class='meta-info-panel'>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>
|
<mat-panel-title>
|
||||||
<fa-icon icon='info-circle' [fixedWidth]="true"></fa-icon>
|
<fa-icon icon='info-circle' [fixedWidth]="true"></fa-icon>
|
||||||
@ -35,7 +37,8 @@
|
|||||||
<form [formGroup]='metaInfoForm' class='expansion-panel-custom-body' (ngSubmit)='saveMotion()'>
|
<form [formGroup]='metaInfoForm' class='expansion-panel-custom-body' (ngSubmit)='saveMotion()'>
|
||||||
|
|
||||||
<!-- Identifier -->
|
<!-- Identifier -->
|
||||||
<div *ngIf="editMotion">
|
<div *ngIf="editMotion && !newMotion">
|
||||||
|
<!-- <div *ngIf="editMotion"> -->
|
||||||
<div *ngIf='!editMotion'>
|
<div *ngIf='!editMotion'>
|
||||||
<h3 translate>Identifier</h3>
|
<h3 translate>Identifier</h3>
|
||||||
{{motion.identifier}}
|
{{motion.identifier}}
|
||||||
@ -92,12 +95,6 @@
|
|||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<!-- <h3>
|
|
||||||
<a [matMenuTriggerFor]="stateMenu">
|
|
||||||
<span>{{motion.recomBy}}</span>
|
|
||||||
</a>
|
|
||||||
</h3> -->
|
|
||||||
<!-- {{motion.recommendation}} -->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Category -->
|
<!-- Category -->
|
||||||
@ -185,7 +182,7 @@
|
|||||||
<textarea matInput placeholder="Reason" formControlName='currentReason' [value]='motion.currentReason'></textarea>
|
<textarea matInput placeholder="Reason" formControlName='currentReason' [value]='motion.currentReason'></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
|
|
||||||
|
</form>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
</mat-accordion>
|
</mat-accordion>
|
@ -19,26 +19,46 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
|
|||||||
metaInfoForm: FormGroup;
|
metaInfoForm: FormGroup;
|
||||||
contentForm: FormGroup;
|
contentForm: FormGroup;
|
||||||
editMotion = false;
|
editMotion = false;
|
||||||
|
newMotion = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param route determine if this is a new or an existing motion
|
||||||
|
* @param formBuilder For reactive forms. Form Group and Form Control
|
||||||
|
*/
|
||||||
constructor(private route: ActivatedRoute, private formBuilder: FormBuilder) {
|
constructor(private route: ActivatedRoute, private formBuilder: FormBuilder) {
|
||||||
super();
|
super();
|
||||||
this.createForm();
|
this.createForm();
|
||||||
this.route.params.subscribe(params => {
|
|
||||||
// has the motion of the DataStore was initialized before.
|
|
||||||
this.motion = this.DS.get(Motion, params.id) as Motion;
|
|
||||||
|
|
||||||
// Observe motion to get the motion in the parameter and also get the changes
|
console.log('route: ', route.snapshot.url[0].path);
|
||||||
this.DS.getObservable().subscribe(newModel => {
|
|
||||||
if (newModel instanceof Motion) {
|
if (route.snapshot.url[0].path === 'new') {
|
||||||
if (newModel.id === +params.id) {
|
this.newMotion = true;
|
||||||
this.motion = newModel as Motion;
|
this.editMotion = true;
|
||||||
|
this.motion = new Motion();
|
||||||
|
} else {
|
||||||
|
// load existing motion
|
||||||
|
this.route.params.subscribe(params => {
|
||||||
|
console.log('params ', params);
|
||||||
|
|
||||||
|
// has the motion of the DataStore was initialized before.
|
||||||
|
this.motion = this.DS.get(Motion, params.id) as Motion;
|
||||||
|
|
||||||
|
// Observe motion to get the motion in the parameter and also get the changes
|
||||||
|
this.DS.getObservable().subscribe(newModel => {
|
||||||
|
if (newModel instanceof Motion) {
|
||||||
|
if (newModel.id === +params.id) {
|
||||||
|
this.motion = newModel as Motion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Parches the Form with content from the dataStore */
|
/**
|
||||||
|
* Async load the values of the motion in the Form.
|
||||||
|
*/
|
||||||
patchForm() {
|
patchForm() {
|
||||||
this.metaInfoForm.patchValue({
|
this.metaInfoForm.patchValue({
|
||||||
category_id: this.motion.category.id,
|
category_id: this.motion.category.id,
|
||||||
@ -54,7 +74,11 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create the whole Form with empty or default values */
|
/**
|
||||||
|
* Creates the forms for the Motion and the MotionVersion
|
||||||
|
*
|
||||||
|
* TODO: Build a custom form validator
|
||||||
|
*/
|
||||||
createForm() {
|
createForm() {
|
||||||
this.metaInfoForm = this.formBuilder.group({
|
this.metaInfoForm = this.formBuilder.group({
|
||||||
identifier: [''],
|
identifier: [''],
|
||||||
@ -70,35 +94,57 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save a motion. Calls the "patchValues" function in the MotionObject
|
||||||
|
*
|
||||||
|
* http:post the motion to the server.
|
||||||
|
* The AutoUpdate-Service should see a change once it arrives and show it
|
||||||
|
* in the list view automatically
|
||||||
|
*/
|
||||||
saveMotion() {
|
saveMotion() {
|
||||||
const newMotionValues = { ...this.metaInfoForm.value, ...this.contentForm.value };
|
const newMotionValues = { ...this.metaInfoForm.value, ...this.contentForm.value };
|
||||||
this.motion.patchValues(newMotionValues);
|
this.motion.patchValues(newMotionValues);
|
||||||
|
|
||||||
|
console.log('save motion: this: ', this);
|
||||||
|
|
||||||
|
this.DS.save(this.motion).subscribe(answer => {
|
||||||
|
console.log(answer);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return all Categories.
|
||||||
|
*/
|
||||||
getMotionCategories(): Category[] {
|
getMotionCategories(): Category[] {
|
||||||
const categories = this.DS.get(Category);
|
const categories = this.DS.get(Category);
|
||||||
return categories as Category[];
|
return categories as Category[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Click on the edit button (pen-symbol)
|
||||||
|
*/
|
||||||
editMotionButton() {
|
editMotionButton() {
|
||||||
this.editMotion ? (this.editMotion = false) : (this.editMotion = true);
|
this.editMotion ? (this.editMotion = false) : (this.editMotion = true);
|
||||||
|
|
||||||
if (this.editMotion) {
|
if (this.editMotion) {
|
||||||
// switch to edit mode
|
|
||||||
this.patchForm();
|
this.patchForm();
|
||||||
this.metaInfoPanel.open();
|
this.metaInfoPanel.open();
|
||||||
this.contentPanel.open();
|
this.contentPanel.open();
|
||||||
} else {
|
} else {
|
||||||
// save button
|
|
||||||
this.saveMotion();
|
this.saveMotion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
/**
|
||||||
console.log('(init)the motion: ', this.motion);
|
* Init. Does nothing here.
|
||||||
console.log('motion state name: ', this.motion.state);
|
*/
|
||||||
}
|
ngOnInit() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to download a motion.
|
||||||
|
*
|
||||||
|
* TODO: does nothing yet.
|
||||||
|
*/
|
||||||
downloadSingleMotionButton() {
|
downloadSingleMotionButton() {
|
||||||
console.log('Download this motion');
|
console.log('Download this motion');
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<mat-toolbar color='primary'>
|
<mat-toolbar color='primary'>
|
||||||
|
|
||||||
<button class='generic-plus-button on-transition-fade' mat-fab>
|
<button class='generic-plus-button on-transition-fade' routerLink='new' mat-fab>
|
||||||
<fa-icon icon='plus'></fa-icon>
|
<fa-icon icon='plus'></fa-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@ -43,7 +43,7 @@
|
|||||||
<br>
|
<br>
|
||||||
<span class='motion-list-from'>
|
<span class='motion-list-from'>
|
||||||
<span translate>by</span>
|
<span translate>by</span>
|
||||||
{{motion.submitterAsUser.username}}
|
{{motion.submitterAsUser}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
|
@ -70,8 +70,10 @@ export class MotionListComponent extends BaseComponent implements OnInit {
|
|||||||
// The alternative approach is to put the observable as DataSource to the table
|
// The alternative approach is to put the observable as DataSource to the table
|
||||||
this.DS.getObservable().subscribe(newModel => {
|
this.DS.getObservable().subscribe(newModel => {
|
||||||
if (newModel instanceof Motion) {
|
if (newModel instanceof Motion) {
|
||||||
this.motionArray.push(newModel as Motion);
|
if (!this.motionArray.includes(newModel)) {
|
||||||
this.dataSource.data = this.motionArray;
|
this.motionArray.push(newModel as Motion);
|
||||||
|
this.dataSource.data = this.motionArray;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { MotionDetailComponent } from './motion-detail/motion-detail.component';
|
|||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', component: MotionListComponent },
|
{ path: '', component: MotionListComponent },
|
||||||
{ path: 'dummy', component: MotionDetailComponent },
|
{ path: 'new', component: MotionDetailComponent },
|
||||||
{ path: ':id', component: MotionDetailComponent }
|
{ path: ':id', component: MotionDetailComponent }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -111,7 +111,8 @@ export class StartComponent extends BaseComponent implements OnInit {
|
|||||||
* function to print datastore
|
* function to print datastore
|
||||||
*/
|
*/
|
||||||
giveDataStore() {
|
giveDataStore() {
|
||||||
this.DS.printWhole();
|
// this.DS.printWhole();
|
||||||
|
console.log('only the motions: \n', this.DS.get(Motion) as Motion[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user