statute paragraphs list view
This commit is contained in:
parent
236dc21d62
commit
64f6f35e31
@ -1,4 +1,29 @@
|
|||||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
import { Permission } from '../../../core/services/operator.service';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One entry for the ellipsis menu.
|
||||||
|
*/
|
||||||
|
export interface EllipsisMenuItem {
|
||||||
|
/**
|
||||||
|
* The text for the menu entry
|
||||||
|
*/
|
||||||
|
text: string;
|
||||||
|
/**
|
||||||
|
* An optional icon to display before the text.
|
||||||
|
*/
|
||||||
|
icon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The action to be performed on click.
|
||||||
|
*/
|
||||||
|
action: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An optional permission to see this entry.
|
||||||
|
*/
|
||||||
|
perm?: Permission;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reusable head bar component for Apps.
|
* Reusable head bar component for Apps.
|
||||||
@ -38,9 +63,9 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
|||||||
* This will execute a function with the name provided in the
|
* This will execute a function with the name provided in the
|
||||||
* `action` field.
|
* `action` field.
|
||||||
* ```ts
|
* ```ts
|
||||||
* onEllipsisItem(event: any) {
|
* onEllipsisItem(item: EllipsisMenuItem) {
|
||||||
* if (event.action) {
|
* if (typeof this[item.action] === 'function') {
|
||||||
* this[event.action]();
|
* this[item.action]();
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
@ -69,7 +94,7 @@ export class HeadBarComponent implements OnInit {
|
|||||||
* The parent needs to provide a menu, i.e `[menuList]=myMenu`.
|
* The parent needs to provide a menu, i.e `[menuList]=myMenu`.
|
||||||
*/
|
*/
|
||||||
@Input()
|
@Input()
|
||||||
public menuList: any[];
|
public menuList: EllipsisMenuItem[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emit a signal to the parent component if the plus button was clicked
|
* Emit a signal to the parent component if the plus button was clicked
|
||||||
@ -81,7 +106,7 @@ export class HeadBarComponent implements OnInit {
|
|||||||
* Emit a signal to the parent of an item in the menuList was selected.
|
* Emit a signal to the parent of an item in the menuList was selected.
|
||||||
*/
|
*/
|
||||||
@Output()
|
@Output()
|
||||||
public ellipsisMenuItem = new EventEmitter<any>();
|
public ellipsisMenuItem = new EventEmitter<EllipsisMenuItem>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty constructor
|
* Empty constructor
|
||||||
@ -97,7 +122,7 @@ export class HeadBarComponent implements OnInit {
|
|||||||
* Emits a signal to the parent if an item in the menu was clicked.
|
* Emits a signal to the parent if an item in the menu was clicked.
|
||||||
* @param item
|
* @param item
|
||||||
*/
|
*/
|
||||||
public clickMenu(item: any): void {
|
public clickMenu(item: EllipsisMenuItem): void {
|
||||||
this.ellipsisMenuItem.emit(item);
|
this.ellipsisMenuItem.emit(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import { Title } from '@angular/platform-browser';
|
|||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { MatTableDataSource, MatTable, MatSort, MatPaginator } from '@angular/material';
|
import { MatTableDataSource, MatTable, MatSort, MatPaginator } from '@angular/material';
|
||||||
import { BaseViewModel } from './base-view-model';
|
import { BaseViewModel } from './base-view-model';
|
||||||
|
import { EllipsisMenuItem } from '../../shared/components/head-bar/head-bar.component';
|
||||||
|
|
||||||
export abstract class ListViewBaseComponent<V extends BaseViewModel> extends BaseComponent {
|
export abstract class ListViewBaseComponent<V extends BaseViewModel> extends BaseComponent {
|
||||||
/**
|
/**
|
||||||
@ -55,9 +56,9 @@ export abstract class ListViewBaseComponent<V extends BaseViewModel> extends Bas
|
|||||||
*
|
*
|
||||||
* @param event clicked entry from ellipsis menu
|
* @param event clicked entry from ellipsis menu
|
||||||
*/
|
*/
|
||||||
public onEllipsisItem(event: any): void {
|
public onEllipsisItem(item: EllipsisMenuItem): void {
|
||||||
if (event.action) {
|
if (typeof this[item.action] === 'function') {
|
||||||
this[event.action]();
|
this[item.action]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
<span translate>Edit section details:</span>
|
<span translate>Edit section details:</span>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input formControlName="name" matInput placeholder="{{'Name' | translate}}">
|
<input formControlName="name" matInput placeholder="{{'Name' | translate}}" required>
|
||||||
<mat-hint *ngIf="!updateForm.controls.name.valid">
|
<mat-hint *ngIf="!updateForm.controls.name.valid">
|
||||||
<span translate>Required</span>
|
<span translate>Required</span>
|
||||||
</mat-hint>
|
</mat-hint>
|
||||||
|
@ -46,6 +46,11 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
|
|||||||
{
|
{
|
||||||
text: 'Motion comment sections',
|
text: 'Motion comment sections',
|
||||||
action: 'toMotionCommentSections'
|
action: 'toMotionCommentSections'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Statute paragrpahs',
|
||||||
|
action: 'toStatuteParagraphs',
|
||||||
|
perm: 'motions.can_manage'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -141,6 +146,13 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
|
|||||||
this.router.navigate(['./comment-section'], { relativeTo: this.route });
|
this.router.navigate(['./comment-section'], { relativeTo: this.route });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* navigate to 'motion/statute-paragraphs'
|
||||||
|
*/
|
||||||
|
public toStatuteParagraphs(): void {
|
||||||
|
this.router.navigate(['./statute-paragraphs'], { relativeTo: this.route });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download all motions As PDF and DocX
|
* Download all motions As PDF and DocX
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,87 @@
|
|||||||
|
<os-head-bar appName="Statute paragraphs" [plusButton]=true (plusButtonClicked)=onPlusButton()
|
||||||
|
[menuList]="menuList" (ellipsisMenuItem)=onEllipsisItem($event)></os-head-bar>
|
||||||
|
<div class="head-spacer"></div>
|
||||||
|
<mat-card *ngIf="statuteParagraphToCreate">
|
||||||
|
<mat-card-title translate>Create new statute paragraph</mat-card-title>
|
||||||
|
<mat-card-content>
|
||||||
|
<form [formGroup]="createForm">
|
||||||
|
<p>
|
||||||
|
<mat-form-field>
|
||||||
|
<input formControlName="title" matInput placeholder="{{'Title' | translate}}" required>
|
||||||
|
<mat-hint *ngIf="!createForm.controls.title.valid">
|
||||||
|
<span translate>Required</span>
|
||||||
|
</mat-hint>
|
||||||
|
</mat-form-field>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<mat-form-field>
|
||||||
|
<textarea formControlName="text" matInput placeholder="{{'Statute paragraph' | translate}}" required></textarea>
|
||||||
|
<mat-hint *ngIf="!createForm.controls.text.valid">
|
||||||
|
<span translate>Required</span>
|
||||||
|
</mat-hint>
|
||||||
|
</mat-form-field>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-card-actions>
|
||||||
|
<button mat-button (click)="create()" translate>Create</button>
|
||||||
|
<button mat-button (click)="statuteParagraphToCreate = null" translate>Abort</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
</mat-card>
|
||||||
|
<mat-accordion class="os-card">
|
||||||
|
<mat-expansion-panel *ngFor="let statuteParagraph of this.statuteParagraphs" (opened)="openId = statuteParagraph.id"
|
||||||
|
(closed)="panelClosed(statuteParagraph)" [expanded]="openId === statuteParagraph.id" multiple="false">
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
<mat-panel-title>
|
||||||
|
{{ statuteParagraph.title }}
|
||||||
|
</mat-panel-title>
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
<form [formGroup]="updateForm" *ngIf="editId === statuteParagraph.id">
|
||||||
|
<span translate>Edit statute paragraph details:</span>
|
||||||
|
<p>
|
||||||
|
<mat-form-field>
|
||||||
|
<input formControlName="title" matInput placeholder="{{'Title' | translate}}" required>
|
||||||
|
<mat-hint *ngIf="!updateForm.controls.title.valid">
|
||||||
|
<span translate>Required</span>
|
||||||
|
</mat-hint>
|
||||||
|
</mat-form-field>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<mat-form-field>
|
||||||
|
<textarea formControlName="text" matInput placeholder="{{'Statute paragraph' | translate}}" required></textarea>
|
||||||
|
<mat-hint *ngIf="!createForm.controls.text.valid">
|
||||||
|
<span translate>Required</span>
|
||||||
|
</mat-hint>
|
||||||
|
</mat-form-field>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
<ng-container *ngIf="editId !== statuteParagraph.id">
|
||||||
|
<mat-card>
|
||||||
|
<mat-card-title>{{ statuteParagraph.title }}</mat-card-title>
|
||||||
|
<mat-card-content>
|
||||||
|
<div [innerHTML]="statuteParagraph.text"></div>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</ng-container>
|
||||||
|
<mat-action-row>
|
||||||
|
<button *ngIf="editId !== statuteParagraph.id" mat-button class="on-transition-fade" (click)="onEditButton(statuteParagraph)"
|
||||||
|
mat-icon-button>
|
||||||
|
<mat-icon>edit</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button *ngIf="editId === statuteParagraph.id" mat-button class="on-transition-fade" (click)="editId = null"
|
||||||
|
mat-icon-button>
|
||||||
|
<mat-icon>cancel</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button *ngIf="editId === statuteParagraph.id" mat-button class="on-transition-fade" (click)="onSaveButton(statuteParagraph)"
|
||||||
|
mat-icon-button>
|
||||||
|
<mat-icon>save</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-button class='on-transition-fade' (click)=onDeleteButton(statuteParagraph) mat-icon-button>
|
||||||
|
<mat-icon>delete</mat-icon>
|
||||||
|
</button>
|
||||||
|
</mat-action-row>
|
||||||
|
</mat-expansion-panel>
|
||||||
|
</mat-accordion>
|
||||||
|
<mat-card *ngIf="statuteParagraphs.length === 0">
|
||||||
|
<mat-card-content><div class="noContent" translate>No statute paragraphs yet...</div></mat-card-content>
|
||||||
|
</mat-card>
|
@ -0,0 +1,17 @@
|
|||||||
|
.head-spacer {
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
line-height: 60px;
|
||||||
|
text-align: right;
|
||||||
|
background: white; /* TODO: remove this and replace with theme */
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-card {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noContent {
|
||||||
|
text-align: center;
|
||||||
|
color: gray; /* TODO: remove this and replace with theme */
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { StatuteParagraphListComponent } from './statute-paragraph-list.component';
|
||||||
|
import { E2EImportsModule } from 'e2e-imports.module';
|
||||||
|
|
||||||
|
describe('StatuteParagraphListComponent', () => {
|
||||||
|
let component: StatuteParagraphListComponent;
|
||||||
|
let fixture: ComponentFixture<StatuteParagraphListComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [E2EImportsModule],
|
||||||
|
declarations: [StatuteParagraphListComponent]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(StatuteParagraphListComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,169 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Title } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { BaseComponent } from '../../../../base.component';
|
||||||
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||||
|
import { PromptService } from '../../../../core/services/prompt.service';
|
||||||
|
import { StatuteParagraph } from '../../../../shared/models/motions/statute-paragraph';
|
||||||
|
import { ViewStatuteParagraph } from '../../models/view-statute-paragraph';
|
||||||
|
import { StatuteParagraphRepositoryService } from '../../services/statute-paragraph-repository.service';
|
||||||
|
import { EllipsisMenuItem } from '../../../../shared/components/head-bar/head-bar.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List view for the statute paragraphs.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'os-statute-paragraph-list',
|
||||||
|
templateUrl: './statute-paragraph-list.component.html',
|
||||||
|
styleUrls: ['./statute-paragraph-list.component.scss']
|
||||||
|
})
|
||||||
|
export class StatuteParagraphListComponent extends BaseComponent implements OnInit {
|
||||||
|
/**
|
||||||
|
* content of the ellipsis menu
|
||||||
|
*/
|
||||||
|
public menuList: EllipsisMenuItem[] = [
|
||||||
|
{
|
||||||
|
text: 'Sort statute paragraphs',
|
||||||
|
action: 'sortStatuteParagraphs'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
public statuteParagraphToCreate: StatuteParagraph | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source of the Data
|
||||||
|
*/
|
||||||
|
public statuteParagraphs: ViewStatuteParagraph[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current focussed formgroup
|
||||||
|
*/
|
||||||
|
public updateForm: FormGroup;
|
||||||
|
|
||||||
|
public createForm: FormGroup;
|
||||||
|
|
||||||
|
public openId: number | null;
|
||||||
|
public editId: number | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The usual component constructor
|
||||||
|
* @param titleService
|
||||||
|
* @param translate
|
||||||
|
* @param repo
|
||||||
|
* @param formBuilder
|
||||||
|
*/
|
||||||
|
public constructor(
|
||||||
|
protected titleService: Title,
|
||||||
|
protected translate: TranslateService,
|
||||||
|
private repo: StatuteParagraphRepositoryService,
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private promptService: PromptService
|
||||||
|
) {
|
||||||
|
super(titleService, translate);
|
||||||
|
const form = {
|
||||||
|
title: ['', Validators.required],
|
||||||
|
text: ['', Validators.required]
|
||||||
|
};
|
||||||
|
this.createForm = this.formBuilder.group(form);
|
||||||
|
this.updateForm = this.formBuilder.group(form);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init function.
|
||||||
|
*
|
||||||
|
* Sets the title and gets/observes statute paragrpahs from DataStore
|
||||||
|
*/
|
||||||
|
public ngOnInit(): void {
|
||||||
|
super.setTitle('Statute paragraphs');
|
||||||
|
this.repo.getViewModelListObservable().subscribe(newViewStatuteParagraphs => {
|
||||||
|
this.statuteParagraphs = newViewStatuteParagraphs;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new Section.
|
||||||
|
*/
|
||||||
|
public onPlusButton(): void {
|
||||||
|
if (!this.statuteParagraphToCreate) {
|
||||||
|
this.createForm.reset();
|
||||||
|
this.createForm.setValue({
|
||||||
|
title: '',
|
||||||
|
text: ''
|
||||||
|
});
|
||||||
|
this.statuteParagraphToCreate = new StatuteParagraph();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public create(): void {
|
||||||
|
if (this.createForm.valid) {
|
||||||
|
this.statuteParagraphToCreate.patchValues(this.createForm.value as StatuteParagraph);
|
||||||
|
this.repo.create(this.statuteParagraphToCreate).subscribe(resp => {
|
||||||
|
this.statuteParagraphToCreate = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executed on edit button
|
||||||
|
* @param viewStatuteParagraph
|
||||||
|
*/
|
||||||
|
public onEditButton(viewStatuteParagraph: ViewStatuteParagraph): void {
|
||||||
|
this.editId = viewStatuteParagraph.id;
|
||||||
|
|
||||||
|
this.updateForm.setValue({
|
||||||
|
title: viewStatuteParagraph.title,
|
||||||
|
text: viewStatuteParagraph.text
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the statute paragrpah
|
||||||
|
*/
|
||||||
|
public onSaveButton(viewStatuteParagraph: ViewStatuteParagraph): void {
|
||||||
|
if (this.updateForm.valid) {
|
||||||
|
this.repo
|
||||||
|
.update(this.updateForm.value as Partial<StatuteParagraph>, viewStatuteParagraph)
|
||||||
|
.subscribe(resp => {
|
||||||
|
this.openId = this.editId = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is executed, when the delete button is pressed
|
||||||
|
*/
|
||||||
|
public async onDeleteButton(viewStatuteParagraph: ViewStatuteParagraph): Promise<any> {
|
||||||
|
const content = this.translate.instant('Delete') + ` ${viewStatuteParagraph.title}?`;
|
||||||
|
if (await this.promptService.open('Are you sure?', content)) {
|
||||||
|
this.repo.delete(viewStatuteParagraph).subscribe(resp => {
|
||||||
|
this.openId = this.editId = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is executed when a mat-extension-panel is closed
|
||||||
|
* @param viewStatuteParagraph the statute paragraph in the panel
|
||||||
|
*/
|
||||||
|
public panelClosed(viewStatuteParagraph: ViewStatuteParagraph): void {
|
||||||
|
this.openId = null;
|
||||||
|
if (this.editId) {
|
||||||
|
this.onSaveButton(viewStatuteParagraph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public onEllipsisItem(item: EllipsisMenuItem): void {
|
||||||
|
if (item.action === 'sortStatuteParagrpahs') {
|
||||||
|
this.sortStatuteParagrpahs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: navigate to a sorting view
|
||||||
|
*/
|
||||||
|
public sortStatuteParagrpahs(): void {
|
||||||
|
console.log('sort statute paragraphs');
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
import { Category } from '../../../shared/models/motions/category';
|
import { Category } from '../../../shared/models/motions/category';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import { BaseViewModel } from '../../base/base-view-model';
|
import { BaseViewModel } from '../../base/base-view-model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +76,7 @@ export class ViewCategory extends BaseViewModel {
|
|||||||
this._opened = false;
|
this._opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTitle(translate?: TranslateService): string {
|
public getTitle(): string {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import { BaseViewModel } from '../../base/base-view-model';
|
import { BaseViewModel } from '../../base/base-view-model';
|
||||||
import { MotionCommentSection } from '../../../shared/models/motions/motion-comment-section';
|
import { MotionCommentSection } from '../../../shared/models/motions/motion-comment-section';
|
||||||
import { Group } from '../../../shared/models/users/group';
|
import { Group } from '../../../shared/models/users/group';
|
||||||
@ -17,9 +16,6 @@ export class ViewMotionCommentSection extends BaseViewModel {
|
|||||||
private _read_groups: Group[];
|
private _read_groups: Group[];
|
||||||
private _write_groups: Group[];
|
private _write_groups: Group[];
|
||||||
|
|
||||||
public edit = false;
|
|
||||||
public open = false;
|
|
||||||
|
|
||||||
public get section(): MotionCommentSection {
|
public get section(): MotionCommentSection {
|
||||||
return this._section;
|
return this._section;
|
||||||
}
|
}
|
||||||
@ -59,7 +55,7 @@ export class ViewMotionCommentSection extends BaseViewModel {
|
|||||||
this._write_groups = write_groups;
|
this._write_groups = write_groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTitle(translate?: TranslateService): string {
|
public getTitle(): string {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import { Workflow } from '../../../shared/models/motions/workflow';
|
|||||||
import { WorkflowState } from '../../../shared/models/motions/workflow-state';
|
import { WorkflowState } from '../../../shared/models/motions/workflow-state';
|
||||||
import { BaseModel } from '../../../shared/models/base/base-model';
|
import { BaseModel } from '../../../shared/models/base/base-model';
|
||||||
import { BaseViewModel } from '../../base/base-view-model';
|
import { BaseViewModel } from '../../base/base-view-model';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
enum LineNumbering {
|
enum LineNumbering {
|
||||||
None,
|
None,
|
||||||
@ -182,7 +181,7 @@ export class ViewMotion extends BaseViewModel {
|
|||||||
this.crMode = ChangeReco.Original;
|
this.crMode = ChangeReco.Original;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTitle(translate?: TranslateService): string {
|
public getTitle(): string {
|
||||||
return this.title;
|
return this.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
66
client/src/app/site/motions/models/view-statute-paragraph.ts
Normal file
66
client/src/app/site/motions/models/view-statute-paragraph.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import { BaseViewModel } from '../../base/base-view-model';
|
||||||
|
import { Group } from '../../../shared/models/users/group';
|
||||||
|
import { BaseModel } from '../../../shared/models/base/base-model';
|
||||||
|
import { StatuteParagraph } from '../../../shared/models/motions/statute-paragraph';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State paragrpah class for the View
|
||||||
|
*
|
||||||
|
* Stores a statute paragraph including all (implicit) references
|
||||||
|
* Provides "safe" access to variables and functions in {@link StatuteParagraph}
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
export class ViewStatuteParagraph extends BaseViewModel {
|
||||||
|
private _paragraph: StatuteParagraph;
|
||||||
|
|
||||||
|
public get statuteParagraph(): StatuteParagraph {
|
||||||
|
return this._paragraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get id(): number {
|
||||||
|
return this.statuteParagraph ? this.statuteParagraph.id : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get title(): string {
|
||||||
|
return this.statuteParagraph ? this.statuteParagraph.title : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get text(): string {
|
||||||
|
return this.statuteParagraph ? this.statuteParagraph.text : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get weight(): number {
|
||||||
|
return this.statuteParagraph ? this.statuteParagraph.weight : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public constructor(paragraph: StatuteParagraph) {
|
||||||
|
super();
|
||||||
|
this._paragraph = paragraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTitle(): string {
|
||||||
|
return this.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the local objects if required
|
||||||
|
* @param section
|
||||||
|
*/
|
||||||
|
public updateValues(paragraph: BaseModel): void {
|
||||||
|
if (paragraph instanceof StatuteParagraph) {
|
||||||
|
this._paragraph = paragraph as StatuteParagraph;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement updating of groups
|
||||||
|
public updateGroup(group: Group): void {
|
||||||
|
console.log(this._paragraph, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duplicate this motion into a copy of itself
|
||||||
|
*/
|
||||||
|
public copy(): ViewStatuteParagraph {
|
||||||
|
return new ViewStatuteParagraph(this._paragraph);
|
||||||
|
}
|
||||||
|
}
|
@ -4,11 +4,13 @@ import { MotionListComponent } from './components/motion-list/motion-list.compon
|
|||||||
import { MotionDetailComponent } from './components/motion-detail/motion-detail.component';
|
import { MotionDetailComponent } from './components/motion-detail/motion-detail.component';
|
||||||
import { CategoryListComponent } from './components/category-list/category-list.component';
|
import { CategoryListComponent } from './components/category-list/category-list.component';
|
||||||
import { MotionCommentSectionListComponent } from './components/motion-comment-section-list/motion-comment-section-list.component';
|
import { MotionCommentSectionListComponent } from './components/motion-comment-section-list/motion-comment-section-list.component';
|
||||||
|
import { StatuteParagraphListComponent } from './components/statute-paragraph-list/statute-paragraph-list.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', component: MotionListComponent },
|
{ path: '', component: MotionListComponent },
|
||||||
{ path: 'category', component: CategoryListComponent },
|
{ path: 'category', component: CategoryListComponent },
|
||||||
{ path: 'comment-section', component: MotionCommentSectionListComponent },
|
{ path: 'comment-section', component: MotionCommentSectionListComponent },
|
||||||
|
{ path: 'statute-paragraphs', component: StatuteParagraphListComponent },
|
||||||
{ path: 'new', component: MotionDetailComponent },
|
{ path: 'new', component: MotionDetailComponent },
|
||||||
{ path: ':id', component: MotionDetailComponent }
|
{ path: ':id', component: MotionDetailComponent }
|
||||||
];
|
];
|
||||||
|
@ -7,9 +7,16 @@ import { MotionListComponent } from './components/motion-list/motion-list.compon
|
|||||||
import { MotionDetailComponent } from './components/motion-detail/motion-detail.component';
|
import { MotionDetailComponent } from './components/motion-detail/motion-detail.component';
|
||||||
import { CategoryListComponent } from './components/category-list/category-list.component';
|
import { CategoryListComponent } from './components/category-list/category-list.component';
|
||||||
import { MotionCommentSectionListComponent } from './components/motion-comment-section-list/motion-comment-section-list.component';
|
import { MotionCommentSectionListComponent } from './components/motion-comment-section-list/motion-comment-section-list.component';
|
||||||
|
import { StatuteParagraphListComponent } from './components/statute-paragraph-list/statute-paragraph-list.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [CommonModule, MotionsRoutingModule, SharedModule],
|
imports: [CommonModule, MotionsRoutingModule, SharedModule],
|
||||||
declarations: [MotionListComponent, MotionDetailComponent, CategoryListComponent, MotionCommentSectionListComponent]
|
declarations: [
|
||||||
|
MotionListComponent,
|
||||||
|
MotionDetailComponent,
|
||||||
|
CategoryListComponent,
|
||||||
|
MotionCommentSectionListComponent,
|
||||||
|
StatuteParagraphListComponent
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class MotionsModule {}
|
export class MotionsModule {}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { E2EImportsModule } from 'e2e-imports.module';
|
||||||
|
import { StatuteParagraphRepositoryService } from './statute-paragraph-repository.service';
|
||||||
|
|
||||||
|
describe('StatuteParagraphRepositoryService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [E2EImportsModule],
|
||||||
|
providers: [StatuteParagraphRepositoryService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject(
|
||||||
|
[StatuteParagraphRepositoryService],
|
||||||
|
(service: StatuteParagraphRepositoryService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}
|
||||||
|
));
|
||||||
|
});
|
@ -0,0 +1,50 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { DataSendService } from '../../../core/services/data-send.service';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { DataStoreService } from '../../../core/services/data-store.service';
|
||||||
|
import { BaseRepository } from '../../base/base-repository';
|
||||||
|
import { ViewStatuteParagraph } from '../models/view-statute-paragraph';
|
||||||
|
import { StatuteParagraph } from '../../../shared/models/motions/statute-paragraph';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repository Services for statute paragraphs
|
||||||
|
*
|
||||||
|
* Rather than manipulating models directly, the repository is meant to
|
||||||
|
* inform the {@link DataSendService} about changes which will send
|
||||||
|
* them to the Server.
|
||||||
|
*/
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class StatuteParagraphRepositoryService extends BaseRepository<ViewStatuteParagraph, StatuteParagraph> {
|
||||||
|
/**
|
||||||
|
* Creates a StatuteParagraphRepository
|
||||||
|
* Converts existing and incoming statute paragraphs to ViewStatuteParagraphs
|
||||||
|
* Handles CRUD using an observer to the DataStore
|
||||||
|
* @param DataSend
|
||||||
|
*/
|
||||||
|
public constructor(protected DS: DataStoreService, private dataSend: DataSendService) {
|
||||||
|
super(DS, StatuteParagraph);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected createViewModel(statuteParagraph: StatuteParagraph): ViewStatuteParagraph {
|
||||||
|
return new ViewStatuteParagraph(statuteParagraph);
|
||||||
|
}
|
||||||
|
|
||||||
|
public create(statuteParagraph: StatuteParagraph): Observable<any> {
|
||||||
|
return this.dataSend.createModel(statuteParagraph);
|
||||||
|
}
|
||||||
|
|
||||||
|
public update(
|
||||||
|
statuteParagraph: Partial<StatuteParagraph>,
|
||||||
|
viewStatuteParagraph: ViewStatuteParagraph
|
||||||
|
): Observable<any> {
|
||||||
|
const updateParagraph = viewStatuteParagraph.statuteParagraph;
|
||||||
|
updateParagraph.patchValues(statuteParagraph);
|
||||||
|
return this.dataSend.updateModel(updateParagraph, 'put');
|
||||||
|
}
|
||||||
|
|
||||||
|
public delete(viewStatuteParagraph: ViewStatuteParagraph): Observable<any> {
|
||||||
|
return this.dataSend.delete(viewStatuteParagraph.statuteParagraph);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user