Merge pull request #3950 from FinnStutzenstein/refineHttpService

Refine the HTTP Service.
This commit is contained in:
Sean 2018-11-01 11:30:20 +01:00 committed by GitHub
commit 4f7d860280
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 329 additions and 400 deletions

View File

@ -1,6 +1,7 @@
import { TranslateLoader } from '@ngx-translate/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators/';
import { Observable } from 'rxjs';
/**
* Translation loader that replaces empty strings with nothing.
@ -28,7 +29,7 @@ export class PruningTranslationLoader implements TranslateLoader {
* Loads a language file, stores the content, give it to the process function.
* @param lang language string (en, fr, de, ...)
*/
public getTranslation(lang: string): any {
public getTranslation(lang: string): Observable<any> {
return this.http.get(`${this.prefix}${lang}${this.suffix}`).pipe(map((res: Object) => this.process(res)));
}

View File

@ -1,11 +1,10 @@
import { Injectable } from '@angular/core';
import { BaseModel } from '../../shared/models/base/base-model';
import { Observable } from 'rxjs';
import { HttpService } from './http.service';
import { HTTPMethod } from './http.service';
import { Identifiable } from '../../shared/models/base/identifiable';
/**
* Send data back to server
* Send data back to server. Cares about the right REST routes.
*
* Contrast to dataStore service
*/
@ -16,38 +15,47 @@ export class DataSendService {
/**
* Construct a DataSendService
*
* @param httpService The HTTP Client
* @param httpService The HTTP Service
*/
public constructor(private httpService: HttpService) {}
/**
* Sends a post request with the model to the server.
* Usually for new Models
* Sends a post request with the model to the server to create it.
*
* @param model The model to create.
*/
public createModel(model: BaseModel): Observable<BaseModel> {
public async createModel(model: BaseModel): Promise<Identifiable> {
const restPath = `rest/${model.collectionString}/`;
return this.httpService.create(restPath, model) as Observable<BaseModel>;
return await this.httpService.post<Identifiable>(restPath, model);
}
/**
* Function to change a model on the server.
* Function to fully update a model on the server.
*
* @param model the base model that is meant to be changed
* @param method the required http method. might be put or patch
* @param model The model that is meant to be changed.
*/
public updateModel(model: BaseModel, method: HTTPMethod): Observable<BaseModel> {
const restPath = `rest/${model.collectionString}/${model.id}`;
return this.httpService.update(restPath, model, method) as Observable<BaseModel>;
public async updateModel(model: BaseModel): Promise<void> {
const restPath = `rest/${model.collectionString}/${model.id}/`;
await this.httpService.put(restPath, model);
}
/**
* Deletes the given model on the server
* Updates a model partially on the server.
*
* @param model the BaseModel that shall be removed
* @return Observable of BaseModel
* @param model The model to partially update.
*/
public deleteModel(model: BaseModel): Observable<BaseModel> {
const restPath = `rest/${model.collectionString}/${model.id}`;
return this.httpService.delete(restPath) as Observable<BaseModel>;
public async partialUpdateModel(model: BaseModel): Promise<void> {
const restPath = `rest/${model.collectionString}/${model.id}/`;
await this.httpService.patch(restPath, model);
}
/**
* Deletes the given model on the server.
*
* @param model the model that shall be deleted.
*/
public async deleteModel(model: BaseModel): Promise<void> {
const restPath = `rest/${model.collectionString}/${model.id}/`;
await this.httpService.delete(restPath);
}
}

View File

@ -1,105 +1,92 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
/**
* Enum for different HTTPMethods
*/
export enum HTTPMethod {
PUT,
PATCH
GET = 'get',
POST = 'post',
PUT = 'put',
PATCH = 'patch',
DELETE = 'delete'
}
/**
* Service for managing HTTP requests. Allows to send data for every method. Also (TODO) will do generic error handling.
*/
@Injectable({
providedIn: 'root'
})
/**
* Service for sending data back to server
*/
export class HttpService {
/**
* Construct a DataSendService
* Construct a HttpService
*
* @param http The HTTP Client
*/
public constructor(private http: HttpClient) {}
private async send<T>(url: string, method: HTTPMethod, data?: any): Promise<T> {
if (!url.endsWith('/')) {
url += '/';
}
const options = {
body: data,
};
try {
const response = await this.http.request<T>(method, url, options).toPromise();
return response;
} catch (e) {
console.log("error", e);
throw e;
}
}
/**
* Exectures a get on a url with a certain object
* @param url The url to send the request to.
* @param data An optional payload for the request.
*/
public async get<T>(url: string, data?: any): Promise<T> {
return await this.send<T>(url, HTTPMethod.GET, data);
}
/**
* Exectures a post on a url with a certain object
* @param url string of the url to send semothing to
* @param obj the object that should be send
* @param data The data to send
*/
public create(url: string, obj: object): Observable<object> {
url = this.formatForSlash(url);
return this.http.post<object>(url, obj).pipe(
tap(
response => {
// TODO: Message, Notify, Etc
console.log('New object added. Response :\n ', response);
},
error => console.error('Error:\n ', error)
)
);
public async post<T>(url: string, data: any): Promise<T> {
return await this.send<T>(url, HTTPMethod.POST, data);
}
/**
* Adds a / at the end, if there is none
* @param str the string where the / should be checked
*/
private formatForSlash(str: string): string {
let retStr = '';
retStr += str;
return retStr.endsWith('/') ? retStr : (retStr += '/');
}
/**
* Save object in the server
*
* Exectures a put on a url with a certain object
* @param url string of the url to send semothing to
* @param obj the object that should be send
* @param method the HTTP Method that should be used {@link HTTPMethod}
* @return Observable from object
* @param data the object that should be send
*/
public update(url: string, obj: object, method?: HTTPMethod): Observable<object> {
url = this.formatForSlash(url);
if (method === null || method === HTTPMethod.PATCH) {
return this.http.patch<object>(url, obj).pipe(
tap(
response => {
console.log('Update object. Response :\n ', response);
},
error => console.log('Error:\n ', error)
)
);
} else if (method === HTTPMethod.PUT) {
return this.http.put<object>(url, obj).pipe(
tap(
response => {
console.log('Update object. Response :\n ', response);
},
error => console.error('Error :\n', error)
)
);
}
public async patch<T>(url: string, data: any): Promise<T> {
return await this.send<T>(url, HTTPMethod.PATCH, data);
}
/**
* Deletes the given object on the server
*
* @param url the url that should be called to delete the object
* @return Observable of object
* Exectures a put on a url with a certain object
* @param url the url that should be called
* @param data: The data to send
*/
public delete(url: string): Observable<object> {
url = this.formatForSlash(url);
return this.http.delete<object>(url).pipe(
tap(
response => {
// TODO: Message, Notify, Etc
console.log('Delete object. Response:\n', response);
},
error => console.error('Error: \n', error)
)
);
public async put<T>(url: string, data: any): Promise<T> {
return await this.send<T>(url, HTTPMethod.PUT, data);
}
/**
* Makes a delete request.
* @param url the url that should be called
* @param data An optional data to send in the requestbody.
*/
public async delete<T>(url: string, data?: any): Promise<T> {
return await this.send<T>(url, HTTPMethod.DELETE, data);
}
}

View File

@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { LoginDataService } from '../../../core/services/login-data.service';
import { environment } from 'environments/environment';
import { HttpClient } from '@angular/common/http';
import { HttpService } from '../../../core/services/http.service';
/**
* Characterize a plugin. This data is retrieved from the server
@ -83,7 +83,7 @@ export class LegalNoticeContentComponent implements OnInit {
public constructor(
private loginDataService: LoginDataService,
private translate: TranslateService,
private http: HttpClient
private http: HttpService
) {}
/**
@ -97,10 +97,13 @@ export class LegalNoticeContentComponent implements OnInit {
});
// Query the version info.
this.http
.get<VersionResponse>(environment.urlPrefix + '/core/version/', {})
.subscribe((info: VersionResponse) => {
this.http.get<VersionResponse>(environment.urlPrefix + '/core/version/', {}).then(
info => {
this.versionInfo = info;
});
},
() => {
// TODO: error handling if the version info could not be loaded
}
);
}
}

View File

@ -1,5 +1,4 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { BaseRepository } from '../../base/base-repository';
import { DataStoreService } from '../../../core/services/data-store.service';
@ -7,6 +6,7 @@ import { Item } from '../../../shared/models/agenda/item';
import { ViewItem } from '../models/view-item';
import { AgendaBaseModel } from '../../../shared/models/base/agenda-base-model';
import { BaseModel } from '../../../shared/models/base/base-model';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Repository service for users
@ -49,7 +49,7 @@ export class AgendaRepositoryService extends BaseRepository<ViewItem, Item> {
*
* TODO: used over not-yet-existing detail view
*/
public update(item: Partial<Item>, viewUser: ViewItem): Observable<Item> {
public async update(item: Partial<Item>, viewUser: ViewItem): Promise<void> {
return null;
}
@ -58,7 +58,7 @@ export class AgendaRepositoryService extends BaseRepository<ViewItem, Item> {
*
* TODO: used over not-yet-existing detail view
*/
public delete(item: ViewItem): Observable<Item> {
public async delete(item: ViewItem): Promise<void> {
return null;
}
@ -67,7 +67,7 @@ export class AgendaRepositoryService extends BaseRepository<ViewItem, Item> {
*
* TODO: used over not-yet-existing detail view
*/
public create(item: Item): Observable<Item> {
public async create(item: Item): Promise<Identifiable> {
return null;
}

View File

@ -4,9 +4,9 @@ import { Assignment } from '../../../shared/models/assignments/assignment';
import { User } from '../../../shared/models/users/user';
import { Tag } from '../../../shared/models/core/tag';
import { Item } from '../../../shared/models/agenda/item';
import { Observable } from 'rxjs';
import { BaseRepository } from '../../base/base-repository';
import { DataStoreService } from '../../../core/services/data-store.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Repository Service for Assignments.
@ -25,15 +25,15 @@ export class AssignmentRepositoryService extends BaseRepository<ViewAssignment,
super(DS, Assignment, [User, Item, Tag]);
}
public update(assignment: Partial<Assignment>, viewAssignment: ViewAssignment): Observable<Assignment> {
public async update(assignment: Partial<Assignment>, viewAssignment: ViewAssignment): Promise<void> {
return null;
}
public delete(viewAssignment: ViewAssignment): Observable<Assignment> {
public async delete(viewAssignment: ViewAssignment): Promise<void> {
return null;
}
public create(assignment: Assignment): Observable<Assignment> {
public async create(assignment: Assignment): Promise<Identifiable> {
return null;
}

View File

@ -4,6 +4,7 @@ import { BaseViewModel } from './base-view-model';
import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model';
import { CollectionStringModelMapperService } from '../../core/services/collectionStringModelMapper.service';
import { DataStoreService } from '../../core/services/data-store.service';
import { Identifiable } from '../../shared/models/base/identifiable';
export abstract class BaseRepository<V extends BaseViewModel, M extends BaseModel> extends OpenSlidesComponent {
/**
@ -78,14 +79,14 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
* @param update the update that should be created
* @param viewModel the view model that the update is based on
*/
public abstract update(update: Partial<M>, viewModel: V): Observable<M>;
public abstract async update(update: Partial<M>, viewModel: V): Promise<void>;
/**
* Deletes a given Model
* @param update the update that should be created
* @param viewModel the view model that the update is based on
*/
public abstract delete(viewModel: V): Observable<M>;
public abstract async delete(viewModel: V): Promise<void>;
/**
* Creates a new model
@ -93,7 +94,7 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
* @param viewModel the view model that the update is based on
* TODO: remove the viewModel
*/
public abstract create(update: M): Observable<M>;
public abstract async create(update: M): Promise<Identifiable>;
/**
* Creates a view model out of a base model.

View File

@ -5,7 +5,6 @@ import { ViewConfig } from '../../models/view-config';
import { BaseComponent } from '../../../../base.component';
import { FormGroup, FormBuilder } from '@angular/forms';
import { ConfigRepositoryService } from '../../services/config-repository.service';
import { tap } from 'rxjs/operators';
import { ParentErrorStateMatcher } from '../../../../shared/parent-error-state-matcher';
/**
@ -117,26 +116,19 @@ export class ConfigFieldComponent extends BaseComponent implements OnInit {
/**
* Updates the this config field.
*/
private update(value: any): void {
private async update(value: any): Promise<void> {
// TODO: Fix the Datetimepicker parser and formatter.
if (this.configItem.inputType === 'datetimepicker') {
value = Date.parse(value);
}
this.debounceTimeout = null;
this.repo
.update({ value: value }, this.configItem)
.pipe(
tap(
response => {
try {
await this.repo.update({ value: value }, this.configItem);
this.error = null;
this.showSuccessIcon();
},
error => {
this.setError(error.error.detail);
} catch (e) {
this.setError(e.error.detail);
}
)
)
.subscribe();
}
/**

View File

@ -6,7 +6,8 @@ import { Config } from '../../../shared/models/core/config';
import { Observable, BehaviorSubject } from 'rxjs';
import { DataStoreService } from '../../../core/services/data-store.service';
import { ConstantsService } from '../../../core/services/constants.service';
import { HttpClient } from '@angular/common/http';
import { HttpService } from '../../../core/services/http.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Holds a single config item.
@ -85,7 +86,7 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config>
/**
* Constructor for ConfigRepositoryService. Requests the constants from the server and creates the config group structure.
*/
public constructor(DS: DataStoreService, private constantsService: ConstantsService, private http: HttpClient) {
public constructor(DS: DataStoreService, private constantsService: ConstantsService, private http: HttpService) {
super(DS, Config);
this.constantsService.get('OpenSlidesConfigVariables').subscribe(constant => {
@ -180,12 +181,12 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config>
/**
* Saves a config value.
*/
public update(config: Partial<Config>, viewConfig: ViewConfig): Observable<Config> {
public async update(config: Partial<Config>, viewConfig: ViewConfig): Promise<void> {
const updatedConfig = new Config();
updatedConfig.patchValues(viewConfig.config);
updatedConfig.patchValues(config);
// TODO: Use datasendService, if it can switch correctly between put, post and patch
return this.http.put<Config>(
await this.http.put(
'rest/' + updatedConfig.collectionString + '/' + updatedConfig.key + '/',
updatedConfig
);
@ -197,7 +198,7 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config>
*
* Function exists solely to correctly implement {@link BaseRepository}
*/
public delete(config: ViewConfig): Observable<Config> {
public async delete(config: ViewConfig): Promise<void> {
throw new Error('Config variables cannot be deleted');
}
@ -207,7 +208,7 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config>
*
* Function exists solely to correctly implement {@link BaseRepository}
*/
public create(config: Config): Observable<Config> {
public async create(config: Config): Promise<Identifiable> {
throw new Error('Config variables cannot be created');
}

View File

@ -7,11 +7,12 @@ import { OperatorService } from 'app/core/services/operator.service';
import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { HttpErrorResponse, HttpClient } from '@angular/common/http';
import { HttpErrorResponse } from '@angular/common/http';
import { environment } from 'environments/environment';
import { OpenSlidesService } from '../../../../core/services/openslides.service';
import { LoginDataService } from '../../../../core/services/login-data.service';
import { ParentErrorStateMatcher } from '../../../../shared/parent-error-state-matcher';
import { HttpService } from '../../../../core/services/http.service';
/**
* Login mask component.
@ -72,7 +73,7 @@ export class LoginMaskComponent extends BaseComponent implements OnInit, OnDestr
private operator: OperatorService,
private router: Router,
private formBuilder: FormBuilder,
private http: HttpClient,
private http: HttpService,
private matSnackBar: MatSnackBar,
private OpenSlides: OpenSlidesService,
private loginDataService: LoginDataService
@ -89,7 +90,8 @@ export class LoginMaskComponent extends BaseComponent implements OnInit, OnDestr
*/
public ngOnInit(): void {
// Get the login data. Save information to the login data service
this.http.get<any>(environment.urlPrefix + '/users/login/', {}).subscribe(response => {
this.http.get<any>(environment.urlPrefix + '/users/login/').then(
response => {
if (response.info_text) {
this.installationNotice = this.matSnackBar.open(response.info_text, this.translate.instant('OK'), {
duration: 5000
@ -97,7 +99,11 @@ export class LoginMaskComponent extends BaseComponent implements OnInit, OnDestr
}
this.loginDataService.setPrivacyPolicy(response.privacy_policy);
this.loginDataService.setLegalNotice(response.legal_notice);
});
},
() => {
// TODO: Error handling
}
);
}
public ngOnDestroy(): void {

View File

@ -4,8 +4,8 @@ import { BaseRepository } from '../../base/base-repository';
import { ViewMediafile } from '../models/view-mediafile';
import { Mediafile } from '../../../shared/models/mediafiles/mediafile';
import { User } from '../../../shared/models/users/user';
import { Observable } from 'rxjs';
import { DataStoreService } from '../../../core/services/data-store.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Repository for files
@ -27,7 +27,7 @@ export class MediafileRepositoryService extends BaseRepository<ViewMediafile, Me
*
* TODO: used over not-yet-existing detail view
*/
public update(file: Partial<Mediafile>, viewFile: ViewMediafile): Observable<Mediafile> {
public async update(file: Partial<Mediafile>, viewFile: ViewMediafile): Promise<void> {
return null;
}
@ -36,7 +36,7 @@ export class MediafileRepositoryService extends BaseRepository<ViewMediafile, Me
*
* TODO: used over not-yet-existing detail view
*/
public delete(file: ViewMediafile): Observable<Mediafile> {
public async delete(file: ViewMediafile): Promise<void> {
return null;
}
@ -45,7 +45,7 @@ export class MediafileRepositoryService extends BaseRepository<ViewMediafile, Me
*
* TODO: used over not-yet-existing detail view
*/
public create(file: Mediafile): Observable<Mediafile> {
public async create(file: Mediafile): Promise<Identifiable> {
return null;
}

View File

@ -10,8 +10,6 @@ import { ViewCategory } from '../../models/view-category';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Motion } from '../../../../shared/models/motions/motion';
import { SortingListComponent } from '../../../../shared/components/sorting-list/sorting-list.component';
import { MotionRepositoryService } from '../../services/motion-repository.service';
import { ViewMotion } from '../../models/view-motion';
import { PromptService } from 'app/core/services/prompt.service';
/**
@ -66,7 +64,6 @@ export class CategoryListComponent extends BaseComponent implements OnInit {
protected translate: TranslateService,
private repo: CategoryRepositoryService,
private formBuilder: FormBuilder,
private motionRepo: MotionRepositoryService,
private promptService: PromptService
) {
super(titleService, translate);
@ -122,12 +119,11 @@ export class CategoryListComponent extends BaseComponent implements OnInit {
/**
* Creates a new category. Executed after hitting save.
*/
public onCreateButton(): void {
public async onCreateButton(): Promise<void> {
if (this.createForm.valid) {
this.categoryToCreate.patchValues(this.createForm.value as Category);
this.repo.create(this.categoryToCreate).subscribe(resp => {
await this.repo.create(this.categoryToCreate)
this.categoryToCreate = null;
});
}
}
@ -147,18 +143,17 @@ export class CategoryListComponent extends BaseComponent implements OnInit {
/**
* Saves the categories
*/
public onSaveButton(viewCategory: ViewCategory): void {
public async onSaveButton(viewCategory: ViewCategory): Promise<void> {
if (this.updateForm.valid) {
this.repo.update(this.updateForm.value as Partial<Category>, viewCategory).subscribe(resp => {
await this.repo.update(this.updateForm.value as Partial<Category>, viewCategory);
this.onCancelButton();
this.sortDataSource();
});
}
// get the sorted motions
if (this.sortSelector) {
const manuallySortedMotions = this.sortSelector.array as Motion[];
this.repo.updateCategoryNumbering(viewCategory.category, manuallySortedMotions).subscribe();
await this.repo.updateCategoryNumbering(viewCategory.category, manuallySortedMotions);
}
}
@ -180,18 +175,11 @@ export class CategoryListComponent extends BaseComponent implements OnInit {
/**
* is executed, when the delete button is pressed
*/
public async onDeleteButton(viewCategory: ViewCategory): Promise<any> {
public async onDeleteButton(viewCategory: ViewCategory): Promise<void> {
const content = this.translate.instant('Delete') + ` ${viewCategory.name}?`;
if (await this.promptService.open('Are you sure?', content)) {
const motList = this.motionsInCategory(viewCategory.category);
motList.forEach(motion => {
motion.category_id = null;
this.motionRepo.update(motion, new ViewMotion(motion));
});
this.repo.delete(viewCategory).subscribe(resp => {
await this.repo.delete(viewCategory);
this.onCancelButton();
});
}
}

View File

@ -109,7 +109,7 @@ export class MotionChangeRecommendationComponent {
});
}
public saveChangeRecommendation(): void {
public async saveChangeRecommendation(): Promise<void> {
this.changeReco.updateChangeReco(
this.contentForm.controls.diffType.value,
this.contentForm.controls.text.value,
@ -117,21 +117,13 @@ export class MotionChangeRecommendationComponent {
);
if (this.newReco) {
this.repo.createByViewModel(this.changeReco).subscribe(response => {
if (response.id) {
this.dialogRef.close(response);
} else {
await this.repo.createByViewModel(this.changeReco);
this.dialogRef.close();
// @TODO Show an error message
}
});
} else {
this.repo.update(this.changeReco.changeRecommendation, this.changeReco).subscribe(response => {
if (response.id) {
this.dialogRef.close(response);
} else {
await this.repo.update(this.changeReco.changeRecommendation, this.changeReco);
this.dialogRef.close();
// @TODO Show an error message
}
});
}
}
}

View File

@ -111,12 +111,11 @@ export class MotionCommentSectionListComponent extends BaseComponent implements
}
}
public create(): void {
public async create(): Promise<void> {
if (this.createForm.valid) {
this.commentSectionToCreate.patchValues(this.createForm.value as MotionCommentSection);
this.repo.create(this.commentSectionToCreate).subscribe(resp => {
await this.repo.create(this.commentSectionToCreate);
this.commentSectionToCreate = null;
});
}
}
@ -137,23 +136,21 @@ export class MotionCommentSectionListComponent extends BaseComponent implements
/**
* Saves the categories
*/
public onSaveButton(viewSection: ViewMotionCommentSection): void {
public async onSaveButton(viewSection: ViewMotionCommentSection): Promise<void> {
if (this.updateForm.valid) {
this.repo.update(this.updateForm.value as Partial<MotionCommentSection>, viewSection).subscribe(resp => {
await this.repo.update(this.updateForm.value as Partial<MotionCommentSection>, viewSection);
this.openId = this.editId = null;
});
}
}
/**
* is executed, when the delete button is pressed
*/
public async onDeleteButton(viewSection: ViewMotionCommentSection): Promise<any> {
public async onDeleteButton(viewSection: ViewMotionCommentSection): Promise<void> {
const content = this.translate.instant('Delete') + ` ${viewSection.name}?`;
if (await this.promptService.open('Are you sure?', content)) {
this.repo.delete(viewSection).subscribe(resp => {
await this.repo.delete(viewSection);
this.openId = this.editId = null;
});
}
}

View File

@ -170,12 +170,12 @@ export class MotionDetailDiffComponent implements AfterViewInit {
* @param {ViewChangeReco} change
* @param {string} value
*/
public setAcceptanceValue(change: ViewChangeReco, value: string): void {
public async setAcceptanceValue(change: ViewChangeReco, value: string): Promise<void> {
if (value === 'accepted') {
this.recoRepo.setAccepted(change).subscribe(); // Subscribe to trigger HTTP request
await this.recoRepo.setAccepted(change);
}
if (value === 'rejected') {
this.recoRepo.setRejected(change).subscribe(); // Subscribe to trigger HTTP request
await this.recoRepo.setRejected(change);
}
}
@ -185,8 +185,8 @@ export class MotionDetailDiffComponent implements AfterViewInit {
* @param {ViewChangeReco} change
* @param {boolean} internal
*/
public setInternal(change: ViewChangeReco, internal: boolean): void {
this.recoRepo.setInternal(change, internal).subscribe(); // Subscribe to trigger HTTP request
public async setInternal(change: ViewChangeReco, internal: boolean): Promise<void> {
await this.recoRepo.setInternal(change, internal);
}
/**
@ -196,10 +196,10 @@ export class MotionDetailDiffComponent implements AfterViewInit {
* @param {ViewChangeReco} reco
* @param {MouseEvent} $event
*/
public deleteChangeRecommendation(reco: ViewChangeReco, $event: MouseEvent): void {
this.recoRepo.delete(reco).subscribe(); // Subscribe to trigger HTTP request
public async deleteChangeRecommendation(reco: ViewChangeReco, $event: MouseEvent): Promise<void> {
$event.stopPropagation();
$event.preventDefault();
await this.recoRepo.delete(reco);
}
/**

View File

@ -264,40 +264,20 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
*
* TODO: state is not yet saved. Need a special "put" command. Repo should handle this.
*/
public saveMotion(): void {
public async saveMotion(): Promise<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 => {
if (response.id) {
const response = await this.repo.create(fromForm);
this.router.navigate(['./motions/' + response.id]);
}
});
} else {
this.repo.update(fromForm, this.motionCopy).subscribe(response => {
await this.repo.update(fromForm, this.motionCopy);
// if the motion was successfully updated, change the edit mode.
// TODO: Show errors if there appear here
if (response.id) {
this.editMotion = false;
}
});
// TODO: Document and evaluate if this actually does what it is supposed to do
if (fromForm.category_id) {
const catOfFormMotion = this.categoryRepo.getCategoryByID(fromForm.category_id);
const motionsWithSameCat = this.categoryRepo.getMotionsOfCategory(catOfFormMotion);
if (!motionsWithSameCat.includes(fromForm)) {
motionsWithSameCat.push(fromForm);
this.categoryRepo.updateCategoryNumbering(
this.categoryRepo.getCategoryByID(fromForm.category_id),
motionsWithSameCat
);
}
}
// TODO: Show errors if there appear here
}
}
@ -329,7 +309,7 @@ export class MotionDetailComponent extends BaseComponent implements OnInit {
* TODO: Repo should handle
*/
public deleteMotionButton(): void {
this.repo.delete(this.motion).subscribe(answer => {
this.repo.delete(this.motion).then(() => {
this.router.navigate(['./motions/']);
});
const motList = this.categoryRepo.getMotionsOfCategory(this.motion.category);

View File

@ -85,12 +85,11 @@ export class StatuteParagraphListComponent extends BaseComponent implements OnIn
}
}
public create(): void {
public async create(): Promise<void> {
if (this.createForm.valid) {
this.statuteParagraphToCreate.patchValues(this.createForm.value as StatuteParagraph);
this.repo.create(this.statuteParagraphToCreate).subscribe(resp => {
await this.repo.create(this.statuteParagraphToCreate);
this.statuteParagraphToCreate = null;
});
}
}
@ -110,25 +109,21 @@ export class StatuteParagraphListComponent extends BaseComponent implements OnIn
/**
* Saves the statute paragrpah
*/
public onSaveButton(viewStatuteParagraph: ViewStatuteParagraph): void {
public async onSaveButton(viewStatuteParagraph: ViewStatuteParagraph): Promise<void> {
if (this.updateForm.valid) {
this.repo
.update(this.updateForm.value as Partial<StatuteParagraph>, viewStatuteParagraph)
.subscribe(resp => {
await this.repo.update(this.updateForm.value as Partial<StatuteParagraph>, viewStatuteParagraph);
this.openId = this.editId = null;
});
}
}
/**
* is executed, when the delete button is pressed
*/
public async onDeleteButton(viewStatuteParagraph: ViewStatuteParagraph): Promise<any> {
public async onDeleteButton(viewStatuteParagraph: ViewStatuteParagraph): Promise<void> {
const content = this.translate.instant('Delete') + ` ${viewStatuteParagraph.title}?`;
if (await this.promptService.open('Are you sure?', content)) {
this.repo.delete(viewStatuteParagraph).subscribe(resp => {
await this.repo.delete(viewStatuteParagraph);
this.openId = this.editId = null;
});
}
}

View File

@ -2,12 +2,12 @@ import { Injectable } from '@angular/core';
import { Category } from '../../../shared/models/motions/category';
import { ViewCategory } from '../models/view-category';
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 { Motion } from '../../../shared/models/motions/motion';
import { CategoryNumbering } from '../models/category-numbering';
import { HttpService, HTTPMethod } from '../../../core/services/http.service';
import { HttpService } from '../../../core/services/http.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Repository Services for Categories
@ -41,11 +41,11 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
return new ViewCategory(category);
}
public create(newCategory: Category): Observable<any> {
return this.dataSend.createModel(newCategory);
public async create(newCategory: Category): Promise<Identifiable> {
return await this.dataSend.createModel(newCategory);
}
public update(category: Partial<Category>, viewCategory?: ViewCategory): Observable<any> {
public async update(category: Partial<Category>, viewCategory: ViewCategory): Promise<void> {
let updateCategory: Category;
if (viewCategory) {
updateCategory = viewCategory.category;
@ -53,12 +53,12 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
updateCategory = new Category();
}
updateCategory.patchValues(category);
return this.dataSend.updateModel(updateCategory, HTTPMethod.PUT);
await this.dataSend.updateModel(updateCategory);
}
public delete(viewCategory: ViewCategory): Observable<any> {
public async delete(viewCategory: ViewCategory): Promise<void> {
const category = viewCategory.category;
return this.dataSend.deleteModel(category);
await this.dataSend.deleteModel(category);
}
/**
@ -91,10 +91,10 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
* @param category the category it should be updated in
* @param motionList the list of motions on this category
*/
public updateCategoryNumbering(category: Category, motionList: Motion[]): Observable<object> {
public async updateCategoryNumbering(category: Category, motionList: Motion[]): Promise<void> {
const categoryNumbering = new CategoryNumbering();
categoryNumbering.setMotions(motionList);
return this.sentCategoryNumbering(category, categoryNumbering);
await this.sentCategoryNumbering(category, categoryNumbering);
}
/**
@ -102,8 +102,8 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
*
* @return Observable from
*/
protected sentCategoryNumbering(category: Category, categoryNumbering: CategoryNumbering): Observable<object> {
protected async sentCategoryNumbering(category: Category, categoryNumbering: CategoryNumbering): Promise<void> {
const collectionString = 'rest/motions/category/' + category.id + '/numbering/';
return this.httpService.create(collectionString, categoryNumbering);
await this.httpService.post(collectionString, categoryNumbering);
}
}

View File

@ -10,7 +10,7 @@ import { BaseRepository } from '../../base/base-repository';
import { DataStoreService } from '../../../core/services/data-store.service';
import { MotionChangeReco } from '../../../shared/models/motions/motion-change-reco';
import { ViewChangeReco } from '../models/view-change-reco';
import { HTTPMethod } from 'app/core/services/http.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Repository Services for change recommendations
@ -44,8 +44,8 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<ViewCh
*
* @param {MotionChangeReco} changeReco
*/
public create(changeReco: MotionChangeReco): Observable<MotionChangeReco> {
return this.dataSend.createModel(changeReco) as Observable<MotionChangeReco>;
public async create(changeReco: MotionChangeReco): Promise<Identifiable> {
return await this.dataSend.createModel(changeReco);
}
/**
@ -53,13 +53,13 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<ViewCh
* change recommendation view object is returned (as an observable).
*
* @param {ViewChangeReco} view
* @deprecated Will not work with PR #3928. There will just be the id as response to create requests.
* Two possibilities: Make a server change to still retrieve the created object or you have to wait for the
* correct autoupdate.
*/
public createByViewModel(view: ViewChangeReco): Observable<ViewChangeReco> {
return this.create(view.changeRecommendation).pipe(
map((changeReco: MotionChangeReco) => {
return new ViewChangeReco(changeReco);
})
);
public async createByViewModel(view: ViewChangeReco): Promise<Identifiable> {
return await this.dataSend.createModel(view.changeRecommendation);
// return new ViewChangeReco(cr);
}
/**
@ -78,8 +78,8 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<ViewCh
* to {@link DataSendService}
* @param {ViewChangeReco} viewModel
*/
public delete(viewModel: ViewChangeReco): Observable<MotionChangeReco> {
return this.dataSend.deleteModel(viewModel.changeRecommendation) as Observable<MotionChangeReco>;
public async delete(viewModel: ViewChangeReco): Promise<void> {
await this.dataSend.deleteModel(viewModel.changeRecommendation);
}
/**
@ -91,10 +91,10 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<ViewCh
* @param {Partial<MotionChangeReco>} update the form data containing the update values
* @param {ViewChangeReco} viewModel The View Change Recommendation. If not present, a new motion will be created
*/
public update(update: Partial<MotionChangeReco>, viewModel: ViewChangeReco): Observable<MotionChangeReco> {
public async update(update: Partial<MotionChangeReco>, viewModel: ViewChangeReco): Promise<void> {
const changeReco = viewModel.changeRecommendation;
changeReco.patchValues(update);
return this.dataSend.updateModel(changeReco, HTTPMethod.PATCH) as Observable<MotionChangeReco>;
await this.dataSend.partialUpdateModel(changeReco);
}
/**
@ -113,12 +113,12 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<ViewCh
*
* @param {ViewChangeReco} change
*/
public setAccepted(change: ViewChangeReco): Observable<MotionChangeReco> {
public async setAccepted(change: ViewChangeReco): Promise<void> {
const changeReco = change.changeRecommendation;
changeReco.patchValues({
rejected: false
});
return this.dataSend.updateModel(changeReco, HTTPMethod.PATCH) as Observable<MotionChangeReco>;
await this.dataSend.partialUpdateModel(changeReco);
}
/**
@ -126,12 +126,12 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<ViewCh
*
* @param {ViewChangeReco} change
*/
public setRejected(change: ViewChangeReco): Observable<MotionChangeReco> {
public async setRejected(change: ViewChangeReco): Promise<void> {
const changeReco = change.changeRecommendation;
changeReco.patchValues({
rejected: true
});
return this.dataSend.updateModel(changeReco, HTTPMethod.PATCH) as Observable<MotionChangeReco>;
await this.dataSend.partialUpdateModel(changeReco);
}
/**
@ -140,11 +140,11 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<ViewCh
* @param {ViewChangeReco} change
* @param {boolean} internal
*/
public setInternal(change: ViewChangeReco, internal: boolean): Observable<MotionChangeReco> {
public async setInternal(change: ViewChangeReco, internal: boolean): Promise<void> {
const changeReco = change.changeRecommendation;
changeReco.patchValues({
internal: internal
});
return this.dataSend.updateModel(changeReco, HTTPMethod.PATCH) as Observable<MotionChangeReco>;
await this.dataSend.partialUpdateModel(changeReco);
}
}

View File

@ -1,12 +1,11 @@
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 { ViewMotionCommentSection } from '../models/view-motion-comment-section';
import { MotionCommentSection } from '../../../shared/models/motions/motion-comment-section';
import { Group } from '../../../shared/models/users/group';
import { HTTPMethod } from 'app/core/services/http.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Repository Services for Categories
@ -41,11 +40,11 @@ export class MotionCommentSectionRepositoryService extends BaseRepository<
return new ViewMotionCommentSection(section, read_groups, write_groups);
}
public create(section: MotionCommentSection): Observable<any> {
return this.dataSend.createModel(section);
public async create(section: MotionCommentSection): Promise<Identifiable> {
return await this.dataSend.createModel(section);
}
public update(section: Partial<MotionCommentSection>, viewSection?: ViewMotionCommentSection): Observable<any> {
public async update(section: Partial<MotionCommentSection>, viewSection?: ViewMotionCommentSection): Promise<void> {
let updateSection: MotionCommentSection;
if (viewSection) {
updateSection = viewSection.section;
@ -53,10 +52,10 @@ export class MotionCommentSectionRepositoryService extends BaseRepository<
updateSection = new MotionCommentSection();
}
updateSection.patchValues(section);
return this.dataSend.updateModel(updateSection, HTTPMethod.PUT);
await this.dataSend.updateModel(updateSection);
}
public delete(viewSection: ViewMotionCommentSection): Observable<any> {
return this.dataSend.deleteModel(viewSection.section);
public async delete(viewSection: ViewMotionCommentSection): Promise<void> {
await this.dataSend.deleteModel(viewSection.section);
}
}

View File

@ -7,7 +7,6 @@ import { Category } from '../../../shared/models/motions/category';
import { Workflow } from '../../../shared/models/motions/workflow';
import { WorkflowState } from '../../../shared/models/motions/workflow-state';
import { ChangeRecoMode, ViewMotion } from '../models/view-motion';
import { Observable } from 'rxjs';
import { BaseRepository } from '../../base/base-repository';
import { DataStoreService } from '../../../core/services/data-store.service';
import { LinenumberingService } from './linenumbering.service';
@ -15,7 +14,7 @@ import { DiffService, LineRange, ModificationType } from './diff.service';
import { ViewChangeReco } from '../models/view-change-reco';
import { MotionChangeReco } from '../../../shared/models/motions/motion-change-reco';
import { ViewUnifiedChange } from '../models/view-unified-change';
import { HTTPMethod } from '../../../core/services/http.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Repository Services for motions (and potentially categories)
@ -79,11 +78,11 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
* @param viewMotion The View Motion. If not present, a new motion will be created
* TODO: Remove the viewMotion and make it actually distignuishable from save()
*/
public create(motion: Motion): Observable<any> {
public async create(motion: Motion): Promise<Identifiable> {
if (!motion.supporters_id) {
delete motion.supporters_id;
}
return this.dataSend.createModel(motion);
return await this.dataSend.createModel(motion);
}
/**
@ -95,10 +94,10 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
* @param update the form data containing the update values
* @param viewMotion The View Motion. If not present, a new motion will be created
*/
public update(update: Partial<Motion>, viewMotion: ViewMotion): Observable<any> {
public async update(update: Partial<Motion>, viewMotion: ViewMotion): Promise<void> {
const motion = viewMotion.motion;
motion.patchValues(update);
return this.dataSend.updateModel(motion, HTTPMethod.PATCH);
await this.dataSend.partialUpdateModel(motion);
}
/**
@ -108,8 +107,8 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
* to {@link DataSendService}
* @param viewMotion
*/
public delete(viewMotion: ViewMotion): Observable<any> {
return this.dataSend.deleteModel(viewMotion.motion);
public async delete(viewMotion: ViewMotion): Promise<void> {
await this.dataSend.deleteModel(viewMotion.motion);
}
/**

View File

@ -1,11 +1,10 @@
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';
import { HTTPMethod } from 'app/core/services/http.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Repository Services for statute paragraphs
@ -32,20 +31,20 @@ export class StatuteParagraphRepositoryService extends BaseRepository<ViewStatut
return new ViewStatuteParagraph(statuteParagraph);
}
public create(statuteParagraph: StatuteParagraph): Observable<any> {
return this.dataSend.createModel(statuteParagraph);
public async create(statuteParagraph: StatuteParagraph): Promise<Identifiable> {
return await this.dataSend.createModel(statuteParagraph);
}
public update(
public async update(
statuteParagraph: Partial<StatuteParagraph>,
viewStatuteParagraph: ViewStatuteParagraph
): Observable<any> {
): Promise<void> {
const updateParagraph = viewStatuteParagraph.statuteParagraph;
updateParagraph.patchValues(statuteParagraph);
return this.dataSend.updateModel(updateParagraph, HTTPMethod.PUT);
await this.dataSend.updateModel(updateParagraph);
}
public delete(viewStatuteParagraph: ViewStatuteParagraph): Observable<any> {
return this.dataSend.deleteModel(viewStatuteParagraph.statuteParagraph);
public async delete(viewStatuteParagraph: ViewStatuteParagraph): Promise<void> {
await this.dataSend.deleteModel(viewStatuteParagraph.statuteParagraph);
}
}

View File

@ -1,7 +1,7 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { TagListComponent } from './tag-list.component';
import { E2EImportsModule } from '../../../../e2e-imports.module';
import { E2EImportsModule } from 'e2e-imports.module';
describe('TagListComponent', () => {
let component: TagListComponent;

View File

@ -1,12 +1,12 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Title } from '@angular/platform-browser';
import { Tag } from '../../../shared/models/core/tag';
import { ListViewBaseComponent } from '../../base/list-view-base';
import { TagRepositoryService } from '../services/tag-repository.service';
import { ViewTag } from '../models/view-tag';
import { Tag } from '../../../../shared/models/core/tag';
import { ListViewBaseComponent } from '../../../base/list-view-base';
import { TagRepositoryService } from '../../services/tag-repository.service';
import { ViewTag } from '../../models/view-tag';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { PromptService } from '../../../core/services/prompt.service';
import { PromptService } from '../../../../core/services/prompt.service';
/**
* Listview for the complete lsit of available Tags
@ -70,42 +70,36 @@ export class TagListComponent extends ListViewBaseComponent<ViewTag> implements
/**
* Saves a newly created tag.
*/
public submitNewTag(): void {
if (this.tagForm.value && this.tagForm.valid) {
this.repo.create(this.tagForm.value).subscribe(response => {
if (response) {
public async submitNewTag(): Promise<void> {
if (!this.tagForm.value || !this.tagForm.valid) {
return;
}
await this.repo.create(this.tagForm.value);
this.tagForm.reset();
this.cancelEditing();
}
});
}
}
/**
* Saves an edited tag.
*/
public submitEditedTag(): void {
if (this.tagForm.value && this.tagForm.valid) {
public async submitEditedTag(): Promise<void> {
if (!this.tagForm.value || !this.tagForm.valid) {
return;
}
const updateData = new Tag({ name: this.tagForm.value.name });
this.repo.update(updateData, this.selectedTag).subscribe(response => {
if (response) {
await this.repo.update(updateData, this.selectedTag);
this.cancelEditing();
}
});
}
}
/**
* Deletes the selected Tag after a successful confirmation.
* @async
*/
public async deleteSelectedTag(): Promise<any> {
public async deleteSelectedTag(): Promise<void> {
const content = this.translate.instant('Delete') + ` ${this.selectedTag.name}?`;
if (await this.promptService.open(this.translate.instant('Are you sure?'), content)) {
this.repo.delete(this.selectedTag).subscribe(response => {
await this.repo.delete(this.selectedTag);
this.cancelEditing();
});
}
}

View File

@ -2,10 +2,9 @@ import { Injectable } from '@angular/core';
import { Tag } from '../../../shared/models/core/tag';
import { ViewTag } from '../models/view-tag';
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 { HTTPMethod } from 'app/core/services/http.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Repository Services for Tags
@ -35,20 +34,20 @@ export class TagRepositoryService extends BaseRepository<ViewTag, Tag> {
return new ViewTag(tag);
}
public create(update: Tag): Observable<any> {
public async create(update: Tag): Promise<Identifiable> {
const newTag = new Tag();
newTag.patchValues(update);
return this.dataSend.createModel(newTag);
return await this.dataSend.createModel(newTag);
}
public update(update: Partial<Tag>, viewTag: ViewTag): Observable<any> {
public async update(update: Partial<Tag>, viewTag: ViewTag): Promise<void> {
const updateTag = new Tag();
updateTag.patchValues(viewTag.tag);
updateTag.patchValues(update);
return this.dataSend.updateModel(updateTag, HTTPMethod.PUT);
await this.dataSend.updateModel(updateTag);
}
public delete(viewTag: ViewTag): Observable<any> {
return this.dataSend.deleteModel(viewTag.tag);
public async delete(viewTag: ViewTag): Promise<void> {
await this.dataSend.deleteModel(viewTag.tag);
}
}

View File

@ -1,6 +1,6 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { TagListComponent } from './components/tag-list.component';
import { TagListComponent } from './components/tag-list/tag-list.component';
const routes: Routes = [{ path: '', component: TagListComponent }];

View File

@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
import { TagRoutingModule } from './tag-routing.module';
import { SharedModule } from '../../shared/shared.module';
import { TagListComponent } from './components/tag-list.component';
import { TagListComponent } from './components/tag-list/tag-list.component';
@NgModule({
imports: [CommonModule, TagRoutingModule, SharedModule],

View File

@ -88,38 +88,35 @@ export class GroupListComponent extends BaseComponent implements OnInit {
* Saves a newly created group.
* @param form form data given by the group
*/
public submitNewGroup(): void {
if (this.groupForm.value && this.groupForm.valid) {
this.repo.create(this.groupForm.value).subscribe(response => {
if (response) {
public async submitNewGroup(): Promise<void> {
if (!this.groupForm.value || !this.groupForm.valid) {
return;
}
await this.repo.create(this.groupForm.value);
this.groupForm.reset();
this.cancelEditing();
}
});
}
}
/**
* Saves an edited group.
* @param form form data given by the group
*/
public submitEditedGroup(): void {
if (this.groupForm.value && this.groupForm.valid) {
public async submitEditedGroup(): Promise<void> {
if (!this.groupForm.value || !this.groupForm.valid) {
return;
}
const updateData = new Group({ name: this.groupForm.value.name });
this.repo.update(updateData, this.selectedGroup).subscribe(response => {
if (response) {
await this.repo.update(updateData, this.selectedGroup);
this.cancelEditing();
}
});
}
}
/**
* Deletes the selected Group
*/
public deleteSelectedGroup(): void {
this.repo.delete(this.selectedGroup).subscribe(response => this.cancelEditing());
public async deleteSelectedGroup(): Promise<void> {
await this.repo.delete(this.selectedGroup)
this.cancelEditing();
}
/**
@ -136,9 +133,9 @@ export class GroupListComponent extends BaseComponent implements OnInit {
* @param group
* @param perm
*/
public togglePerm(viewGroup: ViewGroup, perm: string): void {
public async togglePerm(viewGroup: ViewGroup, perm: string): Promise<void> {
const updateData = new Group({ permissions: viewGroup.getAlteredPermissions(perm) });
this.repo.update(updateData, viewGroup).subscribe();
await this.repo.update(updateData, viewGroup);
}
/**

View File

@ -253,23 +253,17 @@ export class UserDetailComponent implements OnInit {
/**
* Save / Submit a user
*/
public saveUser(): void {
public async saveUser(): Promise<void> {
if (this.newUser) {
this.repo.create(this.personalInfoForm.value).subscribe(
response => {
const response = await this.repo.create(this.personalInfoForm.value);
this.newUser = false;
this.router.navigate([`./users/${response.id}`]);
},
error => console.error('Creation of the user failed: ', error.error)
);
} else {
this.repo.update(this.personalInfoForm.value, this.user).subscribe(
response => {
// TODO (Issue #3962): We need a waiting-State, so if autoupdates come before the response,
// the user is also updated.
await this.repo.update(this.personalInfoForm.value, this.user);
this.setEditMode(false);
this.loadViewUser(response.id);
},
error => console.error('Update of the user failed: ', error.error)
);
this.loadViewUser(this.user.id);
}
}
@ -290,10 +284,9 @@ export class UserDetailComponent implements OnInit {
/**
* click on the delete user button
*/
public deleteUserButton(): void {
this.repo.delete(this.user).subscribe(response => {
public async deleteUserButton(): Promise<void> {
await this.repo.delete(this.user);
this.router.navigate(['./users/']);
});
}
/**

View File

@ -1,5 +1,4 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { ViewGroup } from '../models/view-group';
import { BaseRepository } from '../../base/base-repository';
@ -7,7 +6,7 @@ import { Group } from '../../../shared/models/users/group';
import { DataStoreService } from '../../../core/services/data-store.service';
import { DataSendService } from '../../../core/services/data-send.service';
import { ConstantsService } from '../../../core/services/constants.service';
import { HTTPMethod } from 'app/core/services/http.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Set rules to define the shape of an app permission
@ -109,10 +108,10 @@ export class GroupRepositoryService extends BaseRepository<ViewGroup, Group> {
*
* @param groupData form value. Usually not yet a real user
*/
public create(groupData: Partial<Group>): Observable<any> {
public async create(groupData: Partial<Group>): Promise<Identifiable> {
const newGroup = new Group();
newGroup.patchValues(groupData);
return this.dataSend.createModel(newGroup);
return await this.dataSend.createModel(newGroup);
}
/**
@ -121,18 +120,18 @@ export class GroupRepositoryService extends BaseRepository<ViewGroup, Group> {
* @param permission the new permission
* @param viewGroup the selected Group
*/
public update(groupData: Partial<Group>, viewGroup: ViewGroup): Observable<any> {
public async update(groupData: Partial<Group>, viewGroup: ViewGroup): Promise<void> {
const updateGroup = new Group();
updateGroup.patchValues(viewGroup.group);
updateGroup.patchValues(groupData);
return this.dataSend.updateModel(updateGroup, HTTPMethod.PUT);
await this.dataSend.updateModel(updateGroup);
}
/**
* Deletes a given group
*/
public delete(viewGroup: ViewGroup): Observable<any> {
return this.dataSend.deleteModel(viewGroup.group);
public async delete(viewGroup: ViewGroup): Promise<void> {
await this.dataSend.deleteModel(viewGroup.group);
}
public createViewModel(group: Group): ViewGroup {

View File

@ -4,10 +4,9 @@ import { BaseRepository } from '../../base/base-repository';
import { ViewUser } from '../models/view-user';
import { User } from '../../../shared/models/users/user';
import { Group } from '../../../shared/models/users/group';
import { Observable } from 'rxjs';
import { DataStoreService } from '../../../core/services/data-store.service';
import { DataSendService } from '../../../core/services/data-send.service';
import { HTTPMethod } from '../../../core/services/http.service';
import { Identifiable } from '../../../shared/models/base/identifiable';
/**
* Repository service for users
@ -31,7 +30,7 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
* @param update the forms values
* @param viewUser
*/
public update(update: Partial<User>, viewUser: ViewUser): Observable<any> {
public async update(update: Partial<User>, viewUser: ViewUser): Promise<void> {
const updateUser = new User();
// copy the ViewUser to avoid manipulation of parameters
updateUser.patchValues(viewUser.user);
@ -43,14 +42,14 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
updateUser.username = viewUser.username;
}
return this.dataSend.updateModel(updateUser, HTTPMethod.PUT);
await this.dataSend.updateModel(updateUser);
}
/**
* Deletes a given user
*/
public delete(viewUser: ViewUser): Observable<any> {
return this.dataSend.deleteModel(viewUser.user);
public async delete(viewUser: ViewUser): Promise<void> {
await this.dataSend.deleteModel(viewUser.user);
}
/**
@ -59,7 +58,7 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
* TODO: used over not-yet-existing detail view
* @param userData blank form value. Usually not yet a real user
*/
public create(userData: Partial<User>): Observable<any> {
public async create(userData: Partial<User>): Promise<Identifiable> {
const newUser = new User();
// collectionString of userData is still empty
newUser.patchValues(userData);
@ -73,7 +72,7 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
}
});
return this.dataSend.createModel(newUser);
return await this.dataSend.createModel(newUser);
}
public createViewModel(user: User): ViewUser {