add new Motion form

This commit is contained in:
Sean Engelhardt 2018-08-21 14:56:26 +02:00
parent b808228b42
commit 133ecb4724
9 changed files with 136 additions and 69 deletions

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Observable, of, BehaviorSubject } from 'rxjs';
import { tap, map } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
import { Observable, BehaviorSubject } from 'rxjs';
import { tap } from 'rxjs/operators';
import { ImproperlyConfiguredError } from 'app/core/exceptions';
import { BaseModel, ModelId } from 'app/shared/models/base.model';

View File

@ -26,10 +26,10 @@ export class MotionVersion implements Deserializable {
this.id = id;
this.version_number = version_number;
this.creation_time = creation_time;
this.title = title;
this.text = text;
this.amendment_paragraphs = amendment_paragraphs;
this.reason = reason;
this.title = title || '';
this.text = text || '';
this.amendment_paragraphs = amendment_paragraphs || '';
this.reason = reason || '';
}
deserialize(input: any): this {

View File

@ -66,24 +66,24 @@ export class Motion extends BaseModel {
super();
this._collectionString = 'motions/motion';
this.id = id;
this.identifier = identifier;
this.versions = versions;
this.identifier = identifier || '';
this.versions = versions || [new MotionVersion()];
this.active_version = active_version;
this.parent_id = parent_id;
this.category_id = category_id;
this.motion_block_id = motion_block_id;
this.origin = origin;
this.submitters = submitters;
this.origin = origin || '';
this.submitters = submitters || [new MotionSubmitter()];
this.supporters_id = supporters_id;
this.comments = comments;
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.tags_id = tags_id;
this.attachments_id = attachments_id;
this.polls = polls;
this.agenda_item_id = agenda_item_id;
this.log_messages = log_messages;
this.log_messages = log_messages || [new MotionLog()];
this.initDataStoreValues();
}
@ -124,7 +124,7 @@ export class Motion extends BaseModel {
* returns the most current title from versions
*/
get currentTitle(): string {
if (this.versions[0]) {
if (this.versions && this.versions[0]) {
return this.versions[0].title;
} else {
return '';
@ -141,7 +141,11 @@ export class Motion extends BaseModel {
* returns the most current motion text from versions
*/
get currentText() {
return this.versions[0].text;
if (this.versions) {
return this.versions[0].text;
} else {
return null;
}
}
set currentText(newText: string) {
@ -152,9 +156,17 @@ export class Motion extends BaseModel {
* returns the most current motion reason text from versions
*/
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) {
this.versions[0].reason = newReason;
}
@ -164,20 +176,24 @@ export class Motion extends BaseModel {
*/
get submitterAsUser() {
const submitterIds = [];
this.submitters.forEach(submitter => {
submitterIds.push(submitter.user_id);
});
const users = this.DS.get(User, ...submitterIds);
return users;
if (this.submitters) {
this.submitters.forEach(submitter => {
submitterIds.push(submitter.user_id);
});
const users = this.DS.get(User, ...submitterIds);
return users;
} else {
return null;
}
}
/**
* returns the name of the first submitter
*/
get submitterName() {
const mainSubmitter = this.DS.get(User, this.submitters[0].user_id) as User;
if (mainSubmitter) {
return mainSubmitter;
const submitters = this.submitterAsUser;
if (submitters) {
return submitters[0];
} else {
return '';
}
@ -191,7 +207,7 @@ export class Motion extends BaseModel {
const motionCategory = this.DS.get(Category, this.category_id);
return motionCategory as Category;
} else {
return 'none';
return '';
}
}
@ -205,12 +221,12 @@ export class Motion extends BaseModel {
/**
* return the workflow state
*/
get state() {
if (this.workflow && this.workflow.id) {
get state(): any {
if (this.state_id && this.workflow && this.workflow.id) {
const state = this.workflow.state_by_id(this.state_id);
return state;
} else {
return null;
return '';
}
}
@ -226,12 +242,12 @@ export class Motion extends BaseModel {
*
* TODO: Motion workflow needs to be specific on the server
*/
get recommendation() {
if (this.workflow && this.workflow.id) {
get recommendation(): any {
if (this.recommendation_id && this.workflow && this.workflow.id) {
const state = this.workflow.state_by_id(this.recommendation_id);
return state;
} else {
return null;
return '';
}
}
@ -243,8 +259,13 @@ export class Motion extends BaseModel {
Config,
config => config.key === 'motions_recommendations_by'
)[0] as Config;
const recomByString = motionsRecommendationsByConfig.value;
return recomByString;
if (motionsRecommendationsByConfig) {
const recomByString = motionsRecommendationsByConfig.value;
return recomByString;
} else {
return null;
}
}
deserialize(input: any): this {

View File

@ -1,14 +1,16 @@
<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='check'></fa-icon>
</button>
<div class='motion-title on-transition-fade'>
<span *ngIf="newMotion">New </span>
<span translate>Motion</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 *ngIf="!editMotion"> {{motion.currentTitle}}</span>
<span *ngIf="editMotion"> {{contentForm.get('currentTitle').value}}</span>
@ -23,7 +25,7 @@
<!-- MetaInfo -->
<!-- <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-panel-title>
<fa-icon icon='info-circle' [fixedWidth]="true"></fa-icon>
@ -35,7 +37,8 @@
<form [formGroup]='metaInfoForm' class='expansion-panel-custom-body' (ngSubmit)='saveMotion()'>
<!-- Identifier -->
<div *ngIf="editMotion">
<div *ngIf="editMotion && !newMotion">
<!-- <div *ngIf="editMotion"> -->
<div *ngIf='!editMotion'>
<h3 translate>Identifier</h3>
{{motion.identifier}}
@ -92,12 +95,6 @@
</mat-option>
</mat-select>
</mat-form-field>
<!-- <h3>
<a [matMenuTriggerFor]="stateMenu">
<span>{{motion.recomBy}}</span>
</a>
</h3> -->
<!-- {{motion.recommendation}} -->
</div>
<!-- Category -->
@ -185,7 +182,7 @@
<textarea matInput placeholder="Reason" formControlName='currentReason' [value]='motion.currentReason'></textarea>
</mat-form-field>
</div>
</form>
</form>
</mat-expansion-panel>
</mat-accordion>
</mat-accordion>

View File

@ -19,26 +19,46 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
metaInfoForm: FormGroup;
contentForm: FormGroup;
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) {
super();
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
this.DS.getObservable().subscribe(newModel => {
if (newModel instanceof Motion) {
if (newModel.id === +params.id) {
this.motion = newModel as Motion;
console.log('route: ', route.snapshot.url[0].path);
if (route.snapshot.url[0].path === 'new') {
this.newMotion = true;
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() {
this.metaInfoForm.patchValue({
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() {
this.metaInfoForm = this.formBuilder.group({
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() {
const newMotionValues = { ...this.metaInfoForm.value, ...this.contentForm.value };
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[] {
const categories = this.DS.get(Category);
return categories as Category[];
}
/**
* Click on the edit button (pen-symbol)
*/
editMotionButton() {
this.editMotion ? (this.editMotion = false) : (this.editMotion = true);
if (this.editMotion) {
// switch to edit mode
this.patchForm();
this.metaInfoPanel.open();
this.contentPanel.open();
} else {
// save button
this.saveMotion();
}
}
ngOnInit() {
console.log('(init)the motion: ', this.motion);
console.log('motion state name: ', this.motion.state);
}
/**
* Init. Does nothing here.
*/
ngOnInit() {}
/**
* Function to download a motion.
*
* TODO: does nothing yet.
*/
downloadSingleMotionButton() {
console.log('Download this motion');
}

View File

@ -1,6 +1,6 @@
<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>
</button>
@ -43,7 +43,7 @@
<br>
<span class='motion-list-from'>
<span translate>by</span>
{{motion.submitterAsUser.username}}
{{motion.submitterAsUser}}
</span>
</div>
</mat-cell>

View File

@ -70,8 +70,10 @@ export class MotionListComponent extends BaseComponent implements OnInit {
// The alternative approach is to put the observable as DataSource to the table
this.DS.getObservable().subscribe(newModel => {
if (newModel instanceof Motion) {
this.motionArray.push(newModel as Motion);
this.dataSource.data = this.motionArray;
if (!this.motionArray.includes(newModel)) {
this.motionArray.push(newModel as Motion);
this.dataSource.data = this.motionArray;
}
}
});
}

View File

@ -5,7 +5,7 @@ import { MotionDetailComponent } from './motion-detail/motion-detail.component';
const routes: Routes = [
{ path: '', component: MotionListComponent },
{ path: 'dummy', component: MotionDetailComponent },
{ path: 'new', component: MotionDetailComponent },
{ path: ':id', component: MotionDetailComponent }
];

View File

@ -111,7 +111,8 @@ export class StartComponent extends BaseComponent implements OnInit {
* function to print datastore
*/
giveDataStore() {
this.DS.printWhole();
// this.DS.printWhole();
console.log('only the motions: \n', this.DS.get(Motion) as Motion[]);
}
/**