Merge pull request #3970 from FinnStutzenstein/refineCategories

refine category editing and motion numbering. Fixes the current behav…
This commit is contained in:
Jochen Saalfeld 2018-11-08 16:12:13 +01:00 committed by GitHub
commit 11a5335777
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 80 deletions

View File

@ -39,7 +39,8 @@
</mat-card> </mat-card>
<mat-accordion class="os-card"> <mat-accordion class="os-card">
<mat-expansion-panel *ngFor="let category of this.categories" multiple="false"> <mat-expansion-panel *ngFor="let category of categories" (opened)="openId = category.id" (closed)="panelClosed(category)"
[expanded]="openId === category.id" multiple="false">
<!-- Header shows Prefix and name --> <!-- Header shows Prefix and name -->
<mat-expansion-panel-header> <mat-expansion-panel-header>
@ -50,7 +51,7 @@
{{ category.prefix }} {{ category.prefix }}
</div> </div>
<div *ngIf="editId === category.id"> <div *ngIf="editId === category.id">
{{ this.updateForm.get('prefix').value }} {{ updateForm.get('prefix').value }}
</div> </div>
</div> </div>
<div class="header-name"> <div class="header-name">
@ -58,7 +59,7 @@
{{ category.name }} {{ category.name }}
</div> </div>
<div *ngIf="editId === category.id"> <div *ngIf="editId === category.id">
{{ this.updateForm.get('name').value }} {{ updateForm.get('name').value }}
</div> </div>
</div> </div>
<div class="header-size"> <div class="header-size">
@ -69,17 +70,17 @@
</mat-expansion-panel-header> </mat-expansion-panel-header>
<!-- Edit form shows during the edit event --> <!-- Edit form shows during the edit event -->
<form [formGroup]='this.updateForm' *ngIf="editId === category.id" (keydown)="keyDownFunction($event, category)"> <form id="updateForm" [formGroup]='updateForm' *ngIf="editId === category.id" (keydown)="keyDownFunction($event, category)">
<span translate>Edit category details:</span><br> <span translate>Edit category details</span>:<br>
<mat-form-field> <mat-form-field>
<input formControlName="prefix" matInput placeholder="{{'Prefix' | translate}}"> <input formControlName="prefix" matInput placeholder="{{'Prefix' | translate}}" required>
<mat-hint> <mat-hint *ngIf="!updateForm.controls.prefix.valid">
<span translate>Required</span> <span translate>Required</span>
</mat-hint> </mat-hint>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<input formControlName="name" matInput placeholder="{{'Name' | translate}}"> <input formControlName="name" matInput placeholder="{{'Name' | translate}}" required>
<mat-hint> <mat-hint *ngIf="!updateForm.controls.name.valid">
<span translate>Required</span> <span translate>Required</span>
</mat-hint> </mat-hint>
</mat-form-field> </mat-form-field>
@ -87,10 +88,10 @@
<!-- Show and sort corresponding motions--> <!-- Show and sort corresponding motions-->
<div *ngIf="motionsInCategory(category).length > 0"> <div *ngIf="motionsInCategory(category).length > 0">
<span translate>Motions:</span> <span translate>Motions</span>:
<div *ngIf="editId !== category.id"> <div *ngIf="editId !== category.id">
<ul *ngFor="let motion of motionsInCategory(category)"> <ul *ngFor="let motion of motionsInCategory(category)">
<li>{{motion}}</li> <li>{{ motion }}</li>
</ul> </ul>
</div> </div>
<div *ngIf="editId === category.id"> <div *ngIf="editId === category.id">

View File

@ -40,3 +40,7 @@
text-align: center; text-align: center;
} }
} }
#updateForm {
margin-bottom: 20px;
}

View File

@ -32,10 +32,15 @@ export class CategoryListComponent extends BaseViewComponent implements OnInit {
*/ */
public editId: number | null; public editId: number | null;
/**
* Determine which category is opened.
*/
public openId: number | null;
/** /**
* Source of the data * Source of the data
*/ */
public categories: Array<ViewCategory>; public categories: ViewCategory[];
/** /**
* For new categories * For new categories
@ -146,31 +151,36 @@ export class CategoryListComponent extends BaseViewComponent implements OnInit {
/** /**
* Saves the category * Saves the category
*
* TODO: Do not number the motions. This needs to be a separate button (maybe with propting for confirmation), because
* not every body uses this and this would destroy their own order in motion identifiers.
* See issue #3969
*
* @param viewCategory * @param viewCategory
*/ */
public async onSaveButton(viewCategory: ViewCategory): Promise<void> { public async onSaveButton(viewCategory: ViewCategory): Promise<void> {
if (this.updateForm.valid) { // get the sorted motions. Save them before updating the category.
// TODO: Check the motion sorting code below. If it is removed, change to .then() syntax. let sortedMotionIds;
try { if (this.sortSelector) {
await this.repo.update(this.updateForm.value as Partial<Category>, viewCategory); sortedMotionIds = this.sortSelector.array.map(selectable => selectable.id);
} catch (e) { this.repo.numberMotionsInCategory(viewCategory.category, sortedMotionIds);
this.raiseError(e);
}
this.onCancelButton();
this.sortDataSource();
} }
// get the sorted motions if (this.updateForm.valid) {
// wait for the category to update; then the (maybe) changed prefix can be applied to the motions
await this.repo.update(this.updateForm.value as Partial<Category>, viewCategory);
this.onCancelButton();
if (this.sortSelector) { if (this.sortSelector) {
const manuallySortedMotions = this.sortSelector.array as Motion[]; this.repo.numberMotionsInCategory(viewCategory.category, sortedMotionIds);
await this.repo.updateCategoryNumbering(viewCategory.category, manuallySortedMotions); }
} }
} }
/** /**
* sorts the categories by prefix * sorts the categories by prefix
*/ */
protected sortDataSource(): void { private sortDataSource(): void {
this.categories.sort((viewCategory1, viewCategory2) => (viewCategory1 > viewCategory2 ? 1 : -1)); this.categories.sort((viewCategory1, viewCategory2) => (viewCategory1 > viewCategory2 ? 1 : -1));
} }
@ -196,10 +206,22 @@ export class CategoryListComponent extends BaseViewComponent implements OnInit {
/** /**
* Returns the motions corresponding to a category * Returns the motions corresponding to a category
* @param category target * @param category target
* @returns all motions in the category
*/ */
public motionsInCategory(category: Category): Array<Motion> { public motionsInCategory(category: Category): Motion[] {
const motList = this.repo.getMotionsOfCategory(category); const motions = this.repo.getMotionsOfCategory(category);
motList.sort((motion1, motion2) => (motion1 > motion2 ? 1 : -1)); motions.sort((motion1, motion2) => (motion1 > motion2 ? 1 : -1));
return motList; return motions;
}
/**
* Is executed when a mat-extension-panel is closed
* @param viewCategory the category in the panel
*/
public panelClosed(viewCategory: ViewCategory): void {
this.openId = null;
if (this.editId) {
this.onSaveButton(viewCategory);
}
} }
} }

View File

@ -323,16 +323,9 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
* shows a "are you sure" dialog * shows a "are you sure" dialog
*/ */
public async deleteMotionButton(): Promise<void> { public async deleteMotionButton(): Promise<void> {
await this.repo.delete(this.motion).then(); this.repo.delete(this.motion).then(() => {
this.router.navigate(['./motions/']); this.router.navigate(['./motions/']);
}, this.raiseError);
// This should happen during auto update
// const motList = this.categoryRepo.getMotionsOfCategory(this.motion.category);
// const index = motList.indexOf(this.motion.motion, 0);
// if (index > -1) {
// motList.splice(index, 1);
// }
// this.categoryRepo.updateCategoryNumbering(this.motion.category, motList);
} }
/** /**

View File

@ -1,22 +0,0 @@
import { Motion } from '../../../shared/models/motions/motion';
/**
* wrapper class for the HTTP Call
*/
export class CategoryNumbering {
private motions: number[];
public constructor() {}
public setMotions(motionList: Motion[]): void {
const motion_id_list: number[] = [];
motionList.forEach(motion => {
motion_id_list.push(motion.id);
});
this.motions = motion_id_list;
}
public getMotions(): number[] {
return this.motions;
}
}

View File

@ -5,7 +5,6 @@ import { DataSendService } from '../../../core/services/data-send.service';
import { DataStoreService } from '../../../core/services/data-store.service'; import { DataStoreService } from '../../../core/services/data-store.service';
import { BaseRepository } from '../../base/base-repository'; import { BaseRepository } from '../../base/base-repository';
import { Motion } from '../../../shared/models/motions/motion'; import { Motion } from '../../../shared/models/motions/motion';
import { CategoryNumbering } from '../models/category-numbering';
import { HttpService } from '../../../core/services/http.service'; import { HttpService } from '../../../core/services/http.service';
import { Identifiable } from '../../../shared/models/base/identifiable'; import { Identifiable } from '../../../shared/models/base/identifiable';
import { CollectionStringModelMapperService } from '../../../core/services/collectionStringModelMapper.service'; import { CollectionStringModelMapperService } from '../../../core/services/collectionStringModelMapper.service';
@ -28,7 +27,9 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
* Creates a CategoryRepository * Creates a CategoryRepository
* Converts existing and incoming category to ViewCategories * Converts existing and incoming category to ViewCategories
* Handles CRUD using an observer to the DataStore * Handles CRUD using an observer to the DataStore
* @param DataSend * @param DS
* @param dataSend
* @param httpService
*/ */
public constructor( public constructor(
protected DS: DataStoreService, protected DS: DataStoreService,
@ -64,10 +65,10 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
} }
/** /**
* Returns all Motions belonging to a category * Returns all motions belonging to a category
* @param category category * @param category category
*/ */
public getMotionsOfCategory(category: Category): Array<Motion> { public getMotionsOfCategory(category: Category): Motion[] {
const motList = this.DS.getAll(Motion); const motList = this.DS.getAll(Motion);
const retList: Array<Motion> = []; const retList: Array<Motion> = [];
motList.forEach(motion => { motList.forEach(motion => {
@ -89,23 +90,12 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
} }
/** /**
* Updates a Categories numbering * Updates a categories numbering.
* @param category the category it should be updated in * @param category the category it should be updated in
* @param motionList the list of motions on this category * @param motionList the list of motions on this category
*/ */
public async updateCategoryNumbering(category: Category, motionList: Motion[]): Promise<void> { public async numberMotionsInCategory(category: Category, motionIds: number[]): Promise<void> {
const categoryNumbering = new CategoryNumbering();
categoryNumbering.setMotions(motionList);
await this.sentCategoryNumbering(category, categoryNumbering);
}
/**
* Save category in the server
*
* @return Observable from
*/
protected async sentCategoryNumbering(category: Category, categoryNumbering: CategoryNumbering): Promise<void> {
const collectionString = 'rest/motions/category/' + category.id + '/numbering/'; const collectionString = 'rest/motions/category/' + category.id + '/numbering/';
await this.httpService.post(collectionString, categoryNumbering); await this.httpService.post(collectionString, { motions: motionIds });
} }
} }