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({ @NgModule({
imports: [RouterModule.forRoot(routes)], imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],
exports: [RouterModule] exports: [RouterModule]
}) })
export class AppRoutingModule {} export class AppRoutingModule {}

View File

@ -28,10 +28,6 @@ export class AuthGuard implements CanActivate, CanActivateChild {
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const basePerm: string | string[] = route.data.basePerm; 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) { if (!basePerm) {
return true; return true;
} else if (basePerm instanceof Array) { } else if (basePerm instanceof Array) {

View File

@ -32,6 +32,7 @@ export class DataSendService {
/** /**
* Function to fully update a model on the server. * Function to fully update a model on the server.
* TODO: Deprecated (?)
* *
* @param model The model that is meant to be changed. * @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 * @param userId the id or null for guest
*/ */
public async afterLoginBootup(userId: number | null): Promise<void> { public async afterLoginBootup(userId: number | null): Promise<void> {
console.log('user id', userId);
// Check, which user was logged in last time // Check, which user was logged in last time
const lastUserId = await this.storageService.get<number>('lastUserLoggedIn'); const lastUserId = await this.storageService.get<number>('lastUserLoggedIn');
// if the user changed, reset the cache and save the new user. // 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 { tap, map } from 'rxjs/operators';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAgendaContentObjectRepository } from '../base-agenda-content-object-repository';
import { BaseRepository } from '../base-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 { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ConfigService } from 'app/core/ui-services/config.service'; import { ConfigService } from 'app/core/ui-services/config.service';
import { DataSendService } from 'app/core/core-services/data-send.service'; import { DataSendService } from 'app/core/core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service'; import { DataStoreService } from '../../core-services/data-store.service';
import { HttpService } from 'app/core/core-services/http.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 { Item } from 'app/shared/models/agenda/item';
import { OSTreeSortEvent } from 'app/shared/components/sorting-tree/sorting-tree.component'; 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 { 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 * Repository service for users
@ -42,13 +41,13 @@ export class ItemRepositoryService extends BaseRepository<ViewItem, Item> {
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
protected dataSend: DataSendService,
private httpService: HttpService, private httpService: HttpService,
private config: ConfigService, private config: ConfigService,
private dataSend: DataSendService,
private treeService: TreeService, private treeService: TreeService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, Item); super(DS, dataSend, mapperService, viewModelStoreService, Item);
} }
public getVerboseName = (plural: boolean = false) => { 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 * Trigger the automatic numbering sequence on the server
*/ */
@ -150,15 +137,6 @@ export class ItemRepositoryService extends BaseRepository<ViewItem, Item> {
await this.httpService.delete(restUrl); 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 * Get agenda visibility from the config
* *

View File

@ -2,19 +2,17 @@ import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Topic } from 'app/shared/models/topics/topic'; import { BaseAgendaContentObjectRepository } from '../base-agenda-content-object-repository';
import { Mediafile } from 'app/shared/models/mediafiles/mediafile'; import { CollectionStringMapperService } from 'app/core/core-services/collectionStringMapper.service';
import { Item } from 'app/shared/models/agenda/item';
import { DataStoreService } from 'app/core/core-services/data-store.service'; import { DataStoreService } from 'app/core/core-services/data-store.service';
import { DataSendService } from 'app/core/core-services/data-send.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 { 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 { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile'; import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
import { ViewItem } from 'app/site/agenda/models/view-item'; import { ViewItem } from 'app/site/agenda/models/view-item';
import { BaseAgendaContentObjectRepository } from '../base-agenda-content-object-repository';
/** /**
* Repository for topics * Repository for topics
@ -34,10 +32,10 @@ export class TopicRepositoryService extends BaseAgendaContentObjectRepository<Vi
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private translate: TranslateService 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>) => { public getAgendaTitle = (topic: Partial<Topic> | Partial<ViewTopic>) => {
@ -69,39 +67,6 @@ export class TopicRepositoryService extends BaseAgendaContentObjectRepository<Vi
return viewTopic; 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 * 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 { TranslateService } from '@ngx-translate/core';
import { ViewAssignment } from 'app/site/assignments/models/view-assignment';
import { Assignment } from 'app/shared/models/assignments/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 { 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. * Repository Service for Assignments.
@ -33,11 +33,12 @@ export class AssignmentRepositoryService extends BaseAgendaContentObjectReposito
*/ */
public constructor( public constructor(
DS: DataStoreService, DS: DataStoreService,
dataSend: DataSendService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private translate: TranslateService 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>) => { public getAgendaTitle = (assignment: Partial<Assignment> | Partial<ViewAssignment>) => {
@ -63,16 +64,4 @@ export class AssignmentRepositoryService extends BaseAgendaContentObjectReposito
viewAssignment.getAgendaTitleWithType = () => this.getAgendaTitleWithType(viewAssignment); viewAssignment.getAgendaTitleWithType = () => this.getAgendaTitleWithType(viewAssignment);
return 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 { BaseViewModel } from '../../site/base/base-view-model';
import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model'; import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model';
import { CollectionStringMapperService } from '../core-services/collectionStringMapper.service'; import { CollectionStringMapperService } from '../core-services/collectionStringMapper.service';
import { DataSendService } from '../core-services/data-send.service';
import { DataStoreService } from '../core-services/data-store.service'; import { DataStoreService } from '../core-services/data-store.service';
import { ViewModelStoreService } from '../core-services/view-model-store.service'; import { ViewModelStoreService } from '../core-services/view-model-store.service';
import { BaseRepository } from './base-repository'; import { BaseRepository } from './base-repository';
@ -21,11 +22,12 @@ export abstract class BaseAgendaContentObjectRepository<
*/ */
public constructor( public constructor(
DS: DataStoreService, DS: DataStoreService,
dataSend: DataSendService,
collectionStringMapperService: CollectionStringMapperService, collectionStringMapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
baseModelCtor: ModelConstructor<M>, baseModelCtor: ModelConstructor<M>,
depsModelCtors?: ModelConstructor<BaseModel>[] 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 { BaseViewModel } from '../../site/base/base-view-model';
import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model'; import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model';
import { CollectionStringMapperService } from '../core-services/collectionStringMapper.service'; import { CollectionStringMapperService } from '../core-services/collectionStringMapper.service';
import { DataSendService } from '../core-services/data-send.service';
import { DataStoreService } from '../core-services/data-store.service'; import { DataStoreService } from '../core-services/data-store.service';
import { Identifiable } from '../../shared/models/base/identifiable'; import { Identifiable } from '../../shared/models/base/identifiable';
import { auditTime } from 'rxjs/operators'; 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 viewModelListSubject: BehaviorSubject<V[]> = new BehaviorSubject<V[]>([]);
protected readonly viewModelListAuditSubject: BehaviorSubject<V[]> = new BehaviorSubject<V[]>([]);
/** /**
* Observable subject for any changes of view models. * Observable subject for any changes of view models.
*/ */
@ -59,12 +62,15 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
*/ */
public constructor( public constructor(
protected DS: DataStoreService, protected DS: DataStoreService,
protected dataSend: DataSendService,
protected collectionStringMapperService: CollectionStringMapperService, protected collectionStringMapperService: CollectionStringMapperService,
protected viewModelStoreService: ViewModelStoreService, protected viewModelStoreService: ViewModelStoreService,
protected baseModelCtor: ModelConstructor<M>, protected baseModelCtor: ModelConstructor<M>,
protected depsModelCtors?: ModelConstructor<BaseModel>[] protected depsModelCtors?: ModelConstructor<BaseModel>[]
) { ) {
this._collectionString = baseModelCtor.COLLECTIONSTRING; this._collectionString = baseModelCtor.COLLECTIONSTRING;
this.getViewModelListObservable().subscribe(x => this.viewModelListAuditSubject.next(x));
} }
public onAfterAppsLoaded(): void { 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 * 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 update the update that should be created
* @param viewModel the view model that the update is based on * @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 * Deletes a given Model
* @param update the update that should be created * Provides a default procedure, but can be overwritten if required
* @param viewModel the view model that the update is based on *
* @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 * Creates a new model.
* @param update the update that should be created * Provides a default procedure, but can be overwritten if required
* @param viewModel the view model that the update is based on *
* TODO: remove the viewModel * @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. * 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)); 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. * This observable fires every time an object is changed in the repository.
*/ */

View File

@ -1,12 +1,12 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { DataStoreService } from '../../core-services/data-store.service'; import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository'; import { BaseRepository } from '../base-repository';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service'; import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ChatMessage } from 'app/shared/models/core/chat-message'; import { ChatMessage } from 'app/shared/models/core/chat-message';
import { ViewChatMessage } from 'app/site/common/models/view-chatmessage'; import { ViewChatMessage } from 'app/site/common/models/view-chatmessage';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { DataSendService } from 'app/core/core-services/data-send.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -14,11 +14,12 @@ import { TranslateService } from '@ngx-translate/core';
export class ChatMessageRepositoryService extends BaseRepository<ViewChatMessage, ChatMessage> { export class ChatMessageRepositoryService extends BaseRepository<ViewChatMessage, ChatMessage> {
public constructor( public constructor(
DS: DataStoreService, DS: DataStoreService,
dataSend: DataSendService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, ChatMessage); super(DS, dataSend, mapperService, viewModelStoreService, ChatMessage);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -30,16 +31,4 @@ export class ChatMessageRepositoryService extends BaseRepository<ViewChatMessage
viewChatMessage.getVerboseName = this.getVerboseName; viewChatMessage.getVerboseName = this.getVerboseName;
return viewChatMessage; 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 { BaseRepository } from 'app/core/repositories/base-repository';
import { Config } from 'app/shared/models/core/config'; 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 { DataStoreService } from 'app/core/core-services/data-store.service';
import { ConstantsService } from 'app/core/ui-services/constants.service'; import { ConstantsService } from 'app/core/ui-services/constants.service';
import { HttpService } from 'app/core/core-services/http.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 { CollectionStringMapperService } from 'app/core/core-services/collectionStringMapper.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { ViewConfig } from 'app/site/config/models/view-config'; import { ViewConfig } from 'app/site/config/models/view-config';
@ -97,13 +97,14 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config>
*/ */
public constructor( public constructor(
DS: DataStoreService, DS: DataStoreService,
dataSend: DataSendService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private constantsService: ConstantsService, private constantsService: ConstantsService,
private http: HttpService, private http: HttpService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, Config); super(DS, dataSend, mapperService, viewModelStoreService, Config);
this.constantsService.get('OpenSlidesConfigVariables').subscribe(constant => { this.constantsService.get('OpenSlidesConfigVariables').subscribe(constant => {
this.createConfigStructure(constant); this.createConfigStructure(constant);
@ -142,6 +143,7 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config>
this.updateConfigListObservable(); this.updateConfigListObservable();
// Could be raise in error if the root injector is not known // Could be raise in error if the root injector is not known
// TODO go over repo
this.DS.changeObservable.subscribe(model => { this.DS.changeObservable.subscribe(model => {
if (model instanceof Config) { if (model instanceof Config) {
this.viewModelStore[model.id] = this.createViewModel(model as 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); 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. * initially create the config structure from the given constant.
* @param 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 { BaseRepository } from 'app/core/repositories/base-repository';
import { History } from 'app/shared/models/core/history'; import { History } from 'app/shared/models/core/history';
import { User } from 'app/shared/models/users/user'; 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 { HttpService } from 'app/core/core-services/http.service';
import { ViewHistory } from 'app/site/history/models/view-history'; import { ViewHistory } from 'app/site/history/models/view-history';
import { TimeTravelService } from 'app/core/core-services/time-travel.service'; import { TimeTravelService } from 'app/core/core-services/time-travel.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { ViewUser } from 'app/site/users/models/view-user'; import { ViewUser } from 'app/site/users/models/view-user';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { DataSendService } from 'app/core/core-services/data-send.service';
/** /**
* Repository for the history. * Repository for the history.
@ -32,13 +32,14 @@ export class HistoryRepositoryService extends BaseRepository<ViewHistory, Histor
*/ */
public constructor( public constructor(
DS: DataStoreService, DS: DataStoreService,
dataSend: DataSendService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private httpService: HttpService, private httpService: HttpService,
private timeTravel: TimeTravelService, private timeTravel: TimeTravelService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, History, [User]); super(DS, dataSend, mapperService, viewModelStoreService, History, [User]);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -58,22 +59,6 @@ export class HistoryRepositoryService extends BaseRepository<ViewHistory, Histor
return viewHistory; 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 * Sends a post-request to delete history objects
*/ */

View File

@ -32,11 +32,11 @@ export class MediafileRepositoryService extends BaseRepository<ViewMediafile, Me
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private httpService: HttpService, private httpService: HttpService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, Mediafile, [User]); super(DS, dataSend, mapperService, viewModelStoreService, Mediafile, [User]);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -56,39 +56,6 @@ export class MediafileRepositoryService extends BaseRepository<ViewMediafile, Me
return viewMediafile; 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. * Uploads a file to the server.
* The HttpHeader should be Application/FormData, the empty header will * 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 { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service'; import { DataStoreService } from '../../core-services/data-store.service';
import { HttpService } from '../../core-services/http.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 { ViewCategory } from 'app/site/motions/models/view-category';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; 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, protected DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private httpService: HttpService, private httpService: HttpService,
private configService: ConfigService, private configService: ConfigService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, Category); super(DS, dataSend, mapperService, viewModelStoreService, Category);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -62,26 +61,6 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
return viewCategory; 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 * Returns the category for the ID
* @param category_id category ID * @param category_id category ID

View File

@ -47,10 +47,14 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private translate: TranslateService 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) => { public getVerboseName = (plural: boolean = false) => {
@ -68,16 +72,6 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<
return viewMotionChangeRecommendation; 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. * Given a change recommendation view object, a entry in the backend is created.
* @param view * @param view
@ -87,35 +81,6 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<
return await this.dataSend.createModel(view.changeRecommendation); 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 * 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 { DataSendService } from 'app/core/core-services/data-send.service';
import { DataStoreService } from 'app/core/core-services/data-store.service'; import { DataStoreService } from 'app/core/core-services/data-store.service';
import { HttpService } from 'app/core/core-services/http.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 { Motion } from 'app/shared/models/motions/motion';
import { MotionBlock } from 'app/shared/models/motions/motion-block'; import { MotionBlock } from 'app/shared/models/motions/motion-block';
import { MotionRepositoryService } from './motion-repository.service'; import { MotionRepositoryService } from './motion-repository.service';
@ -39,12 +38,12 @@ export class MotionBlockRepositoryService extends BaseAgendaContentObjectReposit
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private motionRepo: MotionRepositoryService, private motionRepo: MotionRepositoryService,
private httpService: HttpService, private httpService: HttpService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, MotionBlock, [Item]); super(DS, dataSend, mapperService, viewModelStoreService, MotionBlock, [Item]);
} }
public getAgendaTitle = (motionBlock: Partial<MotionBlock> | Partial<ViewMotionBlock>) => { public getAgendaTitle = (motionBlock: Partial<MotionBlock> | Partial<ViewMotionBlock>) => {
@ -74,38 +73,6 @@ export class MotionBlockRepositoryService extends BaseAgendaContentObjectReposit
return viewMotionBlock; 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 * 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 { ViewMotionCommentSection } from 'app/site/motions/models/view-motion-comment-section';
import { MotionCommentSection } from 'app/shared/models/motions/motion-comment-section'; import { MotionCommentSection } from 'app/shared/models/motions/motion-comment-section';
import { Group } from 'app/shared/models/users/group'; import { Group } from 'app/shared/models/users/group';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service'; import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { HttpService } from 'app/core/core-services/http.service'; import { HttpService } from 'app/core/core-services/http.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
@ -45,11 +44,11 @@ export class MotionCommentSectionRepositoryService extends BaseRepository<
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private http: HttpService, private http: HttpService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, MotionCommentSection, [Group]); super(DS, dataSend, mapperService, viewModelStoreService, MotionCommentSection, [Group]);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -70,42 +69,6 @@ export class MotionCommentSectionRepositoryService extends BaseRepository<
return viewMotionCommentSection; 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 * Saves a comment made at a MotionCommentSection. Does an update, if
* there is a comment text. Deletes the comment, if the text is empty. * 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 { Category } from 'app/shared/models/motions/category';
import { ChangeRecoMode, ViewMotion } from 'app/site/motions/models/view-motion'; import { ChangeRecoMode, ViewMotion } from 'app/site/motions/models/view-motion';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service'; 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 { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service'; import { DataStoreService } from '../../core-services/data-store.service';
import { DiffLinesInParagraph, DiffService, LineRange, ModificationType } from '../../ui-services/diff.service'; import { DiffLinesInParagraph, DiffService, LineRange, ModificationType } from '../../ui-services/diff.service';
import { HttpService } from 'app/core/core-services/http.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 { Item } from 'app/shared/models/agenda/item';
import { LinenumberingService } from '../../ui-services/linenumbering.service'; import { LinenumberingService } from '../../ui-services/linenumbering.service';
import { Mediafile } from 'app/shared/models/mediafiles/mediafile'; import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
@ -75,7 +73,7 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private httpService: HttpService, private httpService: HttpService,
private readonly lineNumbering: LinenumberingService, private readonly lineNumbering: LinenumberingService,
private readonly diff: DiffService, private readonly diff: DiffService,
@ -83,7 +81,7 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
private translate: TranslateService, private translate: TranslateService,
private operator: OperatorService private operator: OperatorService
) { ) {
super(DS, mapperService, viewModelStoreService, Motion, [ super(DS, dataSend, mapperService, viewModelStoreService, Motion, [
Category, Category,
User, User,
Workflow, 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 * 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 { BaseRepository } from '../base-repository';
import { ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph'; import { ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph';
import { StatuteParagraph } from 'app/shared/models/motions/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 { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -34,10 +33,10 @@ export class StatuteParagraphRepositoryService extends BaseRepository<ViewStatut
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, StatuteParagraph); super(DS, dataSend, mapperService, viewModelStoreService, StatuteParagraph);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -49,21 +48,4 @@ export class StatuteParagraphRepositoryService extends BaseRepository<ViewStatut
viewStatuteParagraph.getVerboseName = this.getVerboseName; viewStatuteParagraph.getVerboseName = this.getVerboseName;
return viewStatuteParagraph; 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 { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service'; import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository'; import { BaseRepository } from '../base-repository';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service'; import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { WorkflowState } from 'app/shared/models/motions/workflow-state'; import { WorkflowState } from 'app/shared/models/motions/workflow-state';
import { ViewMotion } from 'app/site/motions/models/view-motion'; import { ViewMotion } from 'app/site/motions/models/view-motion';
@ -45,12 +44,12 @@ export class WorkflowRepositoryService extends BaseRepository<ViewWorkflow, Work
public constructor( public constructor(
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
private httpService: HttpService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private httpService: HttpService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, Workflow); super(DS, dataSend, mapperService, viewModelStoreService, Workflow);
this.viewModelListSubject.pipe(auditTime(1)).subscribe(models => { this.viewModelListSubject.pipe(auditTime(1)).subscribe(models => {
if (models && models.length > 0) { if (models && models.length > 0) {
this.initSorting(models); this.initSorting(models);
@ -87,43 +86,6 @@ export class WorkflowRepositoryService extends BaseRepository<ViewWorkflow, Work
return viewWorkflow; 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 * 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 { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service'; import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository'; import { BaseRepository } from '../base-repository';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service'; import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ViewCountdown } from 'app/site/projector/models/view-countdown'; import { ViewCountdown } from 'app/site/projector/models/view-countdown';
import { Countdown } from 'app/shared/models/core/countdown'; import { Countdown } from 'app/shared/models/core/countdown';
@ -18,11 +17,11 @@ export class CountdownRepositoryService extends BaseRepository<ViewCountdown, Co
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private translate: TranslateService, private translate: TranslateService,
private servertimeService: ServertimeService private servertimeService: ServertimeService
) { ) {
super(DS, mapperService, viewModelStoreService, Countdown); super(DS, dataSend, mapperService, viewModelStoreService, Countdown);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -35,20 +34,6 @@ export class CountdownRepositoryService extends BaseRepository<ViewCountdown, Co
return viewCountdown; 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> { public async start(countdown: ViewCountdown): Promise<void> {
const endTime = this.servertimeService.getServertime() / 1000 + countdown.countdown_time; const endTime = this.servertimeService.getServertime() / 1000 + countdown.countdown_time;
await this.update({ running: true, countdown_time: endTime }, countdown); await this.update({ running: true, countdown_time: endTime }, countdown);

View File

@ -1,7 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { DataStoreService } from '../../core-services/data-store.service'; import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository'; import { BaseRepository } from '../base-repository';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service'; import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ProjectorMessage } from 'app/shared/models/core/projector-message'; import { ProjectorMessage } from 'app/shared/models/core/projector-message';
import { ViewProjectorMessage } from 'app/site/projector/models/view-projector-message'; import { ViewProjectorMessage } from 'app/site/projector/models/view-projector-message';
@ -17,10 +16,10 @@ export class ProjectorMessageRepositoryService extends BaseRepository<ViewProjec
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private translate: TranslateService, protected dataSend: DataSendService,
private dataSend: DataSendService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, ProjectorMessage); super(DS, dataSend, mapperService, viewModelStoreService, ProjectorMessage);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -32,18 +31,4 @@ export class ProjectorMessageRepositoryService extends BaseRepository<ViewProjec
viewProjectorMessage.getVerboseName = this.getVerboseName; viewProjectorMessage.getVerboseName = this.getVerboseName;
return viewProjectorMessage; 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, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private http: HttpService, private http: HttpService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, Projector, [Projector]); super(DS, dataSend, mapperService, viewModelStoreService, Projector, [Projector]);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -66,25 +66,6 @@ export class ProjectorRepositoryService extends BaseRepository<ViewProjector, Pr
return await this.dataSend.createModel(projector); 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. * 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 { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service'; import { DataStoreService } from '../../core-services/data-store.service';
import { BaseRepository } from '../base-repository'; import { BaseRepository } from '../base-repository';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service'; import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -34,13 +33,13 @@ export class TagRepositoryService extends BaseRepository<ViewTag, Tag> {
* @param dataSend sending changed objects * @param dataSend sending changed objects
*/ */
public constructor( public constructor(
protected DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, Tag); super(DS, dataSend, mapperService, viewModelStoreService, Tag);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -52,21 +51,4 @@ export class TagRepositoryService extends BaseRepository<ViewTag, Tag> {
viewTag.getVerboseName = this.getVerboseName; viewTag.getVerboseName = this.getVerboseName;
return viewTag; 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 { DataSendService } from '../../core-services/data-send.service';
import { DataStoreService } from '../../core-services/data-store.service'; import { DataStoreService } from '../../core-services/data-store.service';
import { Group } from 'app/shared/models/users/group'; 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 { ViewGroup } from 'app/site/users/models/view-group';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -52,11 +51,11 @@ export class GroupRepositoryService extends BaseRepository<ViewGroup, Group> {
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private constants: ConstantsService, private constants: ConstantsService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, Group); super(DS, dataSend, mapperService, viewModelStoreService, Group);
this.sortPermsPerApp(); 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 { BaseRepository } from '../base-repository';
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service'; import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
import { PersonalNote } from 'app/shared/models/users/personal-note'; 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 { ViewPersonalNote } from 'app/site/users/models/view-personal-note';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core'; 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( public constructor(
DS: DataStoreService, DS: DataStoreService,
dataSend: DataSendService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private translate: TranslateService private translate: TranslateService
) { ) {
super(DS, mapperService, viewModelStoreService, PersonalNote); super(DS, dataSend, mapperService, viewModelStoreService, PersonalNote);
} }
public getVerboseName = (plural: boolean = false) => { public getVerboseName = (plural: boolean = false) => {
@ -37,16 +38,4 @@ export class PersonalNoteRepositoryService extends BaseRepository<ViewPersonalNo
viewPersonalNote.getVerboseName = this.getVerboseName; viewPersonalNote.getVerboseName = this.getVerboseName;
return viewPersonalNote; 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 { environment } from '../../../../environments/environment';
import { Group } from 'app/shared/models/users/group'; import { Group } from 'app/shared/models/users/group';
import { HttpService } from 'app/core/core-services/http.service'; 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 { NewEntry } from 'app/core/ui-services/base-import.service';
import { User } from 'app/shared/models/users/user'; import { User } from 'app/shared/models/users/user';
import { ViewUser } from 'app/site/users/models/view-user'; import { ViewUser } from 'app/site/users/models/view-user';
@ -43,12 +42,12 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
DS: DataStoreService, DS: DataStoreService,
mapperService: CollectionStringMapperService, mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService, viewModelStoreService: ViewModelStoreService,
private dataSend: DataSendService, protected dataSend: DataSendService,
private translate: TranslateService, private translate: TranslateService,
private httpService: HttpService, private httpService: HttpService,
private configService: ConfigService private configService: ConfigService
) { ) {
super(DS, mapperService, viewModelStoreService, User, [Group]); super(DS, dataSend, mapperService, viewModelStoreService, User, [Group]);
} }
public getVerboseName = (plural: boolean = false) => { 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. * 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 update the forms values
* @param viewUser * @param viewUser
*/ */
public async update(update: Partial<User>, viewUser: ViewUser): Promise<void> { public async update(update: Partial<User>, viewUser: ViewUser): Promise<void> {
const updateUser = new User(); const updateUser = new User();
// copy the ViewUser to avoid manipulation of parameters
updateUser.patchValues(viewUser.user); updateUser.patchValues(viewUser.user);
updateUser.patchValues(update); updateUser.patchValues(update);
@ -89,37 +89,7 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
updateUser.gender = ''; updateUser.gender = '';
} }
return await this.dataSend.updateModel(updateUser); return await this.dataSend.partialUpdateModel(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);
} }
/** /**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -34,6 +34,18 @@ export abstract class BaseViewComponent extends BaseComponent implements OnDestr
this.subscriptions = []; 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. * Opens the snack bar with the given message.
* This snack bar will only dismiss if the user clicks the 'OK'-button. * 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. * Manually clears all stored subscriptions.
* Should be overwritten by children which need swipe gestures * 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 {} protected cleanSubjects(): void {
/**
* automatically dismisses the error snack bar and clears subscriptions
* if the component is destroyed.
*/
public ngOnDestroy(): void {
if (this.messageSnackBar) {
this.messageSnackBar.dismiss();
}
if (this.subscriptions.length > 0) { if (this.subscriptions.length > 0) {
for (const sub of this.subscriptions) { for (const sub of this.subscriptions) {
sub.unsubscribe(); 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 { protected onSort(): void {
this.subscriptions.push( this.subscriptions.push(

View File

@ -4,11 +4,11 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; // showcase import { TranslateService } from '@ngx-translate/core'; // showcase
import { BaseComponent } from 'app/base.component'; 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'; * The start component. Greeting page for OpenSlides
import { DataStoreService } from 'app/core/core-services/data-store.service'; */
@Component({ @Component({
selector: 'os-start', selector: 'os-start',
templateUrl: './start.component.html' templateUrl: './start.component.html'
@ -22,8 +22,9 @@ export class StartComponent extends BaseComponent implements OnInit {
* *
* @param titleService the title serve * @param titleService the title serve
* @param translate to translation module * @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); super(titleService, translate);
} }
@ -31,51 +32,18 @@ export class StartComponent extends BaseComponent implements OnInit {
* Init the component. * Init the component.
* *
* Sets the welcomeTitle and welcomeText. * 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 { 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'); 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) { // set the welcome title
this.welcomeTitle = welcomeTitleConfig.value as string; this.configService
} .get<string>('general_event_welcome_title')
.subscribe(welcomeTitle => (this.welcomeTitle = welcomeTitle));
const welcomeTextConfig = this.DS.filter<Config>( // set the welcome text
Config, this.configService
config => config.key === 'general_event_welcome_text' .get<string>('general_event_welcome_text')
)[0] as Config; .subscribe(welcomeText => (this.welcomeText = welcomeText as string));
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'));
} }
} }

View File

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

View File

@ -111,6 +111,10 @@ export class ViewConfig extends BaseViewModel {
public updateDependencies(update: BaseViewModel): void {} 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. * 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, * 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; return this.element_id;
}; };
public getModel(): History {
return this.history;
}
/** /**
* Updates the history object with new values * Updates the history object with new values
* *

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -73,6 +73,15 @@ export class MotionCommentSectionListComponent extends BaseViewComponent impleme
this.updateForm = this.formBuilder.group(form); 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. * 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. * Opens the create form.
*/ */

View File

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

View File

@ -494,7 +494,9 @@
mat-icon-button mat-icon-button
[matMenuTriggerFor]="changeRecoMenu" [matMenuTriggerFor]="changeRecoMenu"
matTooltip="{{ 'Change recommendations' | translate }}" 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> <mat-icon>rate_review</mat-icon>
</button> </button>

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 { Component, OnInit, OnDestroy, ElementRef, HostListener, TemplateRef } from '@angular/core';
import { DomSanitizer, SafeHtml, Title } from '@angular/platform-browser'; import { DomSanitizer, SafeHtml, Title } from '@angular/platform-browser';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; 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 { ChangeRecommendationRepositoryService } from 'app/core/repositories/motions/change-recommendation-repository.service';
import { CreateMotion } from 'app/site/motions/models/create-motion'; import { CreateMotion } from 'app/site/motions/models/create-motion';
import { ConfigService } from 'app/core/ui-services/config.service'; 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 { DiffLinesInParagraph, LineRange } from 'app/core/ui-services/diff.service';
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.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 { LinenumberingService } from 'app/core/ui-services/linenumbering.service';
import { LocalPermissionsService } from 'app/site/motions/services/local-permissions.service'; import { LocalPermissionsService } from 'app/site/motions/services/local-permissions.service';
import { Mediafile } from 'app/shared/models/mediafiles/mediafile'; import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
import { Motion } from 'app/shared/models/motions/motion'; import { Motion } from 'app/shared/models/motions/motion';
import { MotionBlock } from 'app/shared/models/motions/motion-block';
import { import {
MotionChangeRecommendationComponentData, MotionChangeRecommendationComponentData,
MotionChangeRecommendationComponent 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 { PersonalNoteService } from 'app/core/ui-services/personal-note.service';
import { PromptService } from 'app/core/ui-services/prompt.service'; import { PromptService } from 'app/core/ui-services/prompt.service';
import { StatuteParagraphRepositoryService } from 'app/core/repositories/motions/statute-paragraph-repository.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 { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
import { ViewMotionBlock } from 'app/site/motions/models/view-motion-block'; import { ViewMotionBlock } from 'app/site/motions/models/view-motion-block';
import { ViewWorkflow } from 'app/site/motions/models/view-workflow'; 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 { ViewItem } from 'app/site/agenda/models/view-item';
import { ViewportService } from 'app/core/ui-services/viewport.service'; import { ViewportService } from 'app/core/ui-services/viewport.service';
import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile'; 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 { ViewMotionChangeRecommendation } from 'app/site/motions/models/view-change-recommendation';
import { import {
ViewMotionNotificationEditMotion, ViewMotionNotificationEditMotion,
@ -52,7 +48,10 @@ import { ViewMotion, ChangeRecoMode, LineNumberingMode } from 'app/site/motions/
import { ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph'; import { ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph';
import { ViewTag } from 'app/site/tags/models/view-tag'; import { ViewTag } from 'app/site/tags/models/view-tag';
import { ViewUnifiedChange } from 'app/shared/models/motions/view-unified-change'; 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 * Component for the motion detail view
@ -344,6 +343,13 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
*/ */
public backTarget = '../..'; 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. * Constructs the detail view.
* *
@ -391,45 +397,44 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
private agendaRepo: ItemRepositoryService, private agendaRepo: ItemRepositoryService,
private changeRecoRepo: ChangeRecommendationRepositoryService, private changeRecoRepo: ChangeRecommendationRepositoryService,
private statuteRepo: StatuteParagraphRepositoryService, private statuteRepo: StatuteParagraphRepositoryService,
private DS: DataStoreService,
private configService: ConfigService, private configService: ConfigService,
private sanitizer: DomSanitizer, private sanitizer: DomSanitizer,
private promptService: PromptService, private promptService: PromptService,
private pdfExport: MotionPdfExportService, private pdfExport: MotionPdfExportService,
private personalNoteService: PersonalNoteService, private personalNoteService: PersonalNoteService,
private linenumberingService: LinenumberingService, private linenumberingService: LinenumberingService,
private viewModelStore: ViewModelStoreService,
private categoryRepo: CategoryRepositoryService, private categoryRepo: CategoryRepositoryService,
private userRepo: UserRepositoryService, 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); 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));
// 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();
} }
});
/**
* 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();
this.createForm();
this.observeRoute();
this.getMotionByUrl();
this.setSurroundingMotions();
// load config variables // load config variables
this.configService this.configService
@ -452,36 +457,17 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
this.configService this.configService
.get<ChangeRecoMode>('motions_recommendation_text_mode') .get<ChangeRecoMode>('motions_recommendation_text_mode')
.subscribe(mode => (this.crMode = mode)); .subscribe(mode => (this.crMode = mode));
// 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();
}
} }
/**
* 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;
}); });
// Set the default visibility using observers // 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 // Update statute paragraphs
this.mediafilesObserver.subscribe(files => { this.statuteRepo.getViewModelListObservable().subscribe(newViewStatuteParagraphs => {
if (this.createForm) { this.statuteParagraphs = newViewStatuteParagraphs;
const attachmentsCtrl = this.contentForm.get('attachments_id'); });
if (this.mediafilesObserver.value.length === 0) {
attachmentsCtrl.disable(); // Observe motion changes to trigger surrounding motions
} else { this.motionObserver.subscribe(motionChanges => {
attachmentsCtrl.enable(); if (motionChanges) {
} this.setSurroundingMotions();
} }
}); });
} }
@ -510,6 +496,22 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
*/ */
public ngOnDestroy(): void { public ngOnDestroy(): void {
this.unsubscribeEditNotifications(TypeOfNotificationViewMotion.TYPE_CLOSING_EDITING_MOTION); 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,31 +557,35 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
* determine the motion to display using the URL * determine the motion to display using the URL
*/ */
public getMotionByUrl(): void { public getMotionByUrl(): void {
this.route.params.subscribe(params => { const params = this.route.snapshot.params;
if (Object.keys(params).length > 0) { if (params && params.id) {
// load existing motion // existing motion
const motionId: number = +params.id; const motionId: number = +params.id;
this.repo.getViewModelObservable(motionId).subscribe(newViewMotion => {
if (newViewMotion) { // the following subscriptions need to be cleared when the route changes
this.motion = newViewMotion; this.subscriptions.push(
this.repo.getViewModelObservable(motionId).subscribe(motion => {
if (motion) {
this.motion = motion;
this.newStateExtension = this.motion.stateExtension; this.newStateExtension = this.motion.stateExtension;
this.patchForm(this.motion); this.patchForm(this.motion);
} }
}); }),
this.repo.amendmentsTo(motionId).subscribe( this.repo.amendmentsTo(motionId).subscribe(
(amendments: ViewMotion[]): void => { (amendments: ViewMotion[]): void => {
this.amendments = amendments; this.amendments = amendments;
this.recalcUnifiedChanges(); this.recalcUnifiedChanges();
} }
); ),
this.changeRecoRepo this.changeRecoRepo
.getChangeRecosOfMotionObservable(motionId) .getChangeRecosOfMotionObservable(motionId)
.subscribe((recos: ViewMotionChangeRecommendation[]) => { .subscribe((recos: ViewMotionChangeRecommendation[]) => {
this.changeRecommendations = recos; this.changeRecommendations = recos;
this.recalcUnifiedChanges(); this.recalcUnifiedChanges();
}); })
);
} else { } else {
// creates a new motion // new motion
this.newMotion = true; this.newMotion = true;
this.editMotion = true; this.editMotion = true;
// prevent 'undefined' to appear in the ui // prevent 'undefined' to appear in the ui
@ -613,7 +619,6 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
this.motion = new ViewCreateMotion(new CreateMotion(defaultMotion)); this.motion = new ViewCreateMotion(new CreateMotion(defaultMotion));
this.motionCopy = 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 { public navigateToMotion(motion: ViewMotion): void {
if (motion) { if (motion) {
this.router.navigate(['../contacts'], { relativeTo: this.route.parent }); this.router.navigate([`../${motion.id}`], { relativeTo: this.route.parent });
// update the current motion // update the current motion
this.motion = motion; this.motion = motion;
this.setSurroundingMotions(); this.setSurroundingMotions();
@ -1243,6 +1248,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
* Observes the repository for changes in the motion recommender * Observes the repository for changes in the motion recommender
*/ */
public setupRecommender(): void { public setupRecommender(): void {
if (this.motion) {
const configKey = this.motion.isStatuteAmendment() const configKey = this.motion.isStatuteAmendment()
? 'motions_statute_recommendations_by' ? 'motions_statute_recommendations_by'
: 'motions_recommendations_by'; : 'motions_recommendations_by';
@ -1253,6 +1259,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
this.recommender = recommender; this.recommender = recommender;
}); });
} }
}
/** /**
* Create the absolute path to the corresponding list of speakers * Create the absolute path to the corresponding list of speakers

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'; import { AmendmentCreateWizardComponent } from './components/amendment-create-wizard/amendment-create-wizard.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: MotionDetailComponent, pathMatch: 'full' }, { path: '', component: MotionDetailComponent, pathMatch: 'full', runGuardsAndResolvers: 'paramsChange' },
{ path: 'create-amendment', component: AmendmentCreateWizardComponent } { path: 'create-amendment', component: AmendmentCreateWizardComponent }
]; ];

View File

@ -41,7 +41,8 @@ const routes: Routes = [
}, },
{ {
path: ':id', 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; return this.description ? `${this.title} (${this.description})` : this.title;
}; };
public getModel(): Countdown {
return this.countdown;
}
public updateDependencies(update: BaseViewModel): void {} public updateDependencies(update: BaseViewModel): void {}
public getSlide(): ProjectorElementBuildDeskriptor { public getSlide(): ProjectorElementBuildDeskriptor {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -76,6 +76,10 @@ export class ViewGroup extends BaseViewModel {
return this.name; return this.name;
}; };
public getModel(): Group {
return this.group;
}
public updateDependencies(update: BaseViewModel): void { public updateDependencies(update: BaseViewModel): void {
console.log('ViewGroups wants to update Values with : ', update); 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; return this.personalNote ? this.personalNote.toString() : null;
}; };
public getModel(): PersonalNote {
return this.personalNote;
}
public updateDependencies(update: BaseViewModel): void {} public updateDependencies(update: BaseViewModel): void {}
} }

View File

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