OpenSlides/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts

284 lines
8.6 KiB
TypeScript
Raw Normal View History

2018-08-16 17:03:39 +02:00
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
2018-09-03 14:23:54 +02:00
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { MatExpansionPanel } from '@angular/material';
import { BaseComponent } from '../../../../base.component';
import { Category } from '../../../../shared/models/motions/category';
import { ViewportService } from '../../../../core/services/viewport.service';
import { MotionRepositoryService } from '../../services/motion-repository.service';
import { ViewMotion } from '../../models/view-motion';
import { User } from '../../../../shared/models/users/user';
2018-09-13 14:40:04 +02:00
import { DataStoreService } from '../../../../core/services/data-store.service';
2018-09-19 15:18:57 +02:00
import { TranslateService } from '@ngx-translate/core';
import { Motion } from '../../../../shared/models/motions/motion';
import { BehaviorSubject } from 'rxjs';
/**
* Component for the motion detail view
*/
@Component({
selector: 'os-motion-detail',
templateUrl: './motion-detail.component.html',
styleUrls: ['./motion-detail.component.scss']
})
2018-08-22 16:03:49 +02:00
export class MotionDetailComponent extends BaseComponent implements OnInit {
/**
* MatExpansionPanel for the meta info
* Only relevant in mobile view
*/
@ViewChild('metaInfoPanel')
public metaInfoPanel: MatExpansionPanel;
/**
* MatExpansionPanel for the content panel
* Only relevant in mobile view
*/
@ViewChild('contentPanel')
public contentPanel: MatExpansionPanel;
2018-08-16 17:03:39 +02:00
/**
* Motions meta-info
*/
2018-08-29 13:21:25 +02:00
public metaInfoForm: FormGroup;
/**
* Motion content. Can be a new version
*/
2018-08-29 13:21:25 +02:00
public contentForm: FormGroup;
/**
* Determine if the motion is edited
*/
2018-08-29 13:21:25 +02:00
public editMotion = false;
/**
* Determine if the motion is new
*/
2018-08-29 13:21:25 +02:00
public newMotion = false;
2018-08-16 17:03:39 +02:00
/**
* Target motion. Might be new or old
*/
public motion: ViewMotion;
/**
* Copy of the motion that the user might edit
*/
public motionCopy: ViewMotion;
2018-09-19 15:18:57 +02:00
/**
* Subject for the Categories
*/
public categoryObserver: BehaviorSubject<Array<Category>>;
/**
* Subject for the Submitters
*/
public submitterObserver: BehaviorSubject<Array<User>>;
/**
* Subject for the Supporters
*/
public supporterObserver: BehaviorSubject<Array<User>>;
2018-08-21 14:56:26 +02:00
/**
* Constuct the detail view.
*
2018-09-03 14:23:54 +02:00
* @param vp the viewport service
* @param router to navigate back to the motion list and to an existing motion
2018-08-21 14:56:26 +02:00
* @param route determine if this is a new or an existing motion
* @param formBuilder For reactive forms. Form Group and Form Control
* @param repo: Motion Repository
2018-09-19 15:18:57 +02:00
* @param translate: Translation Service
2018-08-21 14:56:26 +02:00
*/
2018-08-29 13:21:25 +02:00
public constructor(
2018-09-03 14:23:54 +02:00
public vp: ViewportService,
private router: Router,
private route: ActivatedRoute,
private formBuilder: FormBuilder,
2018-09-13 14:40:04 +02:00
private repo: MotionRepositoryService,
2018-09-19 15:18:57 +02:00
private DS: DataStoreService,
protected translate: TranslateService
) {
2018-08-22 16:03:49 +02:00
super();
2018-08-16 17:03:39 +02:00
this.createForm();
2018-08-21 14:56:26 +02:00
if (route.snapshot.url[0].path === 'new') {
this.newMotion = true;
this.editMotion = true;
2018-08-24 12:21:56 +02:00
// Both are (temporarily) necessary until submitter and supporters are implemented
// TODO new Motion and ViewMotion
this.motion = new ViewMotion();
this.motionCopy = new ViewMotion();
2018-08-21 14:56:26 +02:00
} else {
// load existing motion
this.route.params.subscribe(params => {
2018-09-10 15:53:11 +02:00
this.repo.getViewModelObservable(params.id).subscribe(newViewMotion => {
this.motion = newViewMotion;
2018-08-21 14:56:26 +02:00
});
});
2018-08-21 14:56:26 +02:00
}
2018-09-19 15:18:57 +02:00
// Initial Filling of the Subjects
this.submitterObserver = new BehaviorSubject(DS.getAll(User));
this.supporterObserver = new BehaviorSubject(DS.getAll(User));
this.categoryObserver = new BehaviorSubject(DS.getAll(Category));
2018-09-19 15:18:57 +02:00
// Make sure the subjects are updated, when a new Model for the type arrives
this.DS.changeObservable.subscribe(newModel => {
if (newModel instanceof User) {
this.submitterObserver.next(DS.getAll(User));
this.supporterObserver.next(DS.getAll(User));
}
if (newModel instanceof Category) {
this.categoryObserver.next(DS.getAll(Category));
}
});
}
2018-08-21 14:56:26 +02:00
/**
* Async load the values of the motion in the Form.
*/
public patchForm(formMotion: ViewMotion): void {
this.metaInfoForm.patchValue({
category_id: formMotion.categoryId,
supporters_id: formMotion.supporterIds,
submitters_id: formMotion.submitterIds,
state_id: formMotion.stateId,
recommendation_id: formMotion.recommendationId,
2018-08-24 12:21:56 +02:00
identifier: formMotion.identifier,
origin: formMotion.origin
});
this.contentForm.patchValue({
title: formMotion.title,
text: formMotion.text,
reason: formMotion.reason
});
2018-08-16 17:03:39 +02:00
}
2018-08-21 14:56:26 +02:00
/**
* Creates the forms for the Motion and the MotionVersion
*
* TODO: Build a custom form validator
*/
public createForm(): void {
2018-08-16 17:03:39 +02:00
this.metaInfoForm = this.formBuilder.group({
identifier: [''],
category_id: [''],
state_id: [''],
recommendation_id: [''],
2018-09-28 15:10:48 +02:00
submitters_id: [],
supporters_id: [],
origin: ['']
});
this.contentForm = this.formBuilder.group({
title: ['', Validators.required],
text: ['', Validators.required],
reason: ['']
2018-08-16 17:03:39 +02:00
});
}
2018-08-21 14:56:26 +02:00
/**
* 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
2018-08-23 10:35:05 +02:00
*
* TODO: state is not yet saved. Need a special "put" command
*
* TODO: Repo should handle
2018-08-21 14:56:26 +02:00
*/
public saveMotion(): void {
const newMotionValues = { ...this.metaInfoForm.value, ...this.contentForm.value };
const fromForm = new Motion();
fromForm.deserialize(newMotionValues);
if (this.newMotion) {
this.repo.create(fromForm).subscribe(response => {
2018-09-28 15:10:48 +02:00
if (response.id) {
this.router.navigate(['./motions/' + response.id]);
}
});
} else {
2018-09-28 15:10:48 +02:00
this.repo.update(fromForm, this.motionCopy).subscribe(response => {
// if the motion was successfully updated, change the edit mode.
// TODO: Show errors if there appear here
if (response.id) {
this.editMotion = false;
}
});
}
2018-08-16 17:03:39 +02:00
}
2018-09-28 15:10:48 +02:00
/**
* get the formated motion text from the repository.
*/
public getFormatedText(): string {
return this.repo.formatMotion(this.motion.id, this.motion.lnMode, this.motion.crMode);
}
2018-08-21 14:56:26 +02:00
/**
* Click on the edit button (pen-symbol)
*/
public editMotionButton(): void {
2018-08-16 17:03:39 +02:00
if (this.editMotion) {
2018-09-28 15:10:48 +02:00
this.saveMotion();
} else {
this.editMotion = true;
this.motionCopy = this.motion.copy();
2018-08-24 12:21:56 +02:00
this.patchForm(this.motionCopy);
2018-09-03 14:23:54 +02:00
if (this.vp.isMobile) {
this.metaInfoPanel.open();
this.contentPanel.open();
}
2018-08-16 17:03:39 +02:00
}
}
/**
* Cancel the editing process
*
* If a new motion was created, return to the list.
*/
public cancelEditMotionButton(): void {
if (this.newMotion) {
this.router.navigate(['./motions/']);
} else {
this.editMotion = false;
}
}
2018-08-21 14:56:26 +02:00
/**
2018-08-22 16:03:49 +02:00
* Trigger to delete the motion
*
* TODO: Repo should handle
2018-08-21 14:56:26 +02:00
*/
public deleteMotionButton(): void {
this.repo.delete(this.motion).subscribe(answer => {
2018-08-22 16:03:49 +02:00
this.router.navigate(['./motions/']);
});
}
2018-09-28 15:10:48 +02:00
/**
* Sets the motions line numbering mode
* @param mode Needs to fot to the enum defined in ViewMotion
*/
public setLineNumberingMode(mode: number): void {
this.motion.lnMode = mode;
}
/**
* Sets the motions change reco mode
* @param mode Needs to fot to the enum defined in ViewMotion
*/
public setChangeRecoMode(mode: number): void {
this.motion.crMode = mode;
}
2018-08-21 14:56:26 +02:00
/**
2018-08-22 16:03:49 +02:00
* Init. Does nothing here.
2018-08-21 14:56:26 +02:00
*/
public ngOnInit(): void {}
}