Merge pull request #4508 from tsiegleauq/cleanup-motion-detail-ds-repos

Cleanup Repos
This commit is contained in:
Sean 2019-03-14 11:40:56 +01:00 committed by GitHub
commit 09ddc83d30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 435 additions and 818 deletions

View File

@ -29,7 +29,7 @@ const routes: Routes = [
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],
exports: [RouterModule]
})
export class AppRoutingModule {}

View File

@ -28,10 +28,6 @@ export class AuthGuard implements CanActivate, CanActivateChild {
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const basePerm: string | string[] = route.data.basePerm;
console.log('Auth guard');
console.log('motions.can_see:', this.operator.hasPerms('motions.can_see'));
console.log('motions.can_manage:', this.operator.hasPerms('motions.can_manage'));
if (!basePerm) {
return true;
} else if (basePerm instanceof Array) {

View File

@ -32,6 +32,7 @@ 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

@ -95,7 +95,6 @@ export class OpenSlidesService {
* @param userId the id or null for guest
*/
public async afterLoginBootup(userId: number | null): Promise<void> {
console.log('user id', userId);
// Check, which user was logged in last time
const lastUserId = await this.storageService.get<number>('lastUserLoggedIn');
// if the user changed, reset the cache and save the new user.

View File

@ -2,22 +2,21 @@ import { Injectable } from '@angular/core';
import { tap, map } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { BaseAgendaContentObjectRepository } from '../base-agenda-content-object-repository';
import { BaseRepository } from '../base-repository';
import { BaseAgendaViewModel } from 'app/site/base/base-agenda-view-model';
import { BaseViewModel } from 'app/site/base/base-view-model';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ConfigService } from 'app/core/ui-services/config.service';
import { DataSendService } from 'app/core/core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service';
import { HttpService } from 'app/core/core-services/http.service';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { Item } from 'app/shared/models/agenda/item';
import { OSTreeSortEvent } from 'app/shared/components/sorting-tree/sorting-tree.component';
import { ViewItem } from 'app/site/agenda/models/view-item';
import { TreeService } from 'app/core/ui-services/tree.service';
import { BaseAgendaViewModel } from 'app/site/base/base-agenda-view-model';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { BaseViewModel } from 'app/site/base/base-view-model';
import { TranslateService } from '@ngx-translate/core';
import { BaseAgendaContentObjectRepository } from '../base-agenda-content-object-repository';
import { TreeService } from 'app/core/ui-services/tree.service';
import { ViewItem } from 'app/site/agenda/models/view-item';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
/**
* Repository service for users
@ -42,13 +41,13 @@ export class ItemRepositoryService extends BaseRepository<ViewItem, Item> {
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
protected dataSend: DataSendService,
private httpService: HttpService,
private config: ConfigService,
private dataSend: DataSendService,
private treeService: TreeService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, Item);
super(DS, dataSend, mapperService, viewModelStoreService, Item);
}
public getVerboseName = (plural: boolean = false) => {
@ -118,18 +117,6 @@ export class ItemRepositoryService extends BaseRepository<ViewItem, Item> {
}
}
/**
* Updates an agenda item
*
* @param update contains the update data
* @param viewItem the item to update
*/
public async update(update: Partial<Item>, viewItem: ViewItem): Promise<void> {
const updateItem = viewItem.item;
updateItem.patchValues(update);
return await this.dataSend.partialUpdateModel(updateItem);
}
/**
* Trigger the automatic numbering sequence on the server
*/
@ -150,15 +137,6 @@ export class ItemRepositoryService extends BaseRepository<ViewItem, Item> {
await this.httpService.delete(restUrl);
}
/**
* @ignore
*
* Agenda items are created implicitly and do not have on create functions
*/
public async create(item: Item): Promise<Identifiable> {
throw new Error('Method not implemented.');
}
/**
* Get agenda visibility from the config
*

View File

@ -2,19 +2,17 @@ import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Topic } from 'app/shared/models/topics/topic';
import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
import { Item } from 'app/shared/models/agenda/item';
import { BaseAgendaContentObjectRepository } from '../base-agenda-content-object-repository';
import { CollectionStringMapperService } from 'app/core/core-services/collectionStringMapper.service';
import { DataStoreService } from 'app/core/core-services/data-store.service';
import { DataSendService } from 'app/core/core-services/data-send.service';
import { Item } from 'app/shared/models/agenda/item';
import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
import { Topic } from 'app/shared/models/topics/topic';
import { ViewTopic } from 'app/site/agenda/models/view-topic';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from 'app/core/core-services/collectionStringMapper.service';
import { CreateTopic } from 'app/site/agenda/models/create-topic';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
import { ViewItem } from 'app/site/agenda/models/view-item';
import { BaseAgendaContentObjectRepository } from '../base-agenda-content-object-repository';
/**
* Repository for topics
@ -34,10 +32,10 @@ export class TopicRepositoryService extends BaseAgendaContentObjectRepository<Vi
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, Topic, [Mediafile, Item]);
super(DS, dataSend, mapperService, viewModelStoreService, Topic, [Mediafile, Item]);
}
public getAgendaTitle = (topic: Partial<Topic> | Partial<ViewTopic>) => {
@ -69,39 +67,6 @@ export class TopicRepositoryService extends BaseAgendaContentObjectRepository<Vi
return viewTopic;
}
/**
* Save a new topic
*
* @param topicData Partial topic data to be created
* @returns an Identifiable (usually id) as promise
*/
public async create(topic: CreateTopic): Promise<Identifiable> {
return await this.dataSend.createModel(topic);
}
/**
* Change an existing topic
*
* @param updateData form value containing the data meant to update the topic
* @param viewTopic the topic that should receive the update
*/
public async update(updateData: Partial<Topic>, viewTopic: ViewTopic): Promise<void> {
const updateTopic = new Topic();
updateTopic.patchValues(viewTopic.topic);
updateTopic.patchValues(updateData);
return await this.dataSend.updateModel(updateTopic);
}
/**
* Delete a topic
*
* @param viewTopic the topic that should be removed
*/
public async delete(viewTopic: ViewTopic): Promise<void> {
return await this.dataSend.deleteModel(viewTopic.topic);
}
/**
* Returns an array of all duplicates for a topic
*

View File

@ -2,19 +2,19 @@ import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { ViewAssignment } from 'app/site/assignments/models/view-assignment';
import { Assignment } from 'app/shared/models/assignments/assignment';
import { User } from 'app/shared/models/users/user';
import { Tag } from 'app/shared/models/core/tag';
import { Item } from 'app/shared/models/agenda/item';
import { DataStoreService } from '../../core-services/data-store.service';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { ViewItem } from 'app/site/agenda/models/view-item';
import { ViewUser } from 'app/site/users/models/view-user';
import { ViewTag } from 'app/site/tags/models/view-tag';
import { BaseAgendaContentObjectRepository } from '../base-agenda-content-object-repository';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { DataSendService } from 'app/core/core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service';
import { Item } from 'app/shared/models/agenda/item';
import { Tag } from 'app/shared/models/core/tag';
import { User } from 'app/shared/models/users/user';
import { ViewAssignment } from 'app/site/assignments/models/view-assignment';
import { ViewItem } from 'app/site/agenda/models/view-item';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { ViewTag } from 'app/site/tags/models/view-tag';
import { ViewUser } from 'app/site/users/models/view-user';
/**
* Repository Service for Assignments.
@ -33,11 +33,12 @@ export class AssignmentRepositoryService extends BaseAgendaContentObjectReposito
*/
public constructor(
DS: DataStoreService,
dataSend: DataSendService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, Assignment, [User, Item, Tag]);
super(DS, dataSend, mapperService, viewModelStoreService, Assignment, [User, Item, Tag]);
}
public getAgendaTitle = (assignment: Partial<Assignment> | Partial<ViewAssignment>) => {
@ -63,16 +64,4 @@ export class AssignmentRepositoryService extends BaseAgendaContentObjectReposito
viewAssignment.getAgendaTitleWithType = () => this.getAgendaTitleWithType(viewAssignment);
return viewAssignment;
}
public async update(assignment: Partial<Assignment>, viewAssignment: ViewAssignment): Promise<void> {
return null;
}
public async delete(viewAssignment: ViewAssignment): Promise<void> {
return null;
}
public async create(assignment: Assignment): Promise<Identifiable> {
return null;
}
}

View File

@ -1,6 +1,7 @@
import { BaseViewModel } from '../../site/base/base-view-model';
import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model';
import { CollectionStringMapperService } from '../core-services/collectionStringMapper.service';
import { DataSendService } from '../core-services/data-send.service';
import { DataStoreService } from '../core-services/data-store.service';
import { ViewModelStoreService } from '../core-services/view-model-store.service';
import { BaseRepository } from './base-repository';
@ -21,11 +22,12 @@ export abstract class BaseAgendaContentObjectRepository<
*/
public constructor(
DS: DataStoreService,
dataSend: DataSendService,
collectionStringMapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
baseModelCtor: ModelConstructor<M>,
depsModelCtors?: ModelConstructor<BaseModel>[]
) {
super(DS, collectionStringMapperService, viewModelStoreService, baseModelCtor, depsModelCtors);
super(DS, dataSend, collectionStringMapperService, viewModelStoreService, baseModelCtor, depsModelCtors);
}
}

View File

@ -3,6 +3,7 @@ import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { BaseViewModel } from '../../site/base/base-view-model';
import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model';
import { CollectionStringMapperService } from '../core-services/collectionStringMapper.service';
import { DataSendService } from '../core-services/data-send.service';
import { DataStoreService } from '../core-services/data-store.service';
import { Identifiable } from '../../shared/models/base/identifiable';
import { auditTime } from 'rxjs/operators';
@ -27,6 +28,8 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
*/
protected readonly viewModelListSubject: BehaviorSubject<V[]> = new BehaviorSubject<V[]>([]);
protected readonly viewModelListAuditSubject: BehaviorSubject<V[]> = new BehaviorSubject<V[]>([]);
/**
* Observable subject for any changes of view models.
*/
@ -59,12 +62,15 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
*/
public constructor(
protected DS: DataStoreService,
protected dataSend: DataSendService,
protected collectionStringMapperService: CollectionStringMapperService,
protected viewModelStoreService: ViewModelStoreService,
protected baseModelCtor: ModelConstructor<M>,
protected depsModelCtors?: ModelConstructor<BaseModel>[]
) {
this._collectionString = baseModelCtor.COLLECTIONSTRING;
this.getViewModelListObservable().subscribe(x => this.viewModelListAuditSubject.next(x));
}
public onAfterAppsLoaded(): void {
@ -137,25 +143,50 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
/**
* Saves the 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 abstract async update(update: Partial<M>, viewModel: V): Promise<void>;
public async update(update: object, viewModel: BaseViewModel): Promise<void> {
const sendUpdate = new this.baseModelCtor();
sendUpdate.patchValues(viewModel.getModel());
sendUpdate.patchValues(update);
return await this.dataSend.partialUpdateModel(sendUpdate);
}
/**
* Deletes a given Model
* @param update the update that should be created
* @param viewModel the view model that the update is based on
* Provides a default procedure, but can be overwritten if required
*
* @param viewModel the view model to delete
*/
public abstract async delete(viewModel: V): Promise<void>;
public async delete(viewModel: BaseViewModel): Promise<void> {
return await this.dataSend.deleteModel(viewModel.getModel());
}
/**
* Creates a new model
* @param update the update that should be created
* @param viewModel the view model that the update is based on
* TODO: remove the viewModel
* Creates a new model.
* Provides a default procedure, but can be overwritten if required
*
* @param model the model to create on the server
*/
public abstract async create(update: M): Promise<Identifiable>;
public async create(model: BaseModel): 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();
sendModel.patchValues(model);
// Strips empty fields from the sending mode data.
// required for i.e. users, since group list is mandatory
Object.keys(sendModel).forEach(key => {
if (!sendModel[key]) {
delete sendModel[key];
}
});
return await this.dataSend.createModel(sendModel);
}
/**
* Creates a view model out of a base model.
@ -209,6 +240,16 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
return this.viewModelListSubject.asObservable().pipe(auditTime(1));
}
/**
* Returns the ViewModelList as piped Behavior Subject.
* Prevents unnecessary calls.
*
* @returns A subject that holds the model list
*/
public getViewModelListBehaviorSubject(): BehaviorSubject<V[]> {
return this.viewModelListAuditSubject;
}
/**
* This observable fires every time an object is changed in the repository.
*/

View File

@ -1,12 +1,12 @@
import { Injectable } from '@angular/core';
import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ChatMessage } from 'app/shared/models/core/chat-message';
import { ViewChatMessage } from 'app/site/common/models/view-chatmessage';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core';
import { DataSendService } from 'app/core/core-services/data-send.service';
@Injectable({
providedIn: 'root'
@ -14,11 +14,12 @@ import { TranslateService } from '@ngx-translate/core';
export class ChatMessageRepositoryService extends BaseRepository<ViewChatMessage, ChatMessage> {
public constructor(
DS: DataStoreService,
dataSend: DataSendService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, ChatMessage);
super(DS, dataSend, mapperService, viewModelStoreService, ChatMessage);
}
public getVerboseName = (plural: boolean = false) => {
@ -30,16 +31,4 @@ export class ChatMessageRepositoryService extends BaseRepository<ViewChatMessage
viewChatMessage.getVerboseName = this.getVerboseName;
return viewChatMessage;
}
public async create(message: ChatMessage): Promise<Identifiable> {
throw new Error('TODO');
}
public async update(message: Partial<ChatMessage>, viewMessage: ViewChatMessage): Promise<void> {
throw new Error('TODO');
}
public async delete(viewMessage: ViewChatMessage): Promise<void> {
throw new Error('TODO');
}
}

View File

@ -4,10 +4,10 @@ import { Observable, BehaviorSubject } from 'rxjs';
import { BaseRepository } from 'app/core/repositories/base-repository';
import { Config } from 'app/shared/models/core/config';
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';
@ -97,13 +97,14 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config>
*/
public constructor(
DS: DataStoreService,
dataSend: DataSendService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private constantsService: ConstantsService,
private http: HttpService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, Config);
super(DS, dataSend, mapperService, viewModelStoreService, Config);
this.constantsService.get('OpenSlidesConfigVariables').subscribe(constant => {
this.createConfigStructure(constant);
@ -142,6 +143,7 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config>
this.updateConfigListObservable();
// Could be raise in error if the root injector is not known
// TODO go over repo
this.DS.changeObservable.subscribe(model => {
if (model instanceof Config) {
this.viewModelStore[model.id] = this.createViewModel(model as Config);
@ -219,26 +221,6 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config>
await this.http.put('rest/' + updatedConfig.collectionString + '/' + updatedConfig.key + '/', updatedConfig);
}
/**
* This particular function should never be necessary since the creation of config
* values is not planed.
*
* Function exists solely to correctly implement {@link BaseRepository}
*/
public async delete(config: ViewConfig): Promise<void> {
throw new Error('Config variables cannot be deleted');
}
/**
* This particular function should never be necessary since the creation of config
* values is not planed.
*
* Function exists solely to correctly implement {@link BaseRepository}
*/
public async create(config: Config): Promise<Identifiable> {
throw new Error('Config variables cannot be created');
}
/**
* initially create the config structure from the given constant.
* @param constant

View File

@ -5,13 +5,13 @@ 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 { User } from 'app/shared/models/users/user';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { HttpService } from 'app/core/core-services/http.service';
import { ViewHistory } from 'app/site/history/models/view-history';
import { TimeTravelService } from 'app/core/core-services/time-travel.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { ViewUser } from 'app/site/users/models/view-user';
import { TranslateService } from '@ngx-translate/core';
import { DataSendService } from 'app/core/core-services/data-send.service';
/**
* Repository for the history.
@ -32,13 +32,14 @@ export class HistoryRepositoryService extends BaseRepository<ViewHistory, Histor
*/
public constructor(
DS: DataStoreService,
dataSend: DataSendService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private httpService: HttpService,
private timeTravel: TimeTravelService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, History, [User]);
super(DS, dataSend, mapperService, viewModelStoreService, History, [User]);
}
public getVerboseName = (plural: boolean = false) => {
@ -58,22 +59,6 @@ export class HistoryRepositoryService extends BaseRepository<ViewHistory, Histor
return viewHistory;
}
/**
* Clients usually do not need to create a history object themselves
* @ignore
*/
public async create(): Promise<Identifiable> {
throw new Error('You cannot create a history object');
}
/**
* Clients usually do not need to modify existing history objects
* @ignore
*/
public async update(): Promise<void> {
throw new Error('You cannot update a history object');
}
/**
* Sends a post-request to delete history objects
*/

View File

@ -32,11 +32,11 @@ export class MediafileRepositoryService extends BaseRepository<ViewMediafile, Me
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private httpService: HttpService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, Mediafile, [User]);
super(DS, dataSend, mapperService, viewModelStoreService, Mediafile, [User]);
}
public getVerboseName = (plural: boolean = false) => {
@ -56,39 +56,6 @@ export class MediafileRepositoryService extends BaseRepository<ViewMediafile, Me
return viewMediafile;
}
/**
* Alter a given mediaFile
* Usually just i.e change the name and the hidden flag.
*
* @param file contains the new values
* @param viewFile the file that should be updated
*/
public async update(file: Partial<Mediafile>, viewFile: ViewMediafile): Promise<void> {
const updateFile = new Mediafile();
updateFile.patchValues(viewFile.mediafile);
updateFile.patchValues(file);
await this.dataSend.updateModel(updateFile);
}
/**
* Deletes the given file from the server
*
* @param file the file to delete
*/
public async delete(file: ViewMediafile): Promise<void> {
return await this.dataSend.deleteModel(file.mediafile);
}
/**
* Mediafiles are uploaded using FormData objects and (usually) not created locally.
*
* @param file a new mediafile
* @returns the ID as a promise
*/
public async create(file: Mediafile): Promise<Identifiable> {
return await this.dataSend.createModel(file);
}
/**
* Uploads a file to the server.
* The HttpHeader should be Application/FormData, the empty header will

View File

@ -10,7 +10,6 @@ import { ConfigService } from 'app/core/ui-services/config.service';
import { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service';
import { HttpService } from '../../core-services/http.service';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { ViewCategory } from 'app/site/motions/models/view-category';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
@ -44,12 +43,12 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
protected DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private httpService: HttpService,
private configService: ConfigService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, Category);
super(DS, dataSend, mapperService, viewModelStoreService, Category);
}
public getVerboseName = (plural: boolean = false) => {
@ -62,26 +61,6 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
return viewCategory;
}
public async create(newCategory: Category): Promise<Identifiable> {
return await this.dataSend.createModel(newCategory);
}
public async update(category: Partial<Category>, viewCategory: ViewCategory): Promise<void> {
let updateCategory: Category;
if (viewCategory) {
updateCategory = viewCategory.category;
} else {
updateCategory = new Category();
}
updateCategory.patchValues(category);
await this.dataSend.updateModel(updateCategory);
}
public async delete(viewCategory: ViewCategory): Promise<void> {
const category = viewCategory.category;
await this.dataSend.deleteModel(category);
}
/**
* Returns the category for the ID
* @param category_id category ID

View File

@ -47,10 +47,14 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, MotionChangeRecommendation, [Category, User, Workflow]);
super(DS, dataSend, mapperService, viewModelStoreService, MotionChangeRecommendation, [
Category,
User,
Workflow
]);
}
public getVerboseName = (plural: boolean = false) => {
@ -68,16 +72,6 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<
return viewMotionChangeRecommendation;
}
/**
* Creates a change recommendation
* Creates a (real) change recommendation and delegates it to the {@link DataSendService}
*
* @param {MotionChangeRecommendation} changeReco
*/
public async create(changeReco: MotionChangeRecommendation): Promise<Identifiable> {
return await this.dataSend.createModel(changeReco);
}
/**
* Given a change recommendation view object, a entry in the backend is created.
* @param view
@ -87,35 +81,6 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<
return await this.dataSend.createModel(view.changeRecommendation);
}
/**
* Deleting a change recommendation.
*
* Extract the change recommendation out of the viewModel and delegate
* to {@link DataSendService}
* @param {ViewMotionChangeRecommendation} viewModel
*/
public async delete(viewModel: ViewMotionChangeRecommendation): Promise<void> {
await this.dataSend.deleteModel(viewModel.changeRecommendation);
}
/**
* updates a change recommendation
*
* Updates a (real) change recommendation with patched data and delegate it
* to the {@link DataSendService}
*
* @param {Partial<MotionChangeRecommendation>} update the form data containing the update values
* @param {ViewMotionChangeRecommendation} viewModel The View Change Recommendation. If not present, a new motion will be created
*/
public async update(
update: Partial<MotionChangeRecommendation>,
viewModel: ViewMotionChangeRecommendation
): Promise<void> {
const changeReco = viewModel.changeRecommendation;
changeReco.patchValues(update);
await this.dataSend.partialUpdateModel(changeReco);
}
/**
* return the Observable of all change recommendations belonging to the given motion
*/

View File

@ -8,7 +8,6 @@ import { CollectionStringMapperService } from 'app/core/core-services/collection
import { DataSendService } from 'app/core/core-services/data-send.service';
import { DataStoreService } from 'app/core/core-services/data-store.service';
import { HttpService } from 'app/core/core-services/http.service';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { Motion } from 'app/shared/models/motions/motion';
import { MotionBlock } from 'app/shared/models/motions/motion-block';
import { MotionRepositoryService } from './motion-repository.service';
@ -39,12 +38,12 @@ export class MotionBlockRepositoryService extends BaseAgendaContentObjectReposit
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private motionRepo: MotionRepositoryService,
private httpService: HttpService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, MotionBlock, [Item]);
super(DS, dataSend, mapperService, viewModelStoreService, MotionBlock, [Item]);
}
public getAgendaTitle = (motionBlock: Partial<MotionBlock> | Partial<ViewMotionBlock>) => {
@ -74,38 +73,6 @@ export class MotionBlockRepositoryService extends BaseAgendaContentObjectReposit
return viewMotionBlock;
}
/**
* Updates a given motion block
*
* @param update a partial motion block containing the update data
* @param viewBlock the motion block to update
*/
public async update(update: Partial<MotionBlock>, viewBlock: ViewMotionBlock): Promise<void> {
const updateMotionBlock = new MotionBlock();
updateMotionBlock.patchValues(viewBlock.motionBlock);
updateMotionBlock.patchValues(update);
return await this.dataSend.updateModel(updateMotionBlock);
}
/**
* Deletes a motion block from the server
*
* @param newBlock the motion block to delete
*/
public async delete(newBlock: ViewMotionBlock): Promise<void> {
return await this.dataSend.deleteModel(newBlock.motionBlock);
}
/**
* Creates a new motion block to the server
*
* @param newBlock The new block to create
* @returns the ID of the created model as promise
*/
public async create(newBlock: MotionBlock): Promise<Identifiable> {
return await this.dataSend.createModel(newBlock);
}
/**
* Removes the motion block id from the given motion
*

View File

@ -6,7 +6,6 @@ import { BaseRepository } from '../base-repository';
import { ViewMotionCommentSection } from 'app/site/motions/models/view-motion-comment-section';
import { MotionCommentSection } from 'app/shared/models/motions/motion-comment-section';
import { Group } from 'app/shared/models/users/group';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { HttpService } from 'app/core/core-services/http.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
@ -45,11 +44,11 @@ export class MotionCommentSectionRepositoryService extends BaseRepository<
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private http: HttpService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, MotionCommentSection, [Group]);
super(DS, dataSend, mapperService, viewModelStoreService, MotionCommentSection, [Group]);
}
public getVerboseName = (plural: boolean = false) => {
@ -70,42 +69,6 @@ export class MotionCommentSectionRepositoryService extends BaseRepository<
return viewMotionCommentSection;
}
/**
* Creates the Comment Section
*
* @param section section to be created
* @returns the promise to create the comment section
*/
public async create(section: MotionCommentSection): Promise<Identifiable> {
return await this.dataSend.createModel(section);
}
/**
* Updates an existion CommentSection
*
* @param section the update that the section should be created on
* @param viewSection the view model representation of that section
*/
public async update(section: Partial<MotionCommentSection>, viewSection?: ViewMotionCommentSection): Promise<void> {
let updateSection: MotionCommentSection;
if (viewSection) {
updateSection = viewSection.section;
} else {
updateSection = new MotionCommentSection();
}
updateSection.patchValues(section);
await this.dataSend.updateModel(updateSection);
}
/**
* Deletes a MotionCommentSection
*
* @param viewSection the view model representation of the model that should be deleted
*/
public async delete(viewSection: ViewMotionCommentSection): Promise<void> {
await this.dataSend.deleteModel(viewSection.section);
}
/**
* Saves a comment made at a MotionCommentSection. Does an update, if
* there is a comment text. Deletes the comment, if the text is empty.

View File

@ -7,12 +7,10 @@ import { tap, map } from 'rxjs/operators';
import { Category } from 'app/shared/models/motions/category';
import { ChangeRecoMode, ViewMotion } from 'app/site/motions/models/view-motion';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { CreateMotion } from 'app/site/motions/models/create-motion';
import { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service';
import { DiffLinesInParagraph, DiffService, LineRange, ModificationType } from '../../ui-services/diff.service';
import { HttpService } from 'app/core/core-services/http.service';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { Item } from 'app/shared/models/agenda/item';
import { LinenumberingService } from '../../ui-services/linenumbering.service';
import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
@ -75,7 +73,7 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private httpService: HttpService,
private readonly lineNumbering: LinenumberingService,
private readonly diff: DiffService,
@ -83,7 +81,7 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
private translate: TranslateService,
private operator: OperatorService
) {
super(DS, mapperService, viewModelStoreService, Motion, [
super(DS, dataSend, mapperService, viewModelStoreService, Motion, [
Category,
User,
Workflow,
@ -258,45 +256,6 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
);
}
/**
* Creates a motion
* Creates a (real) motion with patched data and delegate it
* to the {@link DataSendService}
*
* @param update the form data containing the updated values
* @param viewMotion The View Motion. If not present, a new motion will be created
*/
public async create(motion: CreateMotion): Promise<Identifiable> {
// TODO how to handle category id and motion_block id in CreateMotion?
return await this.dataSend.createModel(motion);
}
/**
* updates a motion
*
* Creates a (real) motion with patched data and delegate it
* to the {@link DataSendService}
*
* @param update the form data containing the updated values
* @param viewMotion The View Motion. If not present, a new motion will be created
*/
public async update(update: Partial<Motion>, viewMotion: ViewMotion): Promise<void> {
const motion = viewMotion.motion;
motion.patchValues(update);
return await this.dataSend.partialUpdateModel(motion);
}
/**
* Deleting a motion.
*
* Extract the motion out of the motionView and delegate
* to {@link DataSendService}
* @param viewMotion
*/
public async delete(viewMotion: ViewMotion): Promise<void> {
return await this.dataSend.deleteModel(viewMotion.motion);
}
/**
* Set the state of a motion
*

View File

@ -5,7 +5,6 @@ import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository';
import { ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph';
import { StatuteParagraph } from 'app/shared/models/motions/statute-paragraph';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core';
@ -34,10 +33,10 @@ export class StatuteParagraphRepositoryService extends BaseRepository<ViewStatut
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, StatuteParagraph);
super(DS, dataSend, mapperService, viewModelStoreService, StatuteParagraph);
}
public getVerboseName = (plural: boolean = false) => {
@ -49,21 +48,4 @@ export class StatuteParagraphRepositoryService extends BaseRepository<ViewStatut
viewStatuteParagraph.getVerboseName = this.getVerboseName;
return viewStatuteParagraph;
}
public async create(statuteParagraph: StatuteParagraph): Promise<Identifiable> {
return await this.dataSend.createModel(statuteParagraph);
}
public async update(
statuteParagraph: Partial<StatuteParagraph>,
viewStatuteParagraph: ViewStatuteParagraph
): Promise<void> {
const updateParagraph = viewStatuteParagraph.statuteParagraph;
updateParagraph.patchValues(statuteParagraph);
await this.dataSend.updateModel(updateParagraph);
}
public async delete(viewStatuteParagraph: ViewStatuteParagraph): Promise<void> {
await this.dataSend.deleteModel(viewStatuteParagraph.statuteParagraph);
}
}

View File

@ -6,7 +6,6 @@ import { ViewWorkflow } from 'app/site/motions/models/view-workflow';
import { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { WorkflowState } from 'app/shared/models/motions/workflow-state';
import { ViewMotion } from 'app/site/motions/models/view-motion';
@ -45,12 +44,12 @@ export class WorkflowRepositoryService extends BaseRepository<ViewWorkflow, Work
public constructor(
DS: DataStoreService,
mapperService: CollectionStringMapperService,
private httpService: HttpService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private httpService: HttpService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, Workflow);
super(DS, dataSend, mapperService, viewModelStoreService, Workflow);
this.viewModelListSubject.pipe(auditTime(1)).subscribe(models => {
if (models && models.length > 0) {
this.initSorting(models);
@ -87,43 +86,6 @@ export class WorkflowRepositoryService extends BaseRepository<ViewWorkflow, Work
return viewWorkflow;
}
/**
* Creates a new workflow
*
* @param newWorkflow the workflow to create
* @returns the ID of a new workflow as promise
*/
public async create(newWorkflow: Workflow): Promise<Identifiable> {
return await this.dataSend.createModel(newWorkflow);
}
/**
* Updates the workflow by the given changes
*
* @param workflow Contains the update
* @param viewWorkflow the target workflow
*/
public async update(workflow: Partial<Workflow>, viewWorkflow: ViewWorkflow): Promise<void> {
let updateWorkflow: Workflow;
if (viewWorkflow) {
updateWorkflow = viewWorkflow.workflow;
} else {
updateWorkflow = new Workflow();
}
updateWorkflow.patchValues(workflow);
await this.dataSend.updateModel(updateWorkflow);
}
/**
* Deletes the given workflow
*
* @param viewWorkflow the workflow to delete
*/
public async delete(viewWorkflow: ViewWorkflow): Promise<void> {
const workflow = viewWorkflow.workflow;
await this.dataSend.deleteModel(workflow);
}
/**
* Adds a new state to the given workflow
*

View File

@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
import { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ViewCountdown } from 'app/site/projector/models/view-countdown';
import { Countdown } from 'app/shared/models/core/countdown';
@ -18,11 +17,11 @@ export class CountdownRepositoryService extends BaseRepository<ViewCountdown, Co
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private translate: TranslateService,
private servertimeService: ServertimeService
) {
super(DS, mapperService, viewModelStoreService, Countdown);
super(DS, dataSend, mapperService, viewModelStoreService, Countdown);
}
public getVerboseName = (plural: boolean = false) => {
@ -35,20 +34,6 @@ export class CountdownRepositoryService extends BaseRepository<ViewCountdown, Co
return viewCountdown;
}
public async create(countdown: Countdown): Promise<Identifiable> {
return await this.dataSend.createModel(countdown);
}
public async update(countdown: Partial<Countdown>, viewCountdown: ViewCountdown): Promise<void> {
const update = viewCountdown.countdown;
update.patchValues(countdown);
await this.dataSend.updateModel(update);
}
public async delete(countdown: ViewCountdown): Promise<void> {
await this.dataSend.deleteModel(countdown.countdown);
}
public async start(countdown: ViewCountdown): Promise<void> {
const endTime = this.servertimeService.getServertime() / 1000 + countdown.countdown_time;
await this.update({ running: true, countdown_time: endTime }, countdown);

View File

@ -1,7 +1,6 @@
import { Injectable } from '@angular/core';
import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ProjectorMessage } from 'app/shared/models/core/projector-message';
import { ViewProjectorMessage } from 'app/site/projector/models/view-projector-message';
@ -17,10 +16,10 @@ export class ProjectorMessageRepositoryService extends BaseRepository<ViewProjec
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private translate: TranslateService,
private dataSend: DataSendService
protected dataSend: DataSendService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, ProjectorMessage);
super(DS, dataSend, mapperService, viewModelStoreService, ProjectorMessage);
}
public getVerboseName = (plural: boolean = false) => {
@ -32,18 +31,4 @@ export class ProjectorMessageRepositoryService extends BaseRepository<ViewProjec
viewProjectorMessage.getVerboseName = this.getVerboseName;
return viewProjectorMessage;
}
public async create(message: ProjectorMessage): Promise<Identifiable> {
return await this.dataSend.createModel(message);
}
public async update(message: Partial<ProjectorMessage>, viewMessage: ViewProjectorMessage): Promise<void> {
const update = viewMessage.projectormessage;
update.patchValues(message);
await this.dataSend.updateModel(update);
}
public async delete(viewMessage: ViewProjectorMessage): Promise<void> {
await this.dataSend.deleteModel(viewMessage.projectormessage);
}
}

View File

@ -39,11 +39,11 @@ export class ProjectorRepositoryService extends BaseRepository<ViewProjector, Pr
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private http: HttpService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, Projector, [Projector]);
super(DS, dataSend, mapperService, viewModelStoreService, Projector, [Projector]);
}
public getVerboseName = (plural: boolean = false) => {
@ -66,25 +66,6 @@ export class ProjectorRepositoryService extends BaseRepository<ViewProjector, Pr
return await this.dataSend.createModel(projector);
}
/**
* Updates a projector.
*/
public async update(projectorData: Partial<Projector>, viewProjector: ViewProjector): Promise<void> {
const projector = new Projector();
projector.patchValues(viewProjector.projector);
projector.patchValues(projectorData);
await this.dataSend.updateModel(projector);
}
/**
* Deletes a given projector.
*
* @param projector
*/
public async delete(projector: ViewProjector): Promise<void> {
await this.dataSend.deleteModel(projector.projector);
}
/**
* Scroll the given projector.
*

View File

@ -5,7 +5,6 @@ import { ViewTag } from 'app/site/tags/models/view-tag';
import { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core';
@ -34,13 +33,13 @@ export class TagRepositoryService extends BaseRepository<ViewTag, Tag> {
* @param dataSend sending changed objects
*/
public constructor(
protected DS: DataStoreService,
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, Tag);
super(DS, dataSend, mapperService, viewModelStoreService, Tag);
}
public getVerboseName = (plural: boolean = false) => {
@ -52,21 +51,4 @@ export class TagRepositoryService extends BaseRepository<ViewTag, Tag> {
viewTag.getVerboseName = this.getVerboseName;
return viewTag;
}
public async create(update: Tag): Promise<Identifiable> {
const newTag = new Tag();
newTag.patchValues(update);
return await this.dataSend.createModel(newTag);
}
public async update(update: Partial<Tag>, viewTag: ViewTag): Promise<void> {
const updateTag = new Tag();
updateTag.patchValues(viewTag.tag);
updateTag.patchValues(update);
await this.dataSend.updateModel(updateTag);
}
public async delete(viewTag: ViewTag): Promise<void> {
await this.dataSend.deleteModel(viewTag.tag);
}
}

View File

@ -6,7 +6,6 @@ import { ConstantsService } from '../../ui-services/constants.service';
import { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service';
import { Group } from 'app/shared/models/users/group';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { ViewGroup } from 'app/site/users/models/view-group';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core';
@ -52,11 +51,11 @@ export class GroupRepositoryService extends BaseRepository<ViewGroup, Group> {
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private constants: ConstantsService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, Group);
super(DS, dataSend, mapperService, viewModelStoreService, Group);
this.sortPermsPerApp();
}
@ -161,35 +160,4 @@ export class GroupRepositoryService extends BaseRepository<ViewGroup, Group> {
}
});
}
/**
* creates and saves a new user
*
* @param groupData form value. Usually not yet a real user
*/
public async create(groupData: Partial<Group>): Promise<Identifiable> {
const newGroup = new Group();
newGroup.patchValues(groupData);
return await this.dataSend.createModel(newGroup);
}
/**
* Updates the given Group with the new permission
*
* @param permission the new permission
* @param viewGroup the selected Group
*/
public async update(groupData: Partial<Group>, viewGroup: ViewGroup): Promise<void> {
const updateGroup = new Group();
updateGroup.patchValues(viewGroup.group);
updateGroup.patchValues(groupData);
await this.dataSend.updateModel(updateGroup);
}
/**
* Deletes a given group
*/
public async delete(viewGroup: ViewGroup): Promise<void> {
await this.dataSend.deleteModel(viewGroup.group);
}
}

View File

@ -4,10 +4,10 @@ import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { PersonalNote } from 'app/shared/models/users/personal-note';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { ViewPersonalNote } from 'app/site/users/models/view-personal-note';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core';
import { DataSendService } from 'app/core/core-services/data-send.service';
/**
*/
@ -21,11 +21,12 @@ export class PersonalNoteRepositoryService extends BaseRepository<ViewPersonalNo
*/
public constructor(
DS: DataStoreService,
dataSend: DataSendService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private translate: TranslateService
) {
super(DS, mapperService, viewModelStoreService, PersonalNote);
super(DS, dataSend, mapperService, viewModelStoreService, PersonalNote);
}
public getVerboseName = (plural: boolean = false) => {
@ -37,16 +38,4 @@ export class PersonalNoteRepositoryService extends BaseRepository<ViewPersonalNo
viewPersonalNote.getVerboseName = this.getVerboseName;
return viewPersonalNote;
}
public async create(personalNote: PersonalNote): Promise<Identifiable> {
throw new Error('Not supported');
}
public async update(personalNote: Partial<PersonalNote>, viewPersonalNote: ViewPersonalNote): Promise<void> {
throw new Error('Not supported');
}
public async delete(viewPersonalNote: ViewPersonalNote): Promise<void> {
throw new Error('Not supported');
}
}

View File

@ -10,7 +10,6 @@ import { DataStoreService } from '../../core-services/data-store.service';
import { environment } from '../../../../environments/environment';
import { Group } from 'app/shared/models/users/group';
import { HttpService } from 'app/core/core-services/http.service';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { NewEntry } from 'app/core/ui-services/base-import.service';
import { User } from 'app/shared/models/users/user';
import { ViewUser } from 'app/site/users/models/view-user';
@ -43,12 +42,12 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
DS: DataStoreService,
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService,
protected dataSend: DataSendService,
private translate: TranslateService,
private httpService: HttpService,
private configService: ConfigService
) {
super(DS, mapperService, viewModelStoreService, User, [Group]);
super(DS, dataSend, mapperService, viewModelStoreService, User, [Group]);
}
public getVerboseName = (plural: boolean = false) => {
@ -67,13 +66,14 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
/**
* Updates a the selected user with the form values.
* Since user should actually "delete" field, the unified update method
* cannot be used
*
* @param update the forms values
* @param viewUser
*/
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);
updateUser.patchValues(update);
@ -89,37 +89,7 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
updateUser.gender = '';
}
return await this.dataSend.updateModel(updateUser);
}
/**
* Deletes a given user
*/
public async delete(viewUser: ViewUser): Promise<void> {
return await this.dataSend.deleteModel(viewUser.user);
}
/**
* creates and saves a new user
*
* TODO: used over not-yet-existing detail view
* @param userData blank form value. Usually not yet a real user
*/
public async create(userData: Partial<User>): Promise<Identifiable> {
const newUser = new User();
// collectionString of userData is still empty
newUser.patchValues(userData);
// during creation, the server demands that basically nothing must be null.
// during the update process, null values are interpreted as delete.
// therefore, remove "null" values.
Object.keys(newUser).forEach(key => {
if (!newUser[key]) {
delete newUser[key];
}
});
return await this.dataSend.createModel(newUser);
return await this.dataSend.partialUpdateModel(updateUser);
}
/**

View File

@ -6,6 +6,9 @@
.sticky-toolbar {
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
position: sticky;
top: 0px;
z-index: 3;

View File

@ -87,7 +87,7 @@ export class SearchValueSelectorComponent implements OnInit, OnDestroy {
this._inputListSubscription.unsubscribe();
}
this._inputListSubject = value;
this._inputListSubscription = this._inputListSubject.subscribe(values => {
this._inputListSubscription = this._inputListSubject.subscribe(() => {
this.filterItems();
});
}

View File

@ -159,9 +159,8 @@ export class ListOfSpeakersComponent extends BaseViewComponent implements OnInit
*/
public ngOnInit(): void {
// load and observe users
this.users = new BehaviorSubject(this.userRepository.getViewModelList());
this.userRepository.getSortedViewModelListObservable().subscribe(users => {
this.users.next(users);
this.users = this.userRepository.getViewModelListBehaviorSubject();
this.userRepository.getViewModelListBehaviorSubject().subscribe(newUsers => {
if (this.viewItem) {
this.setSpeakerList(this.viewItem.id);
}

View File

@ -96,13 +96,8 @@ export class TopicDetailComponent extends BaseViewComponent {
this.getTopicByUrl();
this.createForm();
this.mediafilesObserver = new BehaviorSubject(this.mediafileRepo.getViewModelList());
this.itemObserver = new BehaviorSubject(this.itemRepo.getViewModelList());
this.mediafileRepo
.getViewModelListObservable()
.subscribe(mediafiles => this.mediafilesObserver.next(mediafiles));
this.itemRepo.getViewModelListObservable().subscribe(items => this.itemObserver.next(items));
this.mediafilesObserver = this.mediafileRepo.getViewModelListBehaviorSubject();
this.itemObserver = this.itemRepo.getViewModelListBehaviorSubject();
}
/**

View File

@ -1,5 +1,6 @@
import { CreateTopic } from './create-topic';
import { ViewTopic } from './view-topic';
import { Topic } from 'app/shared/models/topics/topic';
/**
* View model for Topic('Agenda item') creation.
@ -108,6 +109,10 @@ export class ViewCreateTopic extends ViewTopic {
super(topic);
}
public getModel(): Topic {
return super.getModel();
}
public getVerboseName = () => {
throw new Error('This should not be used');
};

View File

@ -132,6 +132,10 @@ export class ViewItem extends BaseViewModel {
this._contentObject = contentObject;
}
public getModel(): Item {
return this.item;
}
public updateDependencies(update: BaseViewModel): boolean {
if (
update &&

View File

@ -1,6 +1,7 @@
import { BaseViewModel } from 'app/site/base/base-view-model';
import { Speaker, SpeakerState } from 'app/shared/models/agenda/speaker';
import { ViewUser } from 'app/site/users/models/view-user';
import { User } from 'app/shared/models/users/user';
/**
* Provides "safe" access to a speaker with all it's components
@ -70,6 +71,10 @@ export class ViewSpeaker extends BaseViewModel {
return this.name;
};
public getModel(): User {
return this.user.user;
}
/**
* Speaker is not a base model,
* @param update the incoming update

View File

@ -71,6 +71,10 @@ export class ViewTopic extends BaseAgendaViewModel {
}
};
public getModel(): Topic {
return this.topic;
}
public getAgendaItem(): ViewItem {
return this.agendaItem;
}

View File

@ -75,6 +75,10 @@ export class ViewAssignment extends BaseAgendaViewModel {
return this.title;
};
public getModel(): Assignment {
return this.assignment;
}
public formatForSearch(): SearchRepresentation {
return [this.title];
}

View File

@ -1,6 +1,7 @@
import { Displayable } from './displayable';
import { Identifiable } from '../../shared/models/base/identifiable';
import { Collection } from 'app/shared/models/base/collection';
import { BaseModel } from 'app/shared/models/base/base-model';
export interface ViewModelConstructor<T extends BaseViewModel> {
COLLECTIONSTRING: string;
@ -56,6 +57,9 @@ export abstract class BaseViewModel implements Displayable, Identifiable, Collec
return this.getTitle();
};
/** return the main model of a view model */
public abstract getModel(): BaseModel;
public abstract updateDependencies(update: BaseViewModel): void;
public toString(): string {

View File

@ -34,6 +34,18 @@ export abstract class BaseViewComponent extends BaseComponent implements OnDestr
this.subscriptions = [];
}
/**
* automatically dismisses the error snack bar and clears subscriptions
* if the component is destroyed.
*/
public ngOnDestroy(): void {
if (this.messageSnackBar) {
this.messageSnackBar.dismiss();
}
this.cleanSubjects();
}
/**
* Opens the snack bar with the given message.
* This snack bar will only dismiss if the user clicks the 'OK'-button.
@ -65,24 +77,23 @@ export abstract class BaseViewComponent extends BaseComponent implements OnDestr
}
/**
* To catch swipe gestures.
* Should be overwritten by children which need swipe gestures
* Manually clears all stored subscriptions.
* Necessary for manual routing control, since the Angular
* life cycle does not accept that navigation to the same URL
* executes the life cycle again
*/
protected swipe(e: TouchEvent, when: string): void {}
/**
* automatically dismisses the error snack bar and clears subscriptions
* if the component is destroyed.
*/
public ngOnDestroy(): void {
if (this.messageSnackBar) {
this.messageSnackBar.dismiss();
}
protected cleanSubjects(): void {
if (this.subscriptions.length > 0) {
for (const sub of this.subscriptions) {
sub.unsubscribe();
}
this.subscriptions = [];
}
}
/**
* To catch swipe gestures.
* Should be overwritten by children which need swipe gestures
*/
protected swipe(e: TouchEvent, when: string): void {}
}

View File

@ -104,7 +104,7 @@ export abstract class ListViewBaseComponent<V extends BaseViewModel, M extends B
}
/**
* Standard sorting function. Siffucient for most list views but can be overwritten
* Standard sorting function. Sufficient for most list views but can be overwritten
*/
protected onSort(): void {
this.subscriptions.push(

View File

@ -4,11 +4,11 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; // showcase
import { BaseComponent } from 'app/base.component';
import { ConfigService } from 'app/core/ui-services/config.service';
// for testing the DS and BaseModel
import { Config } from 'app/shared/models/core/config';
import { DataStoreService } from 'app/core/core-services/data-store.service';
/**
* The start component. Greeting page for OpenSlides
*/
@Component({
selector: 'os-start',
templateUrl: './start.component.html'
@ -22,8 +22,9 @@ export class StartComponent extends BaseComponent implements OnInit {
*
* @param titleService the title serve
* @param translate to translation module
* @param configService read out config values
*/
public constructor(titleService: Title, protected translate: TranslateService, private DS: DataStoreService) {
public constructor(titleService: Title, translate: TranslateService, private configService: ConfigService) {
super(titleService, translate);
}
@ -31,51 +32,18 @@ export class StartComponent extends BaseComponent implements OnInit {
* Init the component.
*
* Sets the welcomeTitle and welcomeText.
* Tries to read them from the DataStore (which will fail initially)
* And observes DataStore for changes
* Set title and observe DataStore for changes.
*/
public ngOnInit(): void {
// required dummy translation, cause translations for config values were never set
// tslint:disable-next-line
const welcomeTitleTranslateDummy = this.translate.instant('Welcome to OpenSlides');
super.setTitle('Home');
// set welcome title and text
const welcomeTitleConfig = this.DS.filter<Config>(
Config,
config => config.key === 'general_event_welcome_title'
)[0] as Config;
if (welcomeTitleConfig) {
this.welcomeTitle = welcomeTitleConfig.value as string;
}
// set the welcome title
this.configService
.get<string>('general_event_welcome_title')
.subscribe(welcomeTitle => (this.welcomeTitle = welcomeTitle));
const welcomeTextConfig = this.DS.filter<Config>(
Config,
config => config.key === 'general_event_welcome_text'
)[0] as Config;
if (welcomeTextConfig) {
this.welcomeText = welcomeTextConfig.value as string;
}
// observe title and text in DS
this.DS.changeObservable.subscribe(newModel => {
if (newModel instanceof Config) {
if (newModel.key === 'general_event_welcome_title') {
this.welcomeTitle = newModel.value as string;
} else if (newModel.key === 'general_event_welcome_text') {
this.welcomeText = newModel.value as string;
}
}
});
}
/**
* test translations in component
*/
public TranslateTest(): void {
console.log('lets translate the word "motion" in the current in the current lang');
console.log('Motions in ' + this.translate.currentLang + ' is ' + this.translate.instant('Motions'));
// set the welcome text
this.configService
.get<string>('general_event_welcome_text')
.subscribe(welcomeText => (this.welcomeText = welcomeText as string));
}
}

View File

@ -32,5 +32,9 @@ export class ViewChatMessage extends BaseViewModel {
return 'Chatmessage';
};
public getModel(): ChatMessage {
return this.chatmessage;
}
public updateDependencies(message: BaseViewModel): void {}
}

View File

@ -111,6 +111,10 @@ export class ViewConfig extends BaseViewModel {
public updateDependencies(update: BaseViewModel): void {}
public getModel(): Config {
return this.config;
}
/**
* Returns the time this config field needs to debounce before sending a request to the server.
* A little debounce time for all inputs is given here and is usefull, if inputs sends multiple onChange-events,

View File

@ -113,6 +113,10 @@ export class ViewHistory extends BaseViewModel {
return this.element_id;
};
public getModel(): History {
return this.history;
}
/**
* Updates the history object with new values
*

View File

@ -80,6 +80,10 @@ export class ViewMediafile extends BaseProjectableViewModel implements Searchabl
return this.title;
};
public getModel(): Mediafile {
return this.mediafile;
}
public formatForSearch(): SearchRepresentation {
const searchValues = [this.title];
if (this.uploader) {

View File

@ -65,6 +65,10 @@ export class ViewCategory extends BaseViewModel implements Searchable {
return '/motions/category';
}
public getModel(): Category {
return this.category;
}
/**
* Updates the local objects if required
* @param update

View File

@ -39,6 +39,10 @@ export class ViewMotionChangeRecommendation extends BaseViewModel implements Vie
public updateDependencies(update: BaseViewModel): void {}
public getModel(): MotionChangeRecommendation {
return this.changeRecommendation;
}
public updateChangeReco(type: number, text: string, internal: boolean): void {
// @TODO HTML sanitazion
this._changeRecommendation.type = type;

View File

@ -81,6 +81,10 @@ export class ViewMotionBlock extends BaseAgendaViewModel implements Searchable {
return this.title;
};
public getModel(): MotionBlock {
return this.motionBlock;
}
public getSlide(): ProjectorElementBuildDeskriptor {
return {
getBasicProjectorElement: options => ({

View File

@ -65,6 +65,10 @@ export class ViewMotionCommentSection extends BaseViewModel {
return this.name;
};
public getModel(): MotionCommentSection {
return this.section;
}
/**
* Updates the local objects if required
* @param section

View File

@ -396,6 +396,10 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
return this.item;
}
public getModel(): Motion {
return this.motion;
}
/**
* Formats the category for search
*

View File

@ -49,6 +49,10 @@ export class ViewStatuteParagraph extends BaseViewModel implements Searchable {
return this.title;
};
public getModel(): StatuteParagraph {
return this.statuteParagraph;
}
public formatForSearch(): SearchRepresentation {
return [this.title];
}

View File

@ -61,6 +61,10 @@ export class ViewWorkflow extends BaseViewModel {
this.workflow.sortStates();
}
public getModel(): Workflow {
return this.workflow;
}
/**
* Updates the local objects if required
*

View File

@ -105,9 +105,9 @@ export class MotionBlockListComponent extends ListViewBaseComponent<ViewMotionBl
super.setTitle('Motion Blocks');
this.initTable();
this.items = new BehaviorSubject(this.itemRepo.getViewModelList());
this.itemRepo.getViewModelListObservable().subscribe(items => this.items.next(items));
this.items = this.itemRepo.getViewModelListBehaviorSubject();
// TODO: Should fall under generic sorting in PR 4411
this.repo.getViewModelListObservable().subscribe(newMotionblocks => {
newMotionblocks.sort((a, b) => (a > b ? 1 : -1));
this.dataSource.data = newMotionblocks;

View File

@ -73,6 +73,15 @@ export class MotionCommentSectionListComponent extends BaseViewComponent impleme
this.updateForm = this.formBuilder.group(form);
}
/**
* Init function.
*/
public ngOnInit(): void {
super.setTitle('Comment fields');
this.groups = this.groupRepo.getViewModelListBehaviorSubject();
this.repo.getViewModelListObservable().subscribe(newViewSections => (this.commentSections = newViewSections));
}
/**
* Event on Key Down in update or create form.
*
@ -96,16 +105,6 @@ export class MotionCommentSectionListComponent extends BaseViewComponent impleme
}
}
/**
* Init function.
*/
public ngOnInit(): void {
super.setTitle('Comment fields');
this.groups = new BehaviorSubject(this.groupRepo.getViewModelList());
this.groupRepo.getViewModelListObservable().subscribe(groups => this.groups.next(groups));
this.repo.getViewModelListObservable().subscribe(newViewSections => (this.commentSections = newViewSections));
}
/**
* Opens the create form.
*/

View File

@ -97,8 +97,7 @@ export class ManageSubmittersComponent extends BaseViewComponent {
this.addSubmitterForm.reset();
// get all users for the submitter add form
this.users = new BehaviorSubject<ViewUser[]>(this.userRepository.getViewModelList());
this.userRepository.getViewModelListObservable().subscribe(users => this.users.next(users));
this.users = this.userRepository.getViewModelListBehaviorSubject();
}
/**

View File

@ -494,7 +494,9 @@
mat-icon-button
[matMenuTriggerFor]="changeRecoMenu"
matTooltip="{{ 'Change recommendations' | translate }}"
*ngIf="motion && !motion.isParagraphBasedAmendment() && allChangingObjects.length > 0"
*ngIf="
motion && !motion.isParagraphBasedAmendment() && allChangingObjects && allChangingObjects.length > 0
"
>
<mat-icon>rate_review</mat-icon>
</button>
@ -503,7 +505,7 @@
type="button"
mat-icon-button
matTooltip="{{ 'Create final print template' | translate }}"
*osPerms="'motions.can_manage';and:isRecoMode(ChangeRecoMode.Final)"
*osPerms="'motions.can_manage'; and: isRecoMode(ChangeRecoMode.Final)"
(click)="createModifiedFinalVersion()"
>
<mat-icon>description</mat-icon>
@ -886,7 +888,7 @@
<button
mat-menu-item
translate
*osPerms="'motions.can_manage';and:isRecoMode(ChangeRecoMode.Final)"
*osPerms="'motions.can_manage'; and: isRecoMode(ChangeRecoMode.Final)"
(click)="setChangeRecoMode(ChangeRecoMode.ModifiedFinal)"
[ngClass]="{ selected: motion?.crMode === ChangeRecoMode.ModifiedFinal }"
>

View File

@ -1,4 +1,4 @@
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
import { Component, OnInit, OnDestroy, ElementRef, HostListener, TemplateRef } from '@angular/core';
import { DomSanitizer, SafeHtml, Title } from '@angular/platform-browser';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
@ -12,15 +12,13 @@ import { CategoryRepositoryService } from 'app/core/repositories/motions/categor
import { ChangeRecommendationRepositoryService } from 'app/core/repositories/motions/change-recommendation-repository.service';
import { CreateMotion } from 'app/site/motions/models/create-motion';
import { ConfigService } from 'app/core/ui-services/config.service';
import { DataStoreService } from 'app/core/core-services/data-store.service';
import { DiffLinesInParagraph, LineRange } from 'app/core/ui-services/diff.service';
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
import { itemVisibilityChoices, Item } from 'app/shared/models/agenda/item';
import { itemVisibilityChoices } from 'app/shared/models/agenda/item';
import { LinenumberingService } from 'app/core/ui-services/linenumbering.service';
import { LocalPermissionsService } from 'app/site/motions/services/local-permissions.service';
import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
import { Motion } from 'app/shared/models/motions/motion';
import { MotionBlock } from 'app/shared/models/motions/motion-block';
import {
MotionChangeRecommendationComponentData,
MotionChangeRecommendationComponent
@ -32,7 +30,6 @@ import { OperatorService } from 'app/core/core-services/operator.service';
import { PersonalNoteService } from 'app/core/ui-services/personal-note.service';
import { PromptService } from 'app/core/ui-services/prompt.service';
import { StatuteParagraphRepositoryService } from 'app/core/repositories/motions/statute-paragraph-repository.service';
import { Tag } from 'app/shared/models/core/tag';
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
import { ViewMotionBlock } from 'app/site/motions/models/view-motion-block';
import { ViewWorkflow } from 'app/site/motions/models/view-workflow';
@ -42,7 +39,6 @@ import { ViewCreateMotion } from 'app/site/motions/models/view-create-motion';
import { ViewItem } from 'app/site/agenda/models/view-item';
import { ViewportService } from 'app/core/ui-services/viewport.service';
import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { ViewMotionChangeRecommendation } from 'app/site/motions/models/view-change-recommendation';
import {
ViewMotionNotificationEditMotion,
@ -52,7 +48,10 @@ import { ViewMotion, ChangeRecoMode, LineNumberingMode } from 'app/site/motions/
import { ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph';
import { ViewTag } from 'app/site/tags/models/view-tag';
import { ViewUnifiedChange } from 'app/shared/models/motions/view-unified-change';
import { Workflow } from 'app/shared/models/motions/workflow';
import { TagRepositoryService } from 'app/core/repositories/tags/tag-repository.service';
import { MediafileRepositoryService } from 'app/core/repositories/mediafiles/mediafile-repository.service';
import { WorkflowRepositoryService } from 'app/core/repositories/motions/workflow-repository.service';
import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service';
/**
* Component for the motion detail view
@ -344,6 +343,13 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
*/
public backTarget = '../..';
/**
* Hold the subscription to the navigation.
* This cannot go into the subscription-list, since it should
* only get destroyed using ngOnDestroy routine and not on route changes.
*/
private navigationSubscription: Subscription;
/**
* Constructs the detail view.
*
@ -391,45 +397,44 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
private agendaRepo: ItemRepositoryService,
private changeRecoRepo: ChangeRecommendationRepositoryService,
private statuteRepo: StatuteParagraphRepositoryService,
private DS: DataStoreService,
private configService: ConfigService,
private sanitizer: DomSanitizer,
private promptService: PromptService,
private pdfExport: MotionPdfExportService,
private personalNoteService: PersonalNoteService,
private linenumberingService: LinenumberingService,
private viewModelStore: ViewModelStoreService,
private categoryRepo: CategoryRepositoryService,
private userRepo: UserRepositoryService,
private notifyService: NotifyService
private notifyService: NotifyService,
private tagRepo: TagRepositoryService,
private mediaFilerepo: MediafileRepositoryService,
private workflowRepo: WorkflowRepositoryService,
private blockRepo: MotionBlockRepositoryService,
private itemRepo: ItemRepositoryService
) {
super(title, translate, matSnackBar);
}
this.workflowObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewWorkflow));
this.blockObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewMotionBlock));
this.mediafilesObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewMediafile));
this.agendaItemObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewItem));
this.tagObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewTag));
this.motionObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewMotion));
/**
* Init.
* Sets all required subjects and fills in the required information
*/
public ngOnInit(): void {
// get required information from the repositories
this.tagObserver = this.tagRepo.getViewModelListBehaviorSubject();
this.mediafilesObserver = this.mediaFilerepo.getViewModelListBehaviorSubject();
this.workflowObserver = this.workflowRepo.getViewModelListBehaviorSubject();
this.blockObserver = this.blockRepo.getViewModelListBehaviorSubject();
this.agendaItemObserver = this.itemRepo.getViewModelListBehaviorSubject();
this.motionObserver = this.repo.getViewModelListBehaviorSubject();
this.submitterObserver = this.userRepo.getViewModelListBehaviorSubject();
this.supporterObserver = this.userRepo.getViewModelListBehaviorSubject();
this.categoryObserver = this.categoryRepo.getViewModelListBehaviorSubject();
// Make sure the subjects are updated, when a new Model for the type arrives
// TODO get rid of DS here
this.DS.changeObservable.subscribe(newModel => {
if (newModel instanceof Workflow) {
this.workflowObserver.next(this.viewModelStore.getAll(ViewWorkflow));
} else if (newModel instanceof MotionBlock) {
this.blockObserver.next(this.viewModelStore.getAll(ViewMotionBlock));
} else if (newModel instanceof Mediafile) {
this.mediafilesObserver.next(this.viewModelStore.getAll(ViewMediafile));
} else if (newModel instanceof Item) {
this.agendaItemObserver.next(this.viewModelStore.getAll(ViewItem));
} else if (newModel instanceof Tag) {
this.tagObserver.next(this.viewModelStore.getAll(ViewTag));
} else if (newModel instanceof Motion) {
this.motionObserver.next(this.viewModelStore.getAll(ViewMotion));
this.setSurroundingMotions();
}
});
this.createForm();
this.observeRoute();
this.getMotionByUrl();
this.setSurroundingMotions();
// load config variables
this.configService
@ -452,36 +457,17 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
this.configService
.get<ChangeRecoMode>('motions_recommendation_text_mode')
.subscribe(mode => (this.crMode = mode));
}
/**
* Init.
* Sets the surrounding motions to navigate back and forth
*/
public ngOnInit(): void {
this.createForm();
this.getMotionByUrl();
this.setSurroundingMotions();
// TODO: Changed to un-sort, since it's a really heavy operation
this.userRepo.getViewModelListObservable().subscribe(unsortedUsers => {
this.submitterObserver.next(unsortedUsers);
this.supporterObserver.next(unsortedUsers);
});
this.categoryRepo.getViewModelListObservable().subscribe(unsortedCategories => {
this.categoryObserver.next(unsortedCategories);
});
// Initial Filling of the Subjects
this.submitterObserver = new BehaviorSubject(this.userRepo.getViewModelList());
this.supporterObserver = new BehaviorSubject(this.userRepo.getViewModelList());
this.categoryObserver = new BehaviorSubject(
this.categoryRepo.sortViewCategoriesByConfig(this.viewModelStore.getAll(ViewCategory))
);
this.statuteRepo.getViewModelListObservable().subscribe(newViewStatuteParagraphs => {
this.statuteParagraphs = newViewStatuteParagraphs;
// disable the selector for attachments if there are none
this.mediafilesObserver.subscribe(() => {
if (this.contentForm) {
const attachmentsCtrl = this.contentForm.get('attachments_id');
if (this.mediafilesObserver.value.length === 0) {
attachmentsCtrl.disable();
} else {
attachmentsCtrl.enable();
}
}
});
// Set the default visibility using observers
@ -491,15 +477,15 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
}
});
// disable the selector for attachments if there are none
this.mediafilesObserver.subscribe(files => {
if (this.createForm) {
const attachmentsCtrl = this.contentForm.get('attachments_id');
if (this.mediafilesObserver.value.length === 0) {
attachmentsCtrl.disable();
} else {
attachmentsCtrl.enable();
}
// Update statute paragraphs
this.statuteRepo.getViewModelListObservable().subscribe(newViewStatuteParagraphs => {
this.statuteParagraphs = newViewStatuteParagraphs;
});
// Observe motion changes to trigger surrounding motions
this.motionObserver.subscribe(motionChanges => {
if (motionChanges) {
this.setSurroundingMotions();
}
});
}
@ -510,6 +496,22 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
*/
public ngOnDestroy(): void {
this.unsubscribeEditNotifications(TypeOfNotificationViewMotion.TYPE_CLOSING_EDITING_MOTION);
if (this.navigationSubscription) {
this.navigationSubscription.unsubscribe();
}
}
/**
* Observes the route for events. Calls to clean all subs if the route changes.
* Calls the motion details from the new route
*/
public observeRoute(): void {
this.navigationSubscription = this.router.events.subscribe(navEvent => {
if (navEvent instanceof NavigationEnd) {
this.cleanSubjects();
this.getMotionByUrl();
}
});
}
/**
@ -555,65 +557,68 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
* determine the motion to display using the URL
*/
public getMotionByUrl(): void {
this.route.params.subscribe(params => {
if (Object.keys(params).length > 0) {
// load existing motion
const motionId: number = +params.id;
this.repo.getViewModelObservable(motionId).subscribe(newViewMotion => {
if (newViewMotion) {
this.motion = newViewMotion;
const params = this.route.snapshot.params;
if (params && params.id) {
// existing motion
const motionId: number = +params.id;
// the following subscriptions need to be cleared when the route changes
this.subscriptions.push(
this.repo.getViewModelObservable(motionId).subscribe(motion => {
if (motion) {
this.motion = motion;
this.newStateExtension = this.motion.stateExtension;
this.patchForm(this.motion);
}
});
}),
this.repo.amendmentsTo(motionId).subscribe(
(amendments: ViewMotion[]): void => {
this.amendments = amendments;
this.recalcUnifiedChanges();
}
);
),
this.changeRecoRepo
.getChangeRecosOfMotionObservable(motionId)
.subscribe((recos: ViewMotionChangeRecommendation[]) => {
this.changeRecommendations = recos;
this.recalcUnifiedChanges();
})
);
} else {
// new motion
this.newMotion = true;
this.editMotion = true;
// prevent 'undefined' to appear in the ui
const defaultMotion: Partial<CreateMotion> = {
title: '',
origin: '',
identifier: ''
};
if (this.route.snapshot.queryParams.parent) {
this.amendmentEdit = true;
const parentMotion = this.repo.getViewModel(this.route.snapshot.queryParams.parent);
const defaultTitle = `${this.translate.instant('Amendment to')} ${parentMotion.identifierOrTitle}`;
const mode = this.configService.instant<string>('motions_amendments_text_mode');
if (mode === 'freestyle' || mode === 'fulltext') {
defaultMotion.title = defaultTitle;
defaultMotion.parent_id = parentMotion.id;
defaultMotion.category_id = parentMotion.category_id;
defaultMotion.motion_block_id = parentMotion.motion_block_id;
this.contentForm.patchValue({
title: defaultTitle,
category_id: parentMotion.category_id,
motion_block_id: parentMotion.motion_block_id,
parent_id: parentMotion.id
});
} else {
// creates a new motion
this.newMotion = true;
this.editMotion = true;
// prevent 'undefined' to appear in the ui
const defaultMotion: Partial<CreateMotion> = {
title: '',
origin: '',
identifier: ''
};
if (this.route.snapshot.queryParams.parent) {
this.amendmentEdit = true;
const parentMotion = this.repo.getViewModel(this.route.snapshot.queryParams.parent);
const defaultTitle = `${this.translate.instant('Amendment to')} ${parentMotion.identifierOrTitle}`;
const mode = this.configService.instant<string>('motions_amendments_text_mode');
if (mode === 'freestyle' || mode === 'fulltext') {
defaultMotion.title = defaultTitle;
defaultMotion.parent_id = parentMotion.id;
defaultMotion.category_id = parentMotion.category_id;
defaultMotion.motion_block_id = parentMotion.motion_block_id;
this.contentForm.patchValue({
title: defaultTitle,
category_id: parentMotion.category_id,
motion_block_id: parentMotion.motion_block_id,
parent_id: parentMotion.id
});
}
if (mode === 'fulltext') {
defaultMotion.text = parentMotion.text;
this.contentForm.patchValue({ text: parentMotion.text });
}
}
this.motion = new ViewCreateMotion(new CreateMotion(defaultMotion));
this.motionCopy = new ViewCreateMotion(new CreateMotion(defaultMotion));
if (mode === 'fulltext') {
defaultMotion.text = parentMotion.text;
this.contentForm.patchValue({ text: parentMotion.text });
}
}
});
this.motion = new ViewCreateMotion(new CreateMotion(defaultMotion));
this.motionCopy = new ViewCreateMotion(new CreateMotion(defaultMotion));
}
}
/**
@ -1095,7 +1100,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
*/
public navigateToMotion(motion: ViewMotion): void {
if (motion) {
this.router.navigate(['../contacts'], { relativeTo: this.route.parent });
this.router.navigate([`../${motion.id}`], { relativeTo: this.route.parent });
// update the current motion
this.motion = motion;
this.setSurroundingMotions();
@ -1243,15 +1248,17 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
* Observes the repository for changes in the motion recommender
*/
public setupRecommender(): void {
const configKey = this.motion.isStatuteAmendment()
? 'motions_statute_recommendations_by'
: 'motions_recommendations_by';
if (this.recommenderSubscription) {
this.recommenderSubscription.unsubscribe();
if (this.motion) {
const configKey = this.motion.isStatuteAmendment()
? 'motions_statute_recommendations_by'
: 'motions_recommendations_by';
if (this.recommenderSubscription) {
this.recommenderSubscription.unsubscribe();
}
this.recommenderSubscription = this.configService.get<string>(configKey).subscribe(recommender => {
this.recommender = recommender;
});
}
this.recommenderSubscription = this.configService.get<string>(configKey).subscribe(recommender => {
this.recommender = recommender;
});
}
/**

View File

@ -5,7 +5,7 @@ import { MotionDetailComponent } from './components/motion-detail/motion-detail.
import { AmendmentCreateWizardComponent } from './components/amendment-create-wizard/amendment-create-wizard.component';
const routes: Routes = [
{ path: '', component: MotionDetailComponent, pathMatch: 'full' },
{ path: '', component: MotionDetailComponent, pathMatch: 'full', runGuardsAndResolvers: 'paramsChange' },
{ path: 'create-amendment', component: AmendmentCreateWizardComponent }
];

View File

@ -41,7 +41,8 @@ const routes: Routes = [
},
{
path: ':id',
loadChildren: './modules/motion-detail/motion-detail.module#MotionDetailModule'
loadChildren: './modules/motion-detail/motion-detail.module#MotionDetailModule',
runGuardsAndResolvers: 'paramsChange'
}
];

View File

@ -54,6 +54,10 @@ export class ViewCountdown extends BaseProjectableViewModel {
return this.description ? `${this.title} (${this.description})` : this.title;
};
public getModel(): Countdown {
return this.countdown;
}
public updateDependencies(update: BaseViewModel): void {}
public getSlide(): ProjectorElementBuildDeskriptor {

View File

@ -35,6 +35,10 @@ export class ViewProjectorMessage extends BaseProjectableViewModel {
return 'Message';
};
public getModel(): ProjectorMessage {
return this.projectormessage;
}
public updateDependencies(update: BaseViewModel): void {}
public getSlide(): ProjectorElementBuildDeskriptor {

View File

@ -106,6 +106,10 @@ export class ViewProjector extends BaseViewModel {
return this.name;
};
public getModel(): Projector {
return this.projector;
}
public updateDependencies(update: BaseViewModel): void {
if (update instanceof ViewProjector && this.reference_projector_id === update.id) {
this._referenceProjector = update;

View File

@ -41,6 +41,10 @@ export class ViewTag extends BaseViewModel implements Searchable {
return this.name;
};
public getModel(): Tag {
return this.tag;
}
public formatForSearch(): SearchRepresentation {
return [this.name];
}

View File

@ -107,7 +107,7 @@ export class GroupListComponent extends BaseViewComponent implements OnInit {
if (!this.groupForm.value || !this.groupForm.valid) {
return;
}
this.repo.create(this.groupForm.value).then(() => {
this.repo.create(this.groupForm.value as Group).then(() => {
this.groupForm.reset();
this.cancelEditing();
}, this.raiseError);

View File

@ -41,6 +41,10 @@ export class ViewCsvCreateUser extends ViewUser {
super(user);
}
public getModel(): User {
return super.getModel();
}
/**
* takes a list of solved group maps to update. Returns the amount of
* entries that remain unmatched

View File

@ -76,6 +76,10 @@ export class ViewGroup extends BaseViewModel {
return this.name;
};
public getModel(): Group {
return this.group;
}
public updateDependencies(update: BaseViewModel): void {
console.log('ViewGroups wants to update Values with : ', update);
}

View File

@ -36,5 +36,9 @@ export class ViewPersonalNote extends BaseViewModel {
return this.personalNote ? this.personalNote.toString() : null;
};
public getModel(): PersonalNote {
return this.personalNote;
}
public updateDependencies(update: BaseViewModel): void {}
}

View File

@ -179,6 +179,10 @@ export class ViewUser extends BaseProjectableViewModel implements Searchable {
this._groups = groups;
}
public getModel(): User {
return this.user;
}
/**
* Formats the category for search
*