Cleanup the repo-cleanup

Adds a "patch" function to allow more modles to send patches with minimal data
rather than just the whole model.

Re-Adds the throwing of some errors to prevent developers from calling
methods that should not be called
This commit is contained in:
Sean Engelhardt 2019-03-25 09:45:11 +01:00
parent 0532a23219
commit 3cd58aa6c5
9 changed files with 117 additions and 22 deletions

View File

@ -32,7 +32,6 @@ export class DataSendService {
/**
* Function to fully update a model on the server.
* TODO: Deprecated (?)
*
* @param model The model that is meant to be changed.
*/

View File

@ -173,17 +173,31 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
}
/**
* Saves the update to an existing model. So called "update"-function
* Saves the (full) update to an existing model. So called "update"-function
* Provides a default procedure, but can be overwritten if required
*
* @param update the update that should be created
* @param viewModel the view model that the update is based on
*/
public async update(update: object, viewModel: BaseViewModel): Promise<void> {
public async update(update: Partial<M>, viewModel: V): Promise<void> {
const sendUpdate = new this.baseModelCtor();
sendUpdate.patchValues(viewModel.getModel());
sendUpdate.patchValues(update);
return await this.dataSend.partialUpdateModel(sendUpdate);
return await this.dataSend.updateModel(sendUpdate);
}
/**
* patches an existing model with new data,
* rather than sending a full update
*
* @param update the update to send
* @param viewModel the motion to update
*/
public async patch(update: Partial<M>, viewModel: V): Promise<void> {
const patch = new this.baseModelCtor();
patch.id = viewModel.id;
patch.patchValues(update);
return await this.dataSend.partialUpdateModel(patch);
}
/**
@ -192,7 +206,7 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
*
* @param viewModel the view model to delete
*/
public async delete(viewModel: BaseViewModel): Promise<void> {
public async delete(viewModel: V): Promise<void> {
return await this.dataSend.deleteModel(viewModel.getModel());
}
@ -202,7 +216,7 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
*
* @param model the model to create on the server
*/
public async create(model: BaseModel): Promise<Identifiable> {
public async create(model: M): Promise<Identifiable> {
// this ensures we get a valid base model, even if the view was just
// sending an object with "as MyModelClass"
const sendModel = new this.baseModelCtor();

View File

@ -8,6 +8,7 @@ import { DataSendService } from 'app/core/core-services/data-send.service';
import { DataStoreService } from 'app/core/core-services/data-store.service';
import { ConstantsService } from 'app/core/ui-services/constants.service';
import { HttpService } from 'app/core/core-services/http.service';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from 'app/core/core-services/collectionStringMapper.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { ViewConfig } from 'app/site/config/models/view-config';
@ -127,6 +128,24 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config>
return viewConfig;
}
/**
* Overwrites the default delete procedure
*
* @ignore
*/
public async delete(): Promise<void> {
throw new Error('Config variables cannot be deleted');
}
/**
* Overwrite the default create procedure.
*
* @ignore
*/
public async create(): Promise<Identifiable> {
throw new Error('Config variables cannot be created');
}
/**
* Overwritten setup. Does only care about the custom list observable and inserts changed configs into the
* config group structure.

View File

@ -4,6 +4,7 @@ import { CollectionStringMapperService } from 'app/core/core-services/collection
import { DataStoreService } from 'app/core/core-services/data-store.service';
import { BaseRepository } from 'app/core/repositories/base-repository';
import { History } from 'app/shared/models/core/history';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { User } from 'app/shared/models/users/user';
import { HttpService } from 'app/core/core-services/http.service';
import { ViewHistory } from 'app/site/history/models/view-history';
@ -60,6 +61,35 @@ export class HistoryRepositoryService extends BaseRepository<ViewHistory, Histor
}
/**
* Overwrites the default procedure
*
* @ignore
*/
public async create(): Promise<Identifiable> {
throw new Error('You cannot create a history object');
}
/**
* Overwrites the default procedure
*
* @ignore
*/
public async update(): Promise<void> {
throw new Error('You cannot update a history object');
}
/**
* Overwrites the default procedure
*
* @ignore
*/
public async patch(): Promise<void> {
throw new Error('You cannot patch a history object');
}
/**
* Overwrites the default procedure
*
* Sends a post-request to delete history objects
*/
public async delete(): Promise<void> {

View File

@ -33,7 +33,7 @@ export class MediafileRepositoryService extends BaseRepository<ViewMediafile, Me
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
translate: TranslateService,
protected dataSend: DataSendService,
dataSend: DataSendService,
private httpService: HttpService
) {
super(DS, dataSend, mapperService, viewModelStoreService, translate, Mediafile, [User]);

View File

@ -317,9 +317,7 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
* @param categoryId the number that indicates the category
*/
public async setCatetory(viewMotion: ViewMotion, categoryId: number): Promise<void> {
const motion = viewMotion.motion;
motion.category_id = categoryId;
await this.update(motion, viewMotion);
await this.patch({ category_id: categoryId }, viewMotion);
}
/**
@ -329,9 +327,7 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
* @param blockId the ID of the motion block
*/
public async setBlock(viewMotion: ViewMotion, blockId: number): Promise<void> {
const motion = viewMotion.motion;
motion.motion_block_id = blockId;
await this.update(motion, viewMotion);
await this.patch({ motion_block_id: blockId }, viewMotion);
}
/**
@ -341,17 +337,17 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
* @param tagId the tags id to add or remove
*/
public async setTag(viewMotion: ViewMotion, tagId: number): Promise<void> {
const motion = viewMotion.motion;
const tagIndex = motion.tags_id.findIndex(tag => tag === tagId);
const tags = viewMotion.motion.tags_id.map(tag => tag);
const tagIndex = tags.findIndex(tag => tag === tagId);
if (tagIndex === -1) {
// add tag to motion
motion.tags_id.push(tagId);
tags.push(tagId);
} else {
// remove tag from motion
motion.tags_id.splice(tagIndex, 1);
tags.splice(tagIndex, 1);
}
await this.update(motion, viewMotion);
await this.patch({ tags_id: tags }, viewMotion);
}
/**
@ -780,7 +776,7 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
*/
public async setStateExtension(viewMotion: ViewMotion, value: string): Promise<void> {
if (viewMotion.state.show_state_extension_field) {
return this.update({ state_extension: value }, viewMotion);
return this.patch({ state_extension: value }, viewMotion);
}
}
@ -792,7 +788,7 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
*/
public async setRecommendationExtension(viewMotion: ViewMotion, value: string): Promise<void> {
if (viewMotion.recommendation.show_recommendation_extension_field) {
return this.update({ recommendation_extension: value }, viewMotion);
return this.patch({ recommendation_extension: value }, viewMotion);
}
}

View File

@ -6,6 +6,7 @@ import { DataSendService } from 'app/core/core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { PersonalNote } from 'app/shared/models/users/personal-note';
import { ViewPersonalNote } from 'app/site/users/models/view-personal-note';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
@ -39,4 +40,40 @@ export class PersonalNoteRepositoryService extends BaseRepository<ViewPersonalNo
viewPersonalNote.getVerboseName = this.getVerboseName;
return viewPersonalNote;
}
/**
* Overwrite the default procedure
*
* @ignore
*/
public async create(): Promise<Identifiable> {
throw new Error('Not supported');
}
/**
* Overwrite the default procedure
*
* @ignore
*/
public async update(): Promise<void> {
throw new Error('Not supported');
}
/**
* Overwrite the default procedure
*
* @ignore
*/
public async patch(): Promise<void> {
throw new Error('Not supported');
}
/**
* Overwrite the default procedure
*
* @ignore
*/
public async delete(): Promise<void> {
throw new Error('Not supported');
}
}

View File

@ -104,7 +104,7 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
updateUser.gender = '';
}
return await this.dataSend.partialUpdateModel(updateUser);
return await this.dataSend.updateModel(updateUser);
}
/**

View File

@ -671,7 +671,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
origin: [''],
statute_amendment: [''], // Internal value for the checkbox, not saved to the model
statute_paragraph_id: [''],
motion_block_id: [],
motion_block_id: [], // TODO: Can be removed if this is not required
parent_id: []
});
this.updateWorkflowIdForCreateForm();