Merge pull request #4901 from FinnStutzenstein/reverse
Reverse relations
This commit is contained in:
commit
3ccf5e9bea
@ -1,7 +1,7 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
|
||||
import { AgendaAppConfig } from '../../site/agenda/agenda.config';
|
||||
import { AppConfig, ModelEntry, SearchableModelEntry } from '../app-config';
|
||||
import { AppConfig, ModelEntry, SearchableModelEntry } from '../definitions/app-config';
|
||||
import { BaseRepository } from 'app/core/repositories/base-repository';
|
||||
import { HistoryAppConfig } from 'app/site/history/history.config';
|
||||
import { ProjectorAppConfig } from 'app/site/projector/projector.config';
|
||||
@ -14,7 +14,7 @@ import { ServicesToLoadOnAppsLoaded } from '../core.module';
|
||||
import { MainMenuService } from './main-menu.service';
|
||||
import { MediafileAppConfig } from '../../site/mediafiles/mediafile.config';
|
||||
import { MotionsAppConfig } from '../../site/motions/motions.config';
|
||||
import { OnAfterAppsLoaded } from '../onAfterAppsLoaded';
|
||||
import { OnAfterAppsLoaded } from '../definitions/on-after-apps-loaded';
|
||||
import { plugins } from '../../../plugins';
|
||||
import { SearchService } from '../ui-services/search.service';
|
||||
import { isSearchable } from '../../site/base/searchable';
|
||||
|
@ -5,7 +5,7 @@ import { Observable, Subject } from 'rxjs';
|
||||
import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model';
|
||||
import { BaseRepository } from '../repositories/base-repository';
|
||||
import { CollectionStringMapperService } from './collection-string-mapper.service';
|
||||
import { Deferred } from '../deferred';
|
||||
import { Deferred } from '../promises/deferred';
|
||||
import { StorageService } from './storage.service';
|
||||
|
||||
/**
|
||||
@ -102,6 +102,13 @@ export class UpdateSlot {
|
||||
return this.deletedModels[collection] || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns the mapping of all deleted models
|
||||
*/
|
||||
public getDeletedModels(): CollectionIds {
|
||||
return this.deletedModels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this object to another update slot.
|
||||
*/
|
||||
@ -221,9 +228,12 @@ export class DataStoreUpdateManagerService {
|
||||
}
|
||||
});
|
||||
|
||||
// Phase 2: updating dependencies
|
||||
// Phase 2: updating dependencies (deleting ad changing in this order)
|
||||
repositories.forEach(repo => {
|
||||
if (repo.updateDependencies(slot.getChangedModels())) {
|
||||
if (repo.updateDependenciesForDeletedModels(slot.getDeletedModels())) {
|
||||
affectedRepos[repo.collectionString] = repo;
|
||||
}
|
||||
if (repo.updateDependenciesForChangedModels(slot.getChangedModels())) {
|
||||
affectedRepos[repo.collectionString] = repo;
|
||||
}
|
||||
});
|
||||
|
@ -4,7 +4,7 @@ import { Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { OpenSlidesStatusService } from './openslides-status.service';
|
||||
import { formatQueryParams, QueryParams } from '../query-params';
|
||||
import { formatQueryParams, QueryParams } from '../definitions/query-params';
|
||||
|
||||
/**
|
||||
* Enum for different HTTPMethods
|
||||
|
@ -8,10 +8,10 @@ import { Group } from 'app/shared/models/users/group';
|
||||
import { ViewUser } from 'app/site/users/models/view-user';
|
||||
import { CollectionStringMapperService } from './collection-string-mapper.service';
|
||||
import { DataStoreService } from './data-store.service';
|
||||
import { Deferred } from '../deferred';
|
||||
import { Deferred } from '../promises/deferred';
|
||||
import { HttpService } from './http.service';
|
||||
import { OfflineService } from './offline.service';
|
||||
import { OnAfterAppsLoaded } from '../onAfterAppsLoaded';
|
||||
import { OnAfterAppsLoaded } from '../definitions/on-after-apps-loaded';
|
||||
import { OpenSlidesStatusService } from './openslides-status.service';
|
||||
import { StorageService } from './storage.service';
|
||||
import { User } from '../../shared/models/users/user';
|
||||
|
@ -3,8 +3,8 @@ import { ApplicationRef, Injectable } from '@angular/core';
|
||||
import { first, take } from 'rxjs/operators';
|
||||
|
||||
import { ConstantsService } from './constants.service';
|
||||
import { Deferred } from '../deferred';
|
||||
import { TimeoutPromise } from '../timeout-promise';
|
||||
import { Deferred } from '../promises/deferred';
|
||||
import { TimeoutPromise } from '../promises/timeout-promise';
|
||||
import { WebsocketService } from './websocket.service';
|
||||
|
||||
interface OpenSlidesSettings {
|
||||
|
@ -0,0 +1,16 @@
|
||||
import { inject, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { E2EImportsModule } from '../../../e2e-imports.module';
|
||||
import { RelationManagerService } from './relation-manager.service';
|
||||
|
||||
describe('RelationManagerService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [E2EImportsModule],
|
||||
providers: [RelationManagerService]
|
||||
});
|
||||
});
|
||||
it('should be created', inject([RelationManagerService], (service: RelationManagerService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
});
|
275
client/src/app/core/core-services/relation-manager.service.ts
Normal file
275
client/src/app/core/core-services/relation-manager.service.ts
Normal file
@ -0,0 +1,275 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { BaseModel } from 'app/shared/models/base/base-model';
|
||||
import { BaseViewModel, ViewModelConstructor } from 'app/site/base/base-view-model';
|
||||
import {
|
||||
BaseOrderedRelation,
|
||||
isCustomRelationDefinition,
|
||||
isGenericRelationDefinition,
|
||||
isNestedRelationDefinition,
|
||||
isNormalRelationDefinition,
|
||||
isReverseRelationDefinition,
|
||||
RelationDefinition,
|
||||
ReverseRelationDefinition
|
||||
} from '../definitions/relations';
|
||||
import { ViewModelStoreService } from './view-model-store.service';
|
||||
|
||||
/**
|
||||
* Manages relations between view models. This service is and should only used by the
|
||||
* base repository to offload maanging relations between view models.
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RelationManagerService {
|
||||
public constructor(private viewModelStoreService: ViewModelStoreService) {}
|
||||
|
||||
/**
|
||||
* Sorts the array of foreign view models in the given view models for the given relation.
|
||||
*/
|
||||
public sortByRelation<V extends BaseViewModel, VForegin extends BaseViewModel>(
|
||||
relation: BaseOrderedRelation<VForegin>,
|
||||
viewModel: V
|
||||
): void {
|
||||
const order = relation.order;
|
||||
viewModel['_' + relation.ownKey].sort((a: BaseViewModel, b: BaseViewModel) => {
|
||||
if (!order || a[order] === b[order]) {
|
||||
return a.id - b.id;
|
||||
} else {
|
||||
return a[order] - b[order];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a view model from the given model and model ctor. All dependencies will be
|
||||
* set accorting to relations.
|
||||
*/
|
||||
public createViewModel<M extends BaseModel, V extends BaseViewModel>(
|
||||
model: M,
|
||||
modelCtor: ViewModelConstructor<V>,
|
||||
relations: RelationDefinition[]
|
||||
): V {
|
||||
const viewModel = new modelCtor(model) as V;
|
||||
|
||||
relations.forEach(relation => {
|
||||
this.setRelationsInViewModel(model, viewModel, relation);
|
||||
});
|
||||
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets one foreign view model in the view model according to the relation and the information
|
||||
* from the model.
|
||||
*/
|
||||
protected setRelationsInViewModel<M extends BaseModel, V extends BaseViewModel>(
|
||||
model: M,
|
||||
viewModel: V,
|
||||
relation: RelationDefinition
|
||||
): void {
|
||||
// no reverse setting needed. This is done in the second phase of the ds-upgrade-manager
|
||||
if (isReverseRelationDefinition(relation)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
(relation.type === 'M2M' || relation.type === 'O2M') &&
|
||||
model[relation.ownIdKey] &&
|
||||
model[relation.ownIdKey].constructor === Array
|
||||
) {
|
||||
const foreignViewModels = this.viewModelStoreService.getMany(
|
||||
relation.foreignModel,
|
||||
model[relation.ownIdKey]
|
||||
);
|
||||
viewModel['_' + relation.ownKey] = foreignViewModels;
|
||||
this.sortByRelation(relation, viewModel);
|
||||
} else if (relation.type === 'M2O') {
|
||||
const foreignViewModel = this.viewModelStoreService.get(relation.foreignModel, model[relation.ownIdKey]);
|
||||
viewModel['_' + relation.ownKey] = foreignViewModel;
|
||||
} else if (isNestedRelationDefinition(relation)) {
|
||||
const foreignViewModels: BaseViewModel[] = model[relation.ownKey].map(foreignModel =>
|
||||
this.createViewModel(foreignModel, relation.foreignModel, relation.relationDefinition || [])
|
||||
);
|
||||
viewModel['_' + relation.ownKey] = foreignViewModels;
|
||||
this.sortByRelation(relation, viewModel);
|
||||
} else if (isGenericRelationDefinition(relation)) {
|
||||
const contentObject = this.viewModelStoreService.get<BaseViewModel>(
|
||||
model[relation.ownContentObjectDataKey].collection,
|
||||
model[relation.ownContentObjectDataKey].id
|
||||
);
|
||||
if (contentObject && relation.isVForeign(contentObject)) {
|
||||
viewModel['_' + relation.ownKey] = contentObject;
|
||||
}
|
||||
} else if (isCustomRelationDefinition(relation)) {
|
||||
relation.setRelations(model, viewModel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an own view model with an deleted model implicit given by the deletedId and
|
||||
* the collection via the relation.
|
||||
*
|
||||
* @return true, if something was updated.
|
||||
*/
|
||||
public updateSingleDependencyForDeletedModel(
|
||||
ownViewModel: BaseViewModel,
|
||||
relation: ReverseRelationDefinition,
|
||||
deletedId: number
|
||||
): boolean {
|
||||
// In both relations, the ownViewModel holds an array of foreignViewModels. Try to find the deleted
|
||||
// foreignViewModel in this array and remove it.
|
||||
if (relation.type === 'O2M' || relation.type === 'M2M') {
|
||||
const ownModelArray = <any>ownViewModel['_' + relation.ownKey];
|
||||
if (!ownModelArray) {
|
||||
return false;
|
||||
}
|
||||
// We have the array of foreign view models for our own view model. Put the foreignViewModel
|
||||
// into it (replace or push).
|
||||
const index = ownModelArray.findIndex(foreignViewModel => foreignViewModel.id === deletedId);
|
||||
if (index > -1) {
|
||||
ownModelArray.splice(index, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// The ownViewModel holds one foreignViewModel. Check, if it is the deleted one.
|
||||
else if (relation.type === 'M2O') {
|
||||
if (ownViewModel['_' + relation.ownKey] && ownViewModel['_' + relation.ownKey].id === deletedId) {
|
||||
ownViewModel['_' + relation.ownKey] = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an own view model with an implicit given model by the collection and changedId.
|
||||
*
|
||||
* @return true, if something was updated.
|
||||
*/
|
||||
public updateSingleDependencyForChangedModel(
|
||||
ownViewModel: BaseViewModel,
|
||||
relation: RelationDefinition,
|
||||
collection: string,
|
||||
changedId: number
|
||||
): boolean {
|
||||
if (isNormalRelationDefinition(relation)) {
|
||||
if (relation.type === 'M2M' || relation.type === 'O2M') {
|
||||
// For the side of the ownViewModel these relations are the same:
|
||||
// the ownViewModel does have may foreign models and we do have a normal relation (not a
|
||||
// reverse one), we just set the many-part of the relation in the ownViewModel.
|
||||
if (
|
||||
ownViewModel[relation.ownIdKey] &&
|
||||
ownViewModel[relation.ownIdKey].constructor === Array &&
|
||||
ownViewModel[relation.ownIdKey].includes(changedId) // The foreign view model belongs to us.
|
||||
) {
|
||||
const foreignViewModel = <any>this.viewModelStoreService.get(collection, changedId);
|
||||
this.setForeingViewModelInOwnViewModelArray(foreignViewModel, ownViewModel, relation.ownKey);
|
||||
return true;
|
||||
}
|
||||
} else if (relation.type === 'M2O') {
|
||||
if (ownViewModel[relation.ownIdKey] === <any>changedId) {
|
||||
// Check, if this is the matching foreign view model.
|
||||
ownViewModel['_' + relation.ownKey] = <any>this.viewModelStoreService.get(collection, changedId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (isReverseRelationDefinition(relation)) {
|
||||
const foreignViewModel = <any>this.viewModelStoreService.get(collection, changedId);
|
||||
|
||||
// The foreign model has one id. Check, if the ownViewModel is the matching view model.
|
||||
// If so, add the foreignViewModel to the array from the ownViewModel (with many foreignViewModels)
|
||||
if (relation.type === 'O2M') {
|
||||
if (foreignViewModel[relation.foreignIdKey] === ownViewModel.id) {
|
||||
this.setForeingViewModelInOwnViewModelArray(foreignViewModel, ownViewModel, relation.ownKey);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// The foreign model should hold an array of ids. If the ownViewModel is in it, the foreignViewModel must
|
||||
// be included into the array from the ownViewModel (with many foreignViewModels)
|
||||
else if (relation.type === 'M2M') {
|
||||
if (
|
||||
foreignViewModel[relation.foreignIdKey] &&
|
||||
foreignViewModel[relation.foreignIdKey].constructor === Array &&
|
||||
foreignViewModel[relation.foreignIdKey].includes(ownViewModel.id)
|
||||
) {
|
||||
this.setForeingViewModelInOwnViewModelArray(foreignViewModel, ownViewModel, relation.ownKey);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// The foreign model should hold an array of ids. If the ownViewModel is in it, the foreignViewModel is the
|
||||
// one and only matching model for the ownViewModel
|
||||
else if (relation.type === 'M2O') {
|
||||
if (
|
||||
foreignViewModel[relation.foreignIdKey] &&
|
||||
foreignViewModel[relation.foreignIdKey].constructor === Array &&
|
||||
foreignViewModel[relation.foreignIdKey].includes(ownViewModel.id)
|
||||
) {
|
||||
ownViewModel['_' + relation.ownKey] = foreignViewModel;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (isNestedRelationDefinition(relation)) {
|
||||
let updated = false;
|
||||
(relation.relationDefinition || []).forEach(nestedRelation => {
|
||||
const nestedViewModels = ownViewModel[relation.ownKey] as BaseViewModel[];
|
||||
nestedViewModels.forEach(nestedViewModel => {
|
||||
if (
|
||||
this.updateSingleDependencyForChangedModel(
|
||||
nestedViewModel,
|
||||
nestedRelation,
|
||||
collection,
|
||||
changedId
|
||||
)
|
||||
) {
|
||||
updated = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
return updated;
|
||||
} else if (isCustomRelationDefinition(relation)) {
|
||||
const foreignViewModel = <any>this.viewModelStoreService.get(collection, changedId);
|
||||
return relation.updateDependency(ownViewModel, foreignViewModel);
|
||||
} else if (isGenericRelationDefinition(relation)) {
|
||||
const foreignModel = <any>this.viewModelStoreService.get(collection, changedId);
|
||||
if (
|
||||
foreignModel &&
|
||||
foreignModel.collectionString === ownViewModel[relation.ownContentObjectDataKey].collection &&
|
||||
foreignModel.id === ownViewModel[relation.ownContentObjectDataKey].id
|
||||
) {
|
||||
if (relation.isVForeign(foreignModel)) {
|
||||
ownViewModel['_' + relation.ownKey] = foreignModel;
|
||||
return true;
|
||||
} else {
|
||||
console.warn(`The object is not an ${relation.VForeignVerbose}:` + foreignModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private setForeingViewModelInOwnViewModelArray(
|
||||
foreignViewModel: BaseViewModel,
|
||||
ownViewModel: BaseViewModel,
|
||||
ownKey: string
|
||||
): void {
|
||||
let ownViewModelArray = <any>ownViewModel['_' + ownKey];
|
||||
if (!ownViewModelArray) {
|
||||
ownViewModel['_' + ownKey] = [];
|
||||
ownViewModelArray = <any>ownViewModel['_' + ownKey]; // get the new reference
|
||||
}
|
||||
// We have the array of foreign view models for our own view model. Put the foreignViewModel
|
||||
// into it (replace or push).
|
||||
const index = ownViewModelArray.findIndex(_foreignViewModel => _foreignViewModel.id === foreignViewModel.id);
|
||||
if (index < 0) {
|
||||
ownViewModelArray.push(foreignViewModel);
|
||||
} else {
|
||||
ownViewModelArray[index] = foreignViewModel;
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ import { take } from 'rxjs/operators';
|
||||
import { TextDecoder, TextEncoder } from 'text-encoding';
|
||||
|
||||
import { OpenSlidesStatusService } from './openslides-status.service';
|
||||
import { formatQueryParams, QueryParams } from '../query-params';
|
||||
import { formatQueryParams, QueryParams } from '../definitions/query-params';
|
||||
|
||||
/**
|
||||
* The generic message format in which messages are send and recieved by the server.
|
||||
|
@ -4,7 +4,7 @@ import { Title } from '@angular/platform-browser';
|
||||
|
||||
import { ProjectionDialogComponent } from 'app/shared/components/projection-dialog/projection-dialog.component';
|
||||
import { ChoiceDialogComponent } from '../shared/components/choice-dialog/choice-dialog.component';
|
||||
import { OnAfterAppsLoaded } from './onAfterAppsLoaded';
|
||||
import { OnAfterAppsLoaded } from './definitions/on-after-apps-loaded';
|
||||
import { OperatorService } from './core-services/operator.service';
|
||||
import { PromptDialogComponent } from '../shared/components/prompt-dialog/prompt-dialog.component';
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Type } from '@angular/core';
|
||||
|
||||
import { BaseViewModel, ViewModelConstructor } from 'app/site/base/base-view-model';
|
||||
import { BaseModel, ModelConstructor } from '../shared/models/base/base-model';
|
||||
import { BaseRepository } from './repositories/base-repository';
|
||||
import { MainMenuEntry } from './core-services/main-menu.service';
|
||||
import { Searchable } from '../site/base/searchable';
|
||||
import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model';
|
||||
import { BaseRepository } from '../repositories/base-repository';
|
||||
import { MainMenuEntry } from '../core-services/main-menu.service';
|
||||
import { Searchable } from '../../site/base/searchable';
|
||||
|
||||
interface BaseModelEntry {
|
||||
collectionString: string;
|
190
client/src/app/core/definitions/relations.ts
Normal file
190
client/src/app/core/definitions/relations.ts
Normal file
@ -0,0 +1,190 @@
|
||||
import { BaseModel } from 'app/shared/models/base/base-model';
|
||||
import { BaseViewModel, ViewModelConstructor } from 'app/site/base/base-view-model';
|
||||
|
||||
// All "standard" relations.
|
||||
export type RelationDefinition<VForeign extends BaseViewModel = BaseViewModel> =
|
||||
| NormalRelationDefinition<VForeign>
|
||||
| ReverseRelationDefinition<VForeign>
|
||||
| NestedRelationDefinition<VForeign>
|
||||
| CustomRelationDefinition<VForeign>
|
||||
| GenericRelationDefinition<VForeign>;
|
||||
|
||||
interface BaseRelationDefinition<VForeign extends BaseViewModel> {
|
||||
/**
|
||||
* The name of the property, where the foreign view model should be accessable.
|
||||
* Note, that this must be a getter to a private variable `_<ownKey`!
|
||||
*
|
||||
* E.g. `category`. (private variable `_category`)
|
||||
*/
|
||||
ownKey: string;
|
||||
|
||||
/**
|
||||
* The model on the other side of the relation.
|
||||
*/
|
||||
foreignModel: ViewModelConstructor<VForeign>;
|
||||
}
|
||||
|
||||
export interface BaseOrderedRelation<VForeign extends BaseViewModel> extends BaseRelationDefinition<VForeign> {
|
||||
/**
|
||||
* Provide an extra key (holding a number) to order by.
|
||||
* If the value is equal or no order key is given, the models
|
||||
* will be sorted by id.
|
||||
*/
|
||||
order?: string;
|
||||
}
|
||||
|
||||
interface BaseNormalRelationDefinition<VForeign extends BaseViewModel> extends BaseRelationDefinition<VForeign> {
|
||||
/**
|
||||
* This is the key in the own model where the id(s) are given. Must be present in
|
||||
* the model and view model. E.g. `category_id` in a motion.
|
||||
*/
|
||||
ownIdKey: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* These relations has to be read as in an ER-model. The right side is always the
|
||||
* model where the relation is defined.
|
||||
* - M2O: From this model to another one, where this model is the right (many).
|
||||
* E.g. motions<->categories: One motions has One category; One category has
|
||||
* Many motions.
|
||||
* - O2M: Reverse relation to M2O. E.g. defined for categories: One category has
|
||||
* Many motions and One motion has One category.
|
||||
* - M2M: M2M relation from this to another model.
|
||||
*/
|
||||
|
||||
interface NormalM2MRelationDefinition<VForeign extends BaseViewModel>
|
||||
extends BaseNormalRelationDefinition<VForeign>,
|
||||
BaseOrderedRelation<VForeign> {
|
||||
type: 'M2M';
|
||||
}
|
||||
|
||||
interface NormalO2MRelationDefinition<VForeign extends BaseViewModel>
|
||||
extends BaseNormalRelationDefinition<VForeign>,
|
||||
BaseOrderedRelation<VForeign> {
|
||||
type: 'O2M';
|
||||
}
|
||||
|
||||
interface NormalM2ORelationDefinition<VForeign extends BaseViewModel> extends BaseNormalRelationDefinition<VForeign> {
|
||||
type: 'M2O';
|
||||
}
|
||||
|
||||
export type NormalRelationDefinition<VForeign extends BaseViewModel = BaseViewModel> =
|
||||
| NormalM2MRelationDefinition<VForeign>
|
||||
| NormalO2MRelationDefinition<VForeign>
|
||||
| NormalM2ORelationDefinition<VForeign>;
|
||||
|
||||
export function isNormalRelationDefinition(obj: RelationDefinition): obj is NormalRelationDefinition<BaseViewModel> {
|
||||
const relation = obj as NormalRelationDefinition<BaseViewModel>;
|
||||
return (relation.type === 'M2O' || relation.type === 'O2M' || relation.type === 'M2M') && !!relation.ownIdKey;
|
||||
}
|
||||
|
||||
interface BaseReverseRelationDefinition<VForeign extends BaseViewModel> {
|
||||
/**
|
||||
* The key with the id(s) is given in the foreign model. Must be present in
|
||||
* the model and view model. E.g. `category_id` from a motion but the relation is
|
||||
* defined for a category.
|
||||
*/
|
||||
foreignIdKey: string;
|
||||
|
||||
/**
|
||||
* The name of the property, where the foreign view model should be accessable.
|
||||
* Note, that this must be a getter to a private variable `_<ownKey`!
|
||||
*
|
||||
* E.g. `category`. (private variable `_category`)
|
||||
*/
|
||||
ownKey: string;
|
||||
|
||||
/**
|
||||
* The model on the other side of the relation.
|
||||
*/
|
||||
foreignModel: ViewModelConstructor<VForeign>;
|
||||
}
|
||||
|
||||
interface ReverseM2MRelationDefinition<VForeign extends BaseViewModel>
|
||||
extends BaseReverseRelationDefinition<VForeign>,
|
||||
BaseOrderedRelation<VForeign> {
|
||||
type: 'M2M';
|
||||
}
|
||||
|
||||
interface ReverseO2MRelationDefinition<VForeign extends BaseViewModel>
|
||||
extends BaseReverseRelationDefinition<VForeign>,
|
||||
BaseOrderedRelation<VForeign> {
|
||||
type: 'O2M';
|
||||
}
|
||||
|
||||
interface ReverseM2ORelationDefinition<VForeign extends BaseViewModel> extends BaseReverseRelationDefinition<VForeign> {
|
||||
type: 'M2O';
|
||||
}
|
||||
|
||||
export type ReverseRelationDefinition<VForeign extends BaseViewModel = BaseViewModel> =
|
||||
| ReverseM2MRelationDefinition<VForeign>
|
||||
| ReverseO2MRelationDefinition<VForeign>
|
||||
| ReverseM2ORelationDefinition<VForeign>;
|
||||
|
||||
export function isReverseRelationDefinition(obj: RelationDefinition): obj is ReverseRelationDefinition<BaseViewModel> {
|
||||
const relation = obj as ReverseRelationDefinition<BaseViewModel>;
|
||||
return (relation.type === 'M2O' || relation.type === 'O2M' || relation.type === 'M2M') && !!relation.foreignIdKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested relations in the REST-API. For the most values see
|
||||
* `NormalRelationDefinition`.
|
||||
*/
|
||||
interface NestedRelationDefinition<VForeign extends BaseViewModel> extends BaseOrderedRelation<VForeign> {
|
||||
type: 'nested';
|
||||
ownKey: string;
|
||||
|
||||
/**
|
||||
* The nested relations.
|
||||
*/
|
||||
relationDefinition?: RelationDefinition[];
|
||||
}
|
||||
|
||||
export function isNestedRelationDefinition(obj: RelationDefinition): obj is NestedRelationDefinition<BaseViewModel> {
|
||||
return obj.type === 'nested';
|
||||
}
|
||||
|
||||
interface GenericRelationDefinition<VForeign extends BaseViewModel = BaseViewModel> {
|
||||
type: 'generic';
|
||||
|
||||
/**
|
||||
* The key where the model and view model holds the ContentObject (object with collection and id).
|
||||
* Similar to ownIdKey.
|
||||
*/
|
||||
ownContentObjectDataKey: string;
|
||||
|
||||
/**
|
||||
* The key where to but the content object.
|
||||
*/
|
||||
ownKey: string;
|
||||
|
||||
possibleModels: ViewModelConstructor<BaseViewModel>[];
|
||||
isVForeign: (obj: any) => obj is VForeign;
|
||||
VForeignVerbose: string;
|
||||
}
|
||||
|
||||
export function isGenericRelationDefinition(obj: RelationDefinition): obj is GenericRelationDefinition<BaseViewModel> {
|
||||
return obj.type === 'generic';
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom relation with callbacks with things todo.
|
||||
*/
|
||||
interface CustomRelationDefinition<VForeign extends BaseViewModel> {
|
||||
type: 'custom';
|
||||
foreignModel: ViewModelConstructor<VForeign>;
|
||||
|
||||
/**
|
||||
* Called, when the view model is created from the model.
|
||||
*/
|
||||
setRelations: (model: BaseModel, viewModel: BaseViewModel) => void;
|
||||
|
||||
/**
|
||||
* Called, when the dependency was updated.
|
||||
*/
|
||||
updateDependency: (ownViewModel: BaseViewModel, foreignViewModel: VForeign) => boolean;
|
||||
}
|
||||
|
||||
export function isCustomRelationDefinition(obj: RelationDefinition): obj is CustomRelationDefinition<BaseViewModel> {
|
||||
return obj.type === 'custom';
|
||||
}
|
@ -4,7 +4,9 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { DataSendService } from 'app/core/core-services/data-send.service';
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { TreeIdNode } from 'app/core/ui-services/tree.service';
|
||||
import { Item } from 'app/shared/models/agenda/item';
|
||||
@ -19,18 +21,19 @@ import {
|
||||
import { ViewMotion } from 'app/site/motions/models/view-motion';
|
||||
import { ViewMotionBlock } from 'app/site/motions/models/view-motion-block';
|
||||
import { ViewTopic } from 'app/site/topics/models/view-topic';
|
||||
import { BaseHasContentObjectRepository, GenericRelationDefinition } from '../base-has-content-object-repository';
|
||||
import { BaseHasContentObjectRepository } from '../base-has-content-object-repository';
|
||||
import { BaseIsAgendaItemContentObjectRepository } from '../base-is-agenda-item-content-object-repository';
|
||||
import { RelationDefinition } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataStoreService } from '../../core-services/data-store.service';
|
||||
|
||||
const ItemRelations: (RelationDefinition | GenericRelationDefinition)[] = [
|
||||
const ItemRelations: RelationDefinition[] = [
|
||||
{
|
||||
type: 'generic',
|
||||
possibleModels: [ViewMotion, ViewMotionBlock, ViewTopic, ViewAssignment],
|
||||
isVForeign: isBaseViewModelWithAgendaItem,
|
||||
VForeignVerbose: 'BaseViewModelWithAgendaItem'
|
||||
VForeignVerbose: 'BaseViewModelWithAgendaItem',
|
||||
ownContentObjectDataKey: 'contentObjectData',
|
||||
ownKey: 'contentObject'
|
||||
}
|
||||
];
|
||||
|
||||
@ -64,10 +67,11 @@ export class ItemRepositoryService extends BaseHasContentObjectRepository<
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private httpService: HttpService,
|
||||
private config: ConfigService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Item, ItemRelations);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, Item, ItemRelations);
|
||||
|
||||
this.setSortFunction((a, b) => a.weight - b.weight);
|
||||
}
|
||||
|
@ -4,7 +4,9 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { DataSendService } from 'app/core/core-services/data-send.service';
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { ListOfSpeakers } from 'app/shared/models/agenda/list-of-speakers';
|
||||
import { Identifiable } from 'app/shared/models/base/identifiable';
|
||||
import { ListOfSpeakersTitleInformation, ViewListOfSpeakers } from 'app/site/agenda/models/view-list-of-speakers';
|
||||
@ -19,19 +21,20 @@ import { ViewMotion } from 'app/site/motions/models/view-motion';
|
||||
import { ViewMotionBlock } from 'app/site/motions/models/view-motion-block';
|
||||
import { ViewTopic } from 'app/site/topics/models/view-topic';
|
||||
import { ViewUser } from 'app/site/users/models/view-user';
|
||||
import { BaseHasContentObjectRepository, GenericRelationDefinition } from '../base-has-content-object-repository';
|
||||
import { BaseHasContentObjectRepository } from '../base-has-content-object-repository';
|
||||
import { BaseIsListOfSpeakersContentObjectRepository } from '../base-is-list-of-speakers-content-object-repository';
|
||||
import { RelationDefinition } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataStoreService } from '../../core-services/data-store.service';
|
||||
import { ItemRepositoryService } from './item-repository.service';
|
||||
|
||||
const ListOfSpeakersRelations: (RelationDefinition | GenericRelationDefinition)[] = [
|
||||
const ListOfSpeakersRelations: RelationDefinition[] = [
|
||||
{
|
||||
type: 'generic',
|
||||
possibleModels: [ViewMotion, ViewMotionBlock, ViewTopic, ViewAssignment, ViewMediafile],
|
||||
isVForeign: isBaseViewModelWithListOfSpeakers,
|
||||
VForeignVerbose: 'BaseViewModelWithListOfSpeakers'
|
||||
VForeignVerbose: 'BaseViewModelWithListOfSpeakers',
|
||||
ownContentObjectDataKey: 'contentObjectData',
|
||||
ownKey: 'contentObject'
|
||||
},
|
||||
{
|
||||
type: 'nested',
|
||||
@ -40,7 +43,7 @@ const ListOfSpeakersRelations: (RelationDefinition | GenericRelationDefinition)[
|
||||
order: 'weight',
|
||||
relationDefinition: [
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'user_id',
|
||||
ownKey: 'user',
|
||||
foreignModel: ViewUser
|
||||
@ -79,10 +82,20 @@ export class ListOfSpeakersRepositoryService extends BaseHasContentObjectReposit
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private httpService: HttpService,
|
||||
private itemRepo: ItemRepositoryService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, ListOfSpeakers, ListOfSpeakersRelations);
|
||||
super(
|
||||
DS,
|
||||
dataSend,
|
||||
mapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
ListOfSpeakers,
|
||||
ListOfSpeakersRelations
|
||||
);
|
||||
}
|
||||
|
||||
public getVerboseName = (plural: boolean = false) => {
|
||||
|
@ -4,7 +4,9 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { DataSendService } from 'app/core/core-services/data-send.service';
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { Assignment } from 'app/shared/models/assignments/assignment';
|
||||
import { AssignmentPoll } from 'app/shared/models/assignments/assignment-poll';
|
||||
import { AssignmentTitleInformation, ViewAssignment } from 'app/site/assignments/models/view-assignment';
|
||||
@ -15,7 +17,6 @@ import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
|
||||
import { ViewTag } from 'app/site/tags/models/view-tag';
|
||||
import { ViewUser } from 'app/site/users/models/view-user';
|
||||
import { BaseIsAgendaItemAndListOfSpeakersContentObjectRepository } from '../base-is-agenda-item-and-list-of-speakers-content-object-repository';
|
||||
import { RelationDefinition } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataStoreService } from '../../core-services/data-store.service';
|
||||
|
||||
@ -39,7 +40,7 @@ const AssignmentRelations: RelationDefinition[] = [
|
||||
order: 'weight',
|
||||
relationDefinition: [
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'user_id',
|
||||
ownKey: 'user',
|
||||
foreignModel: ViewUser
|
||||
@ -58,7 +59,7 @@ const AssignmentRelations: RelationDefinition[] = [
|
||||
order: 'weight',
|
||||
relationDefinition: [
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'user_id',
|
||||
ownKey: 'user',
|
||||
foreignModel: ViewUser
|
||||
@ -104,10 +105,20 @@ export class AssignmentRepositoryService extends BaseIsAgendaItemAndListOfSpeake
|
||||
dataSend: DataSendService,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
protected translate: TranslateService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private httpService: HttpService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Assignment, AssignmentRelations);
|
||||
super(
|
||||
DS,
|
||||
dataSend,
|
||||
mapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
Assignment,
|
||||
AssignmentRelations
|
||||
);
|
||||
}
|
||||
|
||||
public getTitle = (titleInformation: AssignmentTitleInformation) => {
|
||||
|
@ -1,25 +1,8 @@
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { ModelConstructor } from 'app/shared/models/base/base-model';
|
||||
import { BaseModelWithContentObject } from 'app/shared/models/base/base-model-with-content-object';
|
||||
import { ContentObject } from 'app/shared/models/base/content-object';
|
||||
import { BaseViewModel, TitleInformation, ViewModelConstructor } from 'app/site/base/base-view-model';
|
||||
import { BaseViewModel, TitleInformation } from 'app/site/base/base-view-model';
|
||||
import { BaseViewModelWithContentObject } from 'app/site/base/base-view-model-with-content-object';
|
||||
import { BaseRepository, RelationDefinition } from './base-repository';
|
||||
import { CollectionStringMapperService } from '../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../core-services/data-send.service';
|
||||
import { DataStoreService } from '../core-services/data-store.service';
|
||||
import { ViewModelStoreService } from '../core-services/view-model-store.service';
|
||||
|
||||
/**
|
||||
* A generic relation for models with a content_object
|
||||
*/
|
||||
export interface GenericRelationDefinition<VForeign extends BaseViewModel = BaseViewModel> {
|
||||
type: 'generic';
|
||||
possibleModels: ViewModelConstructor<BaseViewModel>[];
|
||||
isVForeign: (obj: any) => obj is VForeign;
|
||||
VForeignVerbose: string;
|
||||
}
|
||||
import { BaseRepository } from './base-repository';
|
||||
|
||||
/**
|
||||
* A base repository for objects that *have* content objects, e.g. items and lists of speakers.
|
||||
@ -40,99 +23,6 @@ export abstract class BaseHasContentObjectRepository<
|
||||
};
|
||||
} = {};
|
||||
|
||||
public constructor(
|
||||
DS: DataStoreService,
|
||||
dataSend: DataSendService,
|
||||
collectionStringMapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
baseModelCtor: ModelConstructor<M>,
|
||||
relationDefinitions: (RelationDefinition | GenericRelationDefinition)[] = []
|
||||
) {
|
||||
super(DS, dataSend, collectionStringMapperService, viewModelStoreService, translate, baseModelCtor, <
|
||||
RelationDefinition[]
|
||||
>relationDefinitions); // This cast "hides" the new generic relation from the base repository. Typescript can't handle this...
|
||||
}
|
||||
|
||||
protected _groupRelationsByCollections(
|
||||
relation: RelationDefinition | GenericRelationDefinition,
|
||||
baseRelation: RelationDefinition
|
||||
): void {
|
||||
if (relation.type === 'generic') {
|
||||
relation.possibleModels.forEach(ctor => {
|
||||
const collection = ctor.COLLECTIONSTRING;
|
||||
if (!this.relationsByCollection[collection]) {
|
||||
this.relationsByCollection[collection] = [];
|
||||
}
|
||||
// The cast to any is needed to convince Typescript, that a GenericRelationDefinition can also
|
||||
// be used as a RelationDefinition
|
||||
this.relationsByCollection[collection].push(<any>baseRelation);
|
||||
});
|
||||
} else {
|
||||
super._groupRelationsByCollections(relation, baseRelation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the generic relation.
|
||||
*/
|
||||
protected updateSingleDependency(
|
||||
ownViewModel: V,
|
||||
relation: RelationDefinition | GenericRelationDefinition,
|
||||
collection: string,
|
||||
changedId: number
|
||||
): boolean {
|
||||
if (relation.type === 'generic') {
|
||||
const foreignModel = <any>this.viewModelStoreService.get(collection, changedId);
|
||||
if (
|
||||
foreignModel &&
|
||||
foreignModel.collectionString === ownViewModel.contentObjectData.collection &&
|
||||
foreignModel.id === ownViewModel.contentObjectData.id
|
||||
) {
|
||||
if (relation.isVForeign(foreignModel)) {
|
||||
(<any>ownViewModel)._contentObject = foreignModel;
|
||||
return true;
|
||||
} else {
|
||||
console.warn(`The object is not an ${relation.VForeignVerbose}:` + foreignModel);
|
||||
}
|
||||
|
||||
// TODO: set reverse
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return super.updateSingleDependency(ownViewModel, relation, collection, changedId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the generic relation.
|
||||
*/
|
||||
protected setRelationsInViewModel<K extends BaseViewModel = V>(
|
||||
model: M,
|
||||
viewModel: K,
|
||||
relation: RelationDefinition | GenericRelationDefinition
|
||||
): void {
|
||||
if (relation.type === 'generic') {
|
||||
(<any>viewModel)._contentObject = this.getContentObject(model, relation);
|
||||
} else {
|
||||
super.setRelationsInViewModel(model, viewModel, relation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to get the content object (as a view model) from the given model and relation.
|
||||
*/
|
||||
protected getContentObject(model: M, relation: GenericRelationDefinition): BaseViewModel {
|
||||
const contentObject = this.viewModelStoreService.get<BaseViewModel>(
|
||||
model.content_object.collection,
|
||||
model.content_object.id
|
||||
);
|
||||
if (!contentObject || !relation.isVForeign(contentObject)) {
|
||||
return null;
|
||||
}
|
||||
return contentObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object with has the given content object as the content object.
|
||||
*
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { BaseModel, ModelConstructor } from 'app/shared/models/base/base-model';
|
||||
import { BaseModel } from 'app/shared/models/base/base-model';
|
||||
import { ViewItem } from 'app/site/agenda/models/view-item';
|
||||
import { ViewListOfSpeakers } from 'app/site/agenda/models/view-list-of-speakers';
|
||||
import { BaseProjectableViewModel } from 'app/site/base/base-projectable-view-model';
|
||||
@ -17,11 +15,7 @@ import {
|
||||
IBaseIsListOfSpeakersContentObjectRepository,
|
||||
isBaseIsListOfSpeakersContentObjectRepository
|
||||
} from './base-is-list-of-speakers-content-object-repository';
|
||||
import { BaseRepository, RelationDefinition } from './base-repository';
|
||||
import { CollectionStringMapperService } from '../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../core-services/data-send.service';
|
||||
import { DataStoreService } from '../core-services/data-store.service';
|
||||
import { ViewModelStoreService } from '../core-services/view-model-store.service';
|
||||
import { BaseRepository } from './base-repository';
|
||||
|
||||
export function isBaseIsAgendaItemAndListOfSpeakersContentObjectRepository(
|
||||
obj: any
|
||||
@ -43,35 +37,15 @@ export abstract class BaseIsAgendaItemAndListOfSpeakersContentObjectRepository<
|
||||
implements
|
||||
IBaseIsAgendaItemContentObjectRepository<V, M, T>,
|
||||
IBaseIsListOfSpeakersContentObjectRepository<V, M, T> {
|
||||
public constructor(
|
||||
DS: DataStoreService,
|
||||
dataSend: DataSendService,
|
||||
collectionStringMapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
baseModelCtor: ModelConstructor<M>,
|
||||
relationDefinitions?: RelationDefinition[]
|
||||
) {
|
||||
super(
|
||||
DS,
|
||||
dataSend,
|
||||
collectionStringMapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
baseModelCtor,
|
||||
relationDefinitions
|
||||
);
|
||||
}
|
||||
|
||||
protected groupRelationsByCollections(): void {
|
||||
this.relationDefinitions.push({
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'agenda_item_id',
|
||||
ownKey: 'item',
|
||||
foreignModel: ViewItem
|
||||
});
|
||||
this.relationDefinitions.push({
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'list_of_speakers_id',
|
||||
ownKey: 'list_of_speakers',
|
||||
foreignModel: ViewListOfSpeakers
|
||||
|
@ -6,10 +6,12 @@ import {
|
||||
TitleInformationWithAgendaItem
|
||||
} from 'app/site/base/base-view-model-with-agenda-item';
|
||||
import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model';
|
||||
import { BaseRepository, RelationDefinition } from './base-repository';
|
||||
import { BaseRepository } from './base-repository';
|
||||
import { CollectionStringMapperService } from '../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../core-services/data-send.service';
|
||||
import { DataStoreService } from '../core-services/data-store.service';
|
||||
import { RelationManagerService } from '../core-services/relation-manager.service';
|
||||
import { RelationDefinition } from '../definitions/relations';
|
||||
import { ViewModelStoreService } from '../core-services/view-model-store.service';
|
||||
|
||||
export function isBaseIsAgendaItemContentObjectRepository(
|
||||
@ -45,6 +47,7 @@ export abstract class BaseIsAgendaItemContentObjectRepository<
|
||||
collectionStringMapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
baseModelCtor: ModelConstructor<M>,
|
||||
relationDefinitions?: RelationDefinition[]
|
||||
) {
|
||||
@ -54,6 +57,7 @@ export abstract class BaseIsAgendaItemContentObjectRepository<
|
||||
collectionStringMapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
baseModelCtor,
|
||||
relationDefinitions
|
||||
);
|
||||
@ -61,7 +65,7 @@ export abstract class BaseIsAgendaItemContentObjectRepository<
|
||||
|
||||
protected groupRelationsByCollections(): void {
|
||||
this.relationDefinitions.push({
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'agenda_item_id',
|
||||
ownKey: 'item',
|
||||
foreignModel: ViewItem
|
||||
|
@ -3,11 +3,13 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { ViewListOfSpeakers } from 'app/site/agenda/models/view-list-of-speakers';
|
||||
import { BaseViewModelWithListOfSpeakers } from 'app/site/base/base-view-model-with-list-of-speakers';
|
||||
import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model';
|
||||
import { BaseRepository, RelationDefinition } from './base-repository';
|
||||
import { BaseRepository } from './base-repository';
|
||||
import { TitleInformation } from '../../site/base/base-view-model';
|
||||
import { CollectionStringMapperService } from '../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../core-services/data-send.service';
|
||||
import { DataStoreService } from '../core-services/data-store.service';
|
||||
import { RelationManagerService } from '../core-services/relation-manager.service';
|
||||
import { RelationDefinition } from '../definitions/relations';
|
||||
import { ViewModelStoreService } from '../core-services/view-model-store.service';
|
||||
|
||||
export function isBaseIsListOfSpeakersContentObjectRepository(
|
||||
@ -43,6 +45,7 @@ export abstract class BaseIsListOfSpeakersContentObjectRepository<
|
||||
collectionStringMapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
baseModelCtor: ModelConstructor<M>,
|
||||
relationDefinitions?: RelationDefinition[]
|
||||
) {
|
||||
@ -52,6 +55,7 @@ export abstract class BaseIsListOfSpeakersContentObjectRepository<
|
||||
collectionStringMapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
baseModelCtor,
|
||||
relationDefinitions
|
||||
);
|
||||
@ -59,7 +63,7 @@ export abstract class BaseIsListOfSpeakersContentObjectRepository<
|
||||
|
||||
protected groupRelationsByCollections(): void {
|
||||
this.relationDefinitions.push({
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'list_of_speakers_id',
|
||||
ownKey: 'list_of_speakers',
|
||||
foreignModel: ViewListOfSpeakers
|
||||
|
@ -9,92 +9,16 @@ import { CollectionStringMapperService } from '../core-services/collection-strin
|
||||
import { DataSendService } from '../core-services/data-send.service';
|
||||
import { CollectionIds, DataStoreService } from '../core-services/data-store.service';
|
||||
import { Identifiable } from '../../shared/models/base/identifiable';
|
||||
import { OnAfterAppsLoaded } from '../onAfterAppsLoaded';
|
||||
import { OnAfterAppsLoaded } from '../definitions/on-after-apps-loaded';
|
||||
import { RelationManagerService } from '../core-services/relation-manager.service';
|
||||
import {
|
||||
isNormalRelationDefinition,
|
||||
isReverseRelationDefinition,
|
||||
RelationDefinition,
|
||||
ReverseRelationDefinition
|
||||
} from '../definitions/relations';
|
||||
import { ViewModelStoreService } from '../core-services/view-model-store.service';
|
||||
|
||||
// All "standard" relations.
|
||||
export type RelationDefinition<VForeign extends BaseViewModel = BaseViewModel> =
|
||||
| NormalRelationDefinition<VForeign>
|
||||
| NestedRelationDefinition<VForeign>
|
||||
| CustomRelationDefinition<VForeign>;
|
||||
|
||||
/**
|
||||
* Normal relations.
|
||||
*/
|
||||
interface NormalRelationDefinition<VForeign extends BaseViewModel> {
|
||||
/**
|
||||
* - O2M: From this model to another one, where this model is the One-side.
|
||||
* E.g. motions<->categories: One motions has One category; One category has
|
||||
* Many motions
|
||||
* - M2M: M2M relation from this to another model.
|
||||
*/
|
||||
type: 'M2M' | 'O2M';
|
||||
|
||||
/**
|
||||
* The key where the id(s) are given. Must be present in the model and view model. E.g. `category_id`.
|
||||
*/
|
||||
ownIdKey: string;
|
||||
|
||||
/**
|
||||
* The name of the property, where the foreign view model should be accessable.
|
||||
* Note, that this must be a getter to a private variable `_<ownKey`!
|
||||
*
|
||||
* E.g. `category`. (private variable `_category`)
|
||||
*/
|
||||
ownKey: string;
|
||||
|
||||
/**
|
||||
* The model on the other side of the relation.
|
||||
*/
|
||||
foreignModel: ViewModelConstructor<VForeign>;
|
||||
|
||||
/**
|
||||
* TODO: reverse relations.
|
||||
*/
|
||||
foreignKey?: keyof VForeign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested relations in the REST-API. For the most values see
|
||||
* `NormalRelationDefinition`.
|
||||
*/
|
||||
interface NestedRelationDefinition<VForeign extends BaseViewModel> {
|
||||
type: 'nested';
|
||||
ownKey: string;
|
||||
foreignModel: ViewModelConstructor<VForeign>;
|
||||
foreignKey?: keyof VForeign;
|
||||
|
||||
/**
|
||||
* The nested relations.
|
||||
*/
|
||||
relationDefinition?: RelationDefinition[];
|
||||
|
||||
/**
|
||||
* Provide an extra key (holding a number) to order by.
|
||||
* If the value is equal or no order key is given, the models
|
||||
* will be sorted by id.
|
||||
*/
|
||||
order?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom relation with callbacks with things todo.
|
||||
*/
|
||||
interface CustomRelationDefinition<VForeign extends BaseViewModel> {
|
||||
type: 'custom';
|
||||
foreignModel: ViewModelConstructor<VForeign>;
|
||||
|
||||
/**
|
||||
* Called, when the view model is created from the model.
|
||||
*/
|
||||
setRelations: (model: BaseModel, viewModel: BaseViewModel) => void;
|
||||
|
||||
/**
|
||||
* Called, when the dependency was updated.
|
||||
*/
|
||||
updateDependency: (ownViewModel: BaseViewModel, foreignViewModel: VForeign) => boolean;
|
||||
}
|
||||
|
||||
export abstract class BaseRepository<V extends BaseViewModel & T, M extends BaseModel, T extends TitleInformation>
|
||||
implements OnAfterAppsLoaded, Collection {
|
||||
/**
|
||||
@ -163,6 +87,8 @@ export abstract class BaseRepository<V extends BaseViewModel & T, M extends Base
|
||||
*/
|
||||
protected relationsByCollection: { [collection: string]: RelationDefinition<BaseViewModel>[] } = {};
|
||||
|
||||
protected reverseRelationsByCollection: { [collection: string]: ReverseRelationDefinition<BaseViewModel>[] } = {};
|
||||
|
||||
/**
|
||||
* The view model ctor of the encapsulated view model.
|
||||
*/
|
||||
@ -183,12 +109,14 @@ export abstract class BaseRepository<V extends BaseViewModel & T, M extends Base
|
||||
protected collectionStringMapperService: CollectionStringMapperService,
|
||||
protected viewModelStoreService: ViewModelStoreService,
|
||||
protected translate: TranslateService,
|
||||
protected relationManager: RelationManagerService,
|
||||
protected baseModelCtor: ModelConstructor<M>,
|
||||
protected relationDefinitions: RelationDefinition<BaseViewModel>[] = []
|
||||
) {
|
||||
this._collectionString = baseModelCtor.COLLECTIONSTRING;
|
||||
|
||||
this.groupRelationsByCollections();
|
||||
this.buildReverseRelationsGrouping();
|
||||
|
||||
// All data is piped through an auditTime of 1ms. This is to prevent massive
|
||||
// updates, if e.g. an autoupdate with a lot motions come in. The result is just one
|
||||
@ -219,13 +147,37 @@ export abstract class BaseRepository<V extends BaseViewModel & T, M extends Base
|
||||
(relation.relationDefinition || []).forEach(nestedRelation => {
|
||||
this._groupRelationsByCollections(nestedRelation, baseRelation);
|
||||
});
|
||||
} else if (relation.type === 'O2M' || relation.type === 'M2M' || relation.type === 'custom') {
|
||||
} else if (
|
||||
relation.type === 'M2O' ||
|
||||
relation.type === 'M2M' ||
|
||||
relation.type === 'O2M' ||
|
||||
relation.type === 'custom'
|
||||
) {
|
||||
const collection = relation.foreignModel.COLLECTIONSTRING;
|
||||
if (!this.relationsByCollection[collection]) {
|
||||
this.relationsByCollection[collection] = [];
|
||||
}
|
||||
this.relationsByCollection[collection].push(baseRelation);
|
||||
} else if (relation.type === 'generic') {
|
||||
relation.possibleModels.forEach(ctor => {
|
||||
const collection = ctor.COLLECTIONSTRING;
|
||||
if (!this.relationsByCollection[collection]) {
|
||||
this.relationsByCollection[collection] = [];
|
||||
}
|
||||
this.relationsByCollection[collection].push(baseRelation);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected buildReverseRelationsGrouping(): void {
|
||||
Object.keys(this.relationsByCollection).forEach(collection => {
|
||||
const reverseRelations = this.relationsByCollection[collection].filter(relation =>
|
||||
isReverseRelationDefinition(relation)
|
||||
) as ReverseRelationDefinition<BaseViewModel>[];
|
||||
if (reverseRelations.length) {
|
||||
this.reverseRelationsByCollection[collection] = reverseRelations;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public onAfterAppsLoaded(): void {
|
||||
@ -274,82 +226,27 @@ export abstract class BaseRepository<V extends BaseViewModel & T, M extends Base
|
||||
* are assigned to the new view model.
|
||||
*/
|
||||
protected createViewModelWithTitles(model: M): V {
|
||||
const viewModel = this.createViewModel(model, this.baseViewModelCtor, this.relationDefinitions);
|
||||
const viewModel = this.relationManager.createViewModel(model, this.baseViewModelCtor, this.relationDefinitions);
|
||||
viewModel.getTitle = () => this.getTitle(viewModel);
|
||||
viewModel.getListTitle = () => this.getListTitle(viewModel);
|
||||
viewModel.getVerboseName = this.getVerboseName;
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a view model from the given model and model ctor. All dependencies will be
|
||||
* set accorting to relations.
|
||||
*/
|
||||
protected createViewModel<K extends BaseViewModel = V>(
|
||||
model: M,
|
||||
modelCtor: ViewModelConstructor<K>,
|
||||
relations: RelationDefinition[]
|
||||
): K {
|
||||
const viewModel = new modelCtor(model) as K;
|
||||
|
||||
// no reverse setting needed
|
||||
relations.forEach(relation => {
|
||||
this.setRelationsInViewModel(model, viewModel, relation);
|
||||
});
|
||||
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets one foreign view model in the view model according to the relation and the information
|
||||
* from the model.
|
||||
*/
|
||||
protected setRelationsInViewModel<K extends BaseViewModel = V>(
|
||||
model: M,
|
||||
viewModel: K,
|
||||
relation: RelationDefinition
|
||||
): void {
|
||||
if (relation.type === 'M2M' && model[relation.ownIdKey] instanceof Array) {
|
||||
const foreignViewModels = this.viewModelStoreService.getMany(
|
||||
relation.foreignModel,
|
||||
model[relation.ownIdKey]
|
||||
);
|
||||
viewModel['_' + relation.ownKey] = foreignViewModels;
|
||||
} else if (relation.type === 'O2M') {
|
||||
const foreignViewModel = this.viewModelStoreService.get(relation.foreignModel, model[relation.ownIdKey]);
|
||||
viewModel['_' + relation.ownKey] = foreignViewModel;
|
||||
} else if (relation.type === 'nested') {
|
||||
const foreignViewModels: BaseViewModel[] = model[relation.ownKey].map(foreignModel =>
|
||||
this.createViewModel(foreignModel, relation.foreignModel, relation.relationDefinition || [])
|
||||
);
|
||||
foreignViewModels.sort((a: BaseViewModel, b: BaseViewModel) => {
|
||||
const order = relation.order;
|
||||
if (!relation.order || a[order] === b[order]) {
|
||||
return a.id - b.id;
|
||||
} else {
|
||||
return a[order] - b[order];
|
||||
}
|
||||
});
|
||||
viewModel['_' + relation.ownKey] = foreignViewModels;
|
||||
} else if (relation.type === 'custom') {
|
||||
relation.setRelations(model, viewModel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all models in this repository with all changed models.
|
||||
*
|
||||
* @param changedModels A mapping of collections to ids of all changed models.
|
||||
* @returns if at least one model was affected.
|
||||
*/
|
||||
public updateDependencies(changedModels: CollectionIds): boolean {
|
||||
public updateDependenciesForChangedModels(changedModels: CollectionIds): boolean {
|
||||
if (!this.relationDefinitions.length) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get all viewModels from this repo once.
|
||||
const viewModels = this.getViewModelList();
|
||||
let somethingUpdated = false;
|
||||
const ownViewModels = this.getViewModelList();
|
||||
const updatedIds = [];
|
||||
Object.keys(changedModels).forEach(collection => {
|
||||
const dependencyChanged: boolean = Object.keys(this.relationsByCollection).includes(collection);
|
||||
if (!dependencyChanged) {
|
||||
@ -357,87 +254,81 @@ export abstract class BaseRepository<V extends BaseViewModel & T, M extends Base
|
||||
}
|
||||
|
||||
// Ok, we are affected by this collection. Update all viewModels from this repo.
|
||||
viewModels.forEach(ownViewModel => {
|
||||
const relations = this.relationsByCollection[collection];
|
||||
if (!relations || !relations.length) {
|
||||
return;
|
||||
}
|
||||
ownViewModels.forEach(ownViewModel => {
|
||||
relations.forEach(relation => {
|
||||
changedModels[collection].forEach(id => {
|
||||
if (this.updateSingleDependency(ownViewModel, relation, collection, id)) {
|
||||
somethingUpdated = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
if (somethingUpdated) {
|
||||
viewModels.forEach(ownViewModel => {
|
||||
this.updateViewModelObservable(ownViewModel.id);
|
||||
});
|
||||
}
|
||||
return somethingUpdated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an own view model with an implicit given model by the collection and changedId.
|
||||
*
|
||||
* @return true, if something was updated.
|
||||
*/
|
||||
protected updateSingleDependency(
|
||||
ownViewModel: BaseViewModel,
|
||||
relation: RelationDefinition,
|
||||
collection: string,
|
||||
changedId: number
|
||||
): boolean {
|
||||
if (relation.type === 'M2M') {
|
||||
if (
|
||||
ownViewModel[relation.ownIdKey] &&
|
||||
ownViewModel[relation.ownIdKey] instanceof Array &&
|
||||
ownViewModel[relation.ownIdKey].includes(changedId)
|
||||
this.relationManager.updateSingleDependencyForChangedModel(
|
||||
ownViewModel,
|
||||
relation,
|
||||
collection,
|
||||
id
|
||||
)
|
||||
) {
|
||||
const foreignViewModel = <any>this.viewModelStoreService.get(collection, changedId);
|
||||
let ownModelArray = <any>ownViewModel['_' + relation.ownKey];
|
||||
if (!ownModelArray) {
|
||||
ownViewModel['_' + relation.ownKey] = [];
|
||||
ownModelArray = <any>ownViewModel['_' + relation.ownKey];
|
||||
}
|
||||
const index = ownModelArray.findIndex(user => user.id === changedId);
|
||||
if (index < 0) {
|
||||
ownModelArray.push(foreignViewModel);
|
||||
} else {
|
||||
ownModelArray[index] = foreignViewModel;
|
||||
}
|
||||
// TODO: set reverse
|
||||
|
||||
return true;
|
||||
}
|
||||
} else if (relation.type === 'O2M') {
|
||||
if (ownViewModel[relation.ownIdKey] === <any>changedId) {
|
||||
ownViewModel['_' + relation.ownKey] = <any>this.viewModelStoreService.get(collection, changedId);
|
||||
// TODO: set reverse
|
||||
|
||||
return true;
|
||||
}
|
||||
} else if (relation.type === 'nested') {
|
||||
let updated = false;
|
||||
(relation.relationDefinition || []).forEach(nestedRelation => {
|
||||
const nestedViewModels = ownViewModel[relation.ownKey] as BaseViewModel[];
|
||||
nestedViewModels.forEach(nestedViewModel => {
|
||||
if (this.updateSingleDependency(nestedViewModel, nestedRelation, collection, changedId)) {
|
||||
updated = true;
|
||||
updatedIds.push(ownViewModel.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
return updated;
|
||||
} else if (relation.type === 'custom') {
|
||||
const foreignViewModel = <any>this.viewModelStoreService.get(collection, changedId);
|
||||
return relation.updateDependency(ownViewModel, foreignViewModel);
|
||||
});
|
||||
// Order all relations, if neeed.
|
||||
if (updatedIds.length) {
|
||||
relations.forEach(relation => {
|
||||
if (
|
||||
(isNormalRelationDefinition(relation) || isReverseRelationDefinition(relation)) &&
|
||||
(relation.type === 'M2M' || relation.type === 'O2M') &&
|
||||
relation.order
|
||||
) {
|
||||
ownViewModels.forEach(ownViewModel => {
|
||||
if (ownViewModel['_' + relation.ownKey]) {
|
||||
this.relationManager.sortByRelation(relation, ownViewModel);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Inform about changes. (List updates is done in `commitUpdate` via `DataStoreUpdateManagerService`)
|
||||
updatedIds.forEach(id => {
|
||||
this.updateViewModelObservable(id);
|
||||
});
|
||||
});
|
||||
return !!updatedIds.length;
|
||||
}
|
||||
|
||||
public updateDependenciesForDeletedModels(deletedModels: CollectionIds): boolean {
|
||||
if (!Object.keys(this.reverseRelationsByCollection).length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get all viewModels from this repo once.
|
||||
const ownViewModels = this.getViewModelList();
|
||||
let somethingChanged = false;
|
||||
Object.keys(deletedModels).forEach(collection => {
|
||||
const dependencyChanged: boolean = Object.keys(this.reverseRelationsByCollection).includes(collection);
|
||||
if (!dependencyChanged) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ok, we are affected by this collection. Update all viewModels from this repo.
|
||||
const relations = this.reverseRelationsByCollection[collection];
|
||||
ownViewModels.forEach(ownViewModel => {
|
||||
relations.forEach(relation => {
|
||||
deletedModels[collection].forEach(id => {
|
||||
if (this.relationManager.updateSingleDependencyForDeletedModel(ownViewModel, relation, id)) {
|
||||
// Inform about changes. (List updates is done in `commitUpdate` via `DataStoreUpdateManagerService`)
|
||||
this.updateViewModelObservable(id);
|
||||
somethingChanged = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
// Ordering all relations is not needed, because just deleting things out of arrays
|
||||
// will not unorder them.
|
||||
});
|
||||
return somethingChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the (full) update to an existing model. So called "update"-function
|
||||
* Provides a default procedure, but can be overwritten if required
|
||||
|
@ -8,6 +8,7 @@ import { ConstantsService } from 'app/core/core-services/constants.service';
|
||||
import { DataSendService } from 'app/core/core-services/data-send.service';
|
||||
import { DataStoreService } from 'app/core/core-services/data-store.service';
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { BaseRepository } from 'app/core/repositories/base-repository';
|
||||
import { Identifiable } from 'app/shared/models/base/identifiable';
|
||||
@ -112,10 +113,11 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private constantsService: ConstantsService,
|
||||
private http: HttpService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Config);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, Config);
|
||||
|
||||
this.constantsService.get('ConfigVariables').subscribe(constant => {
|
||||
this.createConfigStructure(constant);
|
||||
|
@ -7,19 +7,20 @@ import { first, map } from 'rxjs/operators';
|
||||
|
||||
import { DataSendService } from 'app/core/core-services/data-send.service';
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { Identifiable } from 'app/shared/models/base/identifiable';
|
||||
import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
|
||||
import { MediafileTitleInformation, ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
|
||||
import { ViewGroup } from 'app/site/users/models/view-group';
|
||||
import { BaseIsListOfSpeakersContentObjectRepository } from '../base-is-list-of-speakers-content-object-repository';
|
||||
import { RelationDefinition } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataStoreService } from '../../core-services/data-store.service';
|
||||
|
||||
const MediafileRelations: RelationDefinition[] = [
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'parent_id',
|
||||
ownKey: 'parent',
|
||||
foreignModel: ViewMediafile
|
||||
@ -64,9 +65,19 @@ export class MediafileRepositoryService extends BaseIsListOfSpeakersContentObjec
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
dataSend: DataSendService,
|
||||
relationManager: RelationManagerService,
|
||||
private httpService: HttpService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Mediafile, MediafileRelations);
|
||||
super(
|
||||
DS,
|
||||
dataSend,
|
||||
mapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
Mediafile,
|
||||
MediafileRelations
|
||||
);
|
||||
this.directoryBehaviorSubject = new BehaviorSubject([]);
|
||||
this.getViewModelListObservable().subscribe(mediafiles => {
|
||||
if (mediafiles) {
|
||||
|
@ -2,12 +2,14 @@ import { Injectable } from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { TreeIdNode } from 'app/core/ui-services/tree.service';
|
||||
import { Category } from 'app/shared/models/motions/category';
|
||||
import { Motion } from 'app/shared/models/motions/motion';
|
||||
import { CategoryTitleInformation, ViewCategory } from 'app/site/motions/models/view-category';
|
||||
import { BaseRepository, RelationDefinition } from '../base-repository';
|
||||
import { ViewMotion } from 'app/site/motions/models/view-motion';
|
||||
import { BaseRepository } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../../core-services/data-send.service';
|
||||
import { DataStoreService } from '../../core-services/data-store.service';
|
||||
@ -15,10 +17,24 @@ import { HttpService } from '../../core-services/http.service';
|
||||
|
||||
const CategoryRelations: RelationDefinition[] = [
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'parent_id',
|
||||
ownKey: 'parent',
|
||||
foreignModel: ViewCategory
|
||||
},
|
||||
{
|
||||
type: 'O2M',
|
||||
foreignIdKey: 'category_id',
|
||||
ownKey: 'motions',
|
||||
foreignModel: ViewMotion,
|
||||
order: 'category_weight'
|
||||
},
|
||||
{
|
||||
type: 'O2M',
|
||||
foreignIdKey: 'parent_id',
|
||||
ownKey: 'children',
|
||||
foreignModel: ViewCategory,
|
||||
order: 'weight'
|
||||
}
|
||||
];
|
||||
|
||||
@ -54,9 +70,19 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private httpService: HttpService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Category, CategoryRelations);
|
||||
super(
|
||||
DS,
|
||||
dataSend,
|
||||
mapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
Category,
|
||||
CategoryRelations
|
||||
);
|
||||
|
||||
this.setSortFunction((a, b) => a.weight - b.weight);
|
||||
}
|
||||
@ -98,14 +124,4 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
|
||||
public async sortCategories(data: TreeIdNode[]): Promise<void> {
|
||||
await this.httpService.post('/rest/motions/category/sort_categories/', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the DataStore by Motions and returns the amount of motions in the given category
|
||||
*
|
||||
* @param category the category
|
||||
* @returns the number of motions inside the category
|
||||
*/
|
||||
public getMotionAmountByCategory(category: ViewCategory): number {
|
||||
return this.DS.filter(Motion, motion => motion.category_id === category.id).length;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import { map } from 'rxjs/operators';
|
||||
import { CollectionStringMapperService } from 'app/core/core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from 'app/core/core-services/data-send.service';
|
||||
import { DataStoreService } from 'app/core/core-services/data-store.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { Identifiable } from 'app/shared/models/base/identifiable';
|
||||
import { MotionChangeRecommendation } from 'app/shared/models/motions/motion-change-reco';
|
||||
@ -56,9 +57,18 @@ export class ChangeRecommendationRepositoryService extends BaseRepository<
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private diffService: DiffService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, MotionChangeRecommendation);
|
||||
super(
|
||||
DS,
|
||||
dataSend,
|
||||
mapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
MotionChangeRecommendation
|
||||
);
|
||||
}
|
||||
|
||||
public getTitle = (titleInformation: MotionChangeRecommendationTitleInformation) => {
|
||||
|
@ -1,21 +1,29 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { CollectionStringMapperService } from 'app/core/core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from 'app/core/core-services/data-send.service';
|
||||
import { DataStoreService } from 'app/core/core-services/data-store.service';
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { Motion } from 'app/shared/models/motions/motion';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { MotionBlock } from 'app/shared/models/motions/motion-block';
|
||||
import { ViewMotion } from 'app/site/motions/models/view-motion';
|
||||
import { MotionBlockTitleInformation, ViewMotionBlock } from 'app/site/motions/models/view-motion-block';
|
||||
import { BaseIsAgendaItemAndListOfSpeakersContentObjectRepository } from '../base-is-agenda-item-and-list-of-speakers-content-object-repository';
|
||||
import { MotionRepositoryService } from './motion-repository.service';
|
||||
|
||||
const MotionBlockRelations: RelationDefinition[] = [
|
||||
{
|
||||
type: 'O2M',
|
||||
foreignIdKey: 'motion_block_id',
|
||||
ownKey: 'motions',
|
||||
foreignModel: ViewMotion
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* Repository service for motion blocks
|
||||
*/
|
||||
@ -42,10 +50,20 @@ export class MotionBlockRepositoryService extends BaseIsAgendaItemAndListOfSpeak
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private motionRepo: MotionRepositoryService,
|
||||
private httpService: HttpService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, MotionBlock);
|
||||
super(
|
||||
DS,
|
||||
dataSend,
|
||||
mapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
MotionBlock,
|
||||
MotionBlockRelations
|
||||
);
|
||||
this.initSorting();
|
||||
}
|
||||
|
||||
@ -68,29 +86,6 @@ export class MotionBlockRepositoryService extends BaseIsAgendaItemAndListOfSpeak
|
||||
this.motionRepo.update(updateMotion, viewMotion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the DataStore by Motions and returns the
|
||||
*
|
||||
* @param block the motion block
|
||||
* @returns the number of motions inside a motion block
|
||||
*/
|
||||
public getMotionAmountByBlock(block: MotionBlock): number {
|
||||
return this.DS.filter(Motion, motion => motion.motion_block_id === block.id).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe the motion repository and return the motions belonging to the given
|
||||
* block as observable
|
||||
*
|
||||
* @param block a motion block
|
||||
* @returns an observable to view motions
|
||||
*/
|
||||
public getViewMotionsByBlock(block: MotionBlock): Observable<ViewMotion[]> {
|
||||
return this.motionRepo
|
||||
.getViewModelListObservable()
|
||||
.pipe(map(viewMotions => viewMotions.filter(viewMotion => viewMotion.motion_block_id === block.id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves motion blocks by name
|
||||
*
|
||||
|
@ -3,7 +3,9 @@ import { Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { MotionCommentSection } from 'app/shared/models/motions/motion-comment-section';
|
||||
import { ViewMotion } from 'app/site/motions/models/view-motion';
|
||||
import {
|
||||
@ -11,7 +13,7 @@ import {
|
||||
ViewMotionCommentSection
|
||||
} from 'app/site/motions/models/view-motion-comment-section';
|
||||
import { ViewGroup } from 'app/site/users/models/view-group';
|
||||
import { BaseRepository, RelationDefinition } from '../base-repository';
|
||||
import { BaseRepository } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../../core-services/data-send.service';
|
||||
import { DataStoreService } from '../../core-services/data-store.service';
|
||||
@ -65,6 +67,7 @@ export class MotionCommentSectionRepositoryService extends BaseRepository<
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private http: HttpService
|
||||
) {
|
||||
super(
|
||||
@ -73,6 +76,7 @@ export class MotionCommentSectionRepositoryService extends BaseRepository<
|
||||
mapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
MotionCommentSection,
|
||||
MotionCommentSectionRelations
|
||||
);
|
||||
|
@ -8,7 +8,9 @@ import { map } from 'rxjs/operators';
|
||||
import { DataStoreService } from 'app/core/core-services/data-store.service';
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { OperatorService } from 'app/core/core-services/operator.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { DiffLinesInParagraph, DiffService } from 'app/core/ui-services/diff.service';
|
||||
import { TreeIdNode } from 'app/core/ui-services/tree.service';
|
||||
@ -30,7 +32,6 @@ import { ViewTag } from 'app/site/tags/models/view-tag';
|
||||
import { ViewPersonalNote } from 'app/site/users/models/view-personal-note';
|
||||
import { ViewUser } from 'app/site/users/models/view-user';
|
||||
import { BaseIsAgendaItemAndListOfSpeakersContentObjectRepository } from '../base-is-agenda-item-and-list-of-speakers-content-object-repository';
|
||||
import { RelationDefinition } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../../core-services/data-send.service';
|
||||
import { LinenumberingService, LineNumberRange } from '../../ui-services/linenumbering.service';
|
||||
@ -69,31 +70,31 @@ export interface ParagraphToChoose {
|
||||
|
||||
const MotionRelations: RelationDefinition[] = [
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'state_id',
|
||||
ownKey: 'state',
|
||||
foreignModel: ViewState
|
||||
},
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'recommendation_id',
|
||||
ownKey: 'recommendation',
|
||||
foreignModel: ViewState
|
||||
},
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'workflow_id',
|
||||
ownKey: 'workflow',
|
||||
foreignModel: ViewWorkflow
|
||||
},
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'category_id',
|
||||
ownKey: 'category',
|
||||
foreignModel: ViewCategory
|
||||
},
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'motion_block_id',
|
||||
ownKey: 'motion_block',
|
||||
foreignModel: ViewMotionBlock
|
||||
@ -105,7 +106,7 @@ const MotionRelations: RelationDefinition[] = [
|
||||
order: 'weight',
|
||||
relationDefinition: [
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'user_id',
|
||||
ownKey: 'user',
|
||||
foreignModel: ViewUser
|
||||
@ -131,7 +132,7 @@ const MotionRelations: RelationDefinition[] = [
|
||||
foreignModel: ViewTag
|
||||
},
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'parent_id',
|
||||
ownKey: 'parent',
|
||||
foreignModel: ViewMotion
|
||||
@ -190,6 +191,7 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
config: ConfigService,
|
||||
private httpService: HttpService,
|
||||
private readonly sanitizer: DomSanitizer,
|
||||
@ -197,7 +199,7 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
|
||||
private readonly diff: DiffService,
|
||||
private operator: OperatorService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Motion, MotionRelations);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, Motion, MotionRelations);
|
||||
config.get<SortProperty>('motions_motions_sorting').subscribe(conf => {
|
||||
this.sortProperty = conf;
|
||||
this.setConfigSortFn();
|
||||
|
@ -2,18 +2,20 @@ import { Injectable } from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { State } from 'app/shared/models/motions/state';
|
||||
import { StateTitleInformation, ViewState } from 'app/site/motions/models/view-state';
|
||||
import { ViewWorkflow, WorkflowTitleInformation } from 'app/site/motions/models/view-workflow';
|
||||
import { BaseRepository, RelationDefinition } from '../base-repository';
|
||||
import { BaseRepository } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../../core-services/data-send.service';
|
||||
import { DataStoreService } from '../../core-services/data-store.service';
|
||||
|
||||
const StateRelations: RelationDefinition[] = [
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'workflow_id',
|
||||
ownKey: 'workflow',
|
||||
foreignModel: ViewWorkflow
|
||||
@ -54,9 +56,10 @@ export class StateRepositoryService extends BaseRepository<ViewState, State, Sta
|
||||
dataSend: DataSendService,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, State, StateRelations);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, State, StateRelations);
|
||||
}
|
||||
|
||||
public getTitle = (titleInformation: WorkflowTitleInformation) => {
|
||||
|
@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { StatuteParagraph } from 'app/shared/models/motions/statute-paragraph';
|
||||
import { StatuteParagraphTitleInformation, ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph';
|
||||
@ -39,9 +40,10 @@ export class StatuteParagraphRepositoryService extends BaseRepository<
|
||||
dataSend: DataSendService,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, StatuteParagraph);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, StatuteParagraph);
|
||||
}
|
||||
|
||||
public getTitle = (titleInformation: StatuteParagraphTitleInformation) => {
|
||||
|
@ -2,12 +2,14 @@ import { Injectable } from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { Workflow } from 'app/shared/models/motions/workflow';
|
||||
import { ViewMotion } from 'app/site/motions/models/view-motion';
|
||||
import { ViewState } from 'app/site/motions/models/view-state';
|
||||
import { ViewWorkflow, WorkflowTitleInformation } from 'app/site/motions/models/view-workflow';
|
||||
import { BaseRepository, RelationDefinition } from '../base-repository';
|
||||
import { BaseRepository } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../../core-services/data-send.service';
|
||||
import { DataStoreService } from '../../core-services/data-store.service';
|
||||
@ -20,7 +22,7 @@ const WorkflowRelations: RelationDefinition[] = [
|
||||
foreignModel: ViewState
|
||||
},
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'first_state_id',
|
||||
ownKey: 'first_state',
|
||||
foreignModel: ViewState
|
||||
@ -55,9 +57,19 @@ export class WorkflowRepositoryService extends BaseRepository<ViewWorkflow, Work
|
||||
dataSend: DataSendService,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Workflow, WorkflowRelations);
|
||||
super(
|
||||
DS,
|
||||
dataSend,
|
||||
mapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
Workflow,
|
||||
WorkflowRelations
|
||||
);
|
||||
}
|
||||
|
||||
public getTitle = (titleInformation: WorkflowTitleInformation) => {
|
||||
|
@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ServertimeService } from 'app/core/core-services/servertime.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { Countdown } from 'app/shared/models/core/countdown';
|
||||
@ -21,9 +22,10 @@ export class CountdownRepositoryService extends BaseRepository<ViewCountdown, Co
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private servertimeService: ServertimeService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Countdown);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, Countdown);
|
||||
}
|
||||
|
||||
public getTitle = (titleInformation: CountdownTitleInformation) => {
|
||||
|
@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { Identifiable } from 'app/shared/models/base/identifiable';
|
||||
import { ProjectionDefault } from 'app/shared/models/core/projection-default';
|
||||
@ -39,9 +40,10 @@ export class ProjectionDefaultRepositoryService extends BaseRepository<
|
||||
dataSend: DataSendService,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, ProjectionDefault);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, ProjectionDefault);
|
||||
}
|
||||
|
||||
public getVerboseName = (plural: boolean = false) => {
|
||||
|
@ -3,6 +3,7 @@ import { Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { DataSendService } from 'app/core/core-services/data-send.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { ProjectorMessage } from 'app/shared/models/core/projector-message';
|
||||
import {
|
||||
@ -26,9 +27,10 @@ export class ProjectorMessageRepositoryService extends BaseRepository<
|
||||
dataSend: DataSendService,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, ProjectorMessage);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, ProjectorMessage);
|
||||
}
|
||||
|
||||
public getTitle = (titleInformation: ProjectorMessageTitleInformation) => {
|
||||
|
@ -3,11 +3,13 @@ import { Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { Identifiable } from 'app/shared/models/base/identifiable';
|
||||
import { Projector } from 'app/shared/models/core/projector';
|
||||
import { ProjectorTitleInformation, ViewProjector } from 'app/site/projector/models/view-projector';
|
||||
import { BaseRepository, RelationDefinition } from '../base-repository';
|
||||
import { BaseRepository } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../../core-services/data-send.service';
|
||||
import { DataStoreService } from '../../core-services/data-store.service';
|
||||
@ -23,7 +25,7 @@ export enum ScrollScaleDirection {
|
||||
|
||||
const ProjectorRelations: RelationDefinition[] = [
|
||||
{
|
||||
type: 'O2M',
|
||||
type: 'M2O',
|
||||
ownIdKey: 'reference_projector_id',
|
||||
ownKey: 'referenceProjector',
|
||||
foreignModel: ViewProjector
|
||||
@ -51,9 +53,19 @@ export class ProjectorRepositoryService extends BaseRepository<ViewProjector, Pr
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private http: HttpService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Projector, ProjectorRelations);
|
||||
super(
|
||||
DS,
|
||||
dataSend,
|
||||
mapperService,
|
||||
viewModelStoreService,
|
||||
translate,
|
||||
relationManager,
|
||||
Projector,
|
||||
ProjectorRelations
|
||||
);
|
||||
}
|
||||
|
||||
public getTitle = (titleInformation: ProjectorTitleInformation) => {
|
||||
|
@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { Tag } from 'app/shared/models/core/tag';
|
||||
import { TagTitleInformation, ViewTag } from 'app/site/tags/models/view-tag';
|
||||
@ -38,9 +39,10 @@ export class TagRepositoryService extends BaseRepository<ViewTag, Tag, TagTitleI
|
||||
dataSend: DataSendService,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Tag);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, Tag);
|
||||
this.initSorting();
|
||||
}
|
||||
|
||||
|
@ -5,12 +5,13 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { CollectionStringMapperService } from 'app/core/core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from 'app/core/core-services/data-send.service';
|
||||
import { DataStoreService } from 'app/core/core-services/data-store.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { Topic } from 'app/shared/models/topics/topic';
|
||||
import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
|
||||
import { TopicTitleInformation, ViewTopic } from 'app/site/topics/models/view-topic';
|
||||
import { BaseIsAgendaItemAndListOfSpeakersContentObjectRepository } from '../base-is-agenda-item-and-list-of-speakers-content-object-repository';
|
||||
import { RelationDefinition } from '../base-repository';
|
||||
|
||||
const TopicRelations: RelationDefinition[] = [
|
||||
{
|
||||
@ -44,9 +45,10 @@ export class TopicRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCon
|
||||
dataSend: DataSendService,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Topic, TopicRelations);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, Topic, TopicRelations);
|
||||
}
|
||||
|
||||
public getTitle = (titleInformation: TopicTitleInformation) => {
|
||||
|
@ -3,6 +3,7 @@ import { Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { Group } from 'app/shared/models/users/group';
|
||||
import { GroupTitleInformation, ViewGroup } from 'app/site/users/models/view-group';
|
||||
@ -55,10 +56,11 @@ export class GroupRepositoryService extends BaseRepository<ViewGroup, Group, Gro
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService,
|
||||
private constantsService: ConstantsService,
|
||||
private http: HttpService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, Group);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, Group);
|
||||
this.sortPermsPerApp();
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ import { Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { DataSendService } from 'app/core/core-services/data-send.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { Identifiable } from 'app/shared/models/base/identifiable';
|
||||
import { PersonalNote } from 'app/shared/models/users/personal-note';
|
||||
@ -30,9 +31,10 @@ export class PersonalNoteRepositoryService extends BaseRepository<
|
||||
dataSend: DataSendService,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
translate: TranslateService
|
||||
translate: TranslateService,
|
||||
relationManager: RelationManagerService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, PersonalNote);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, PersonalNote);
|
||||
}
|
||||
|
||||
public getTitle = (titleInformation: PersonalNoteTitleInformation) => {
|
||||
|
@ -3,13 +3,15 @@ import { Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { HttpService } from 'app/core/core-services/http.service';
|
||||
import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { RelationDefinition } from 'app/core/definitions/relations';
|
||||
import { NewEntry } from 'app/core/ui-services/base-import.service';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { User } from 'app/shared/models/users/user';
|
||||
import { ViewGroup } from 'app/site/users/models/view-group';
|
||||
import { UserTitleInformation, ViewUser } from 'app/site/users/models/view-user';
|
||||
import { BaseRepository, RelationDefinition } from '../base-repository';
|
||||
import { BaseRepository } from '../base-repository';
|
||||
import { CollectionStringMapperService } from '../../core-services/collection-string-mapper.service';
|
||||
import { DataSendService } from '../../core-services/data-send.service';
|
||||
import { DataStoreService } from '../../core-services/data-store.service';
|
||||
@ -61,11 +63,12 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User, UserTi
|
||||
dataSend: DataSendService,
|
||||
mapperService: CollectionStringMapperService,
|
||||
viewModelStoreService: ViewModelStoreService,
|
||||
relationManager: RelationManagerService,
|
||||
protected translate: TranslateService,
|
||||
private httpService: HttpService,
|
||||
private configService: ConfigService
|
||||
) {
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, User, UserRelations);
|
||||
super(DS, dataSend, mapperService, viewModelStoreService, translate, relationManager, User, UserRelations);
|
||||
this.sortProperty = this.configService.instant('users_sort_by');
|
||||
this.configService.get<SortProperty>('users_sort_by').subscribe(conf => {
|
||||
this.sortProperty = conf;
|
||||
|
@ -6,4 +6,8 @@ import { ContentObject } from './content-object';
|
||||
*/
|
||||
export abstract class BaseModelWithContentObject<T = object> extends BaseModel<T> {
|
||||
public abstract content_object: ContentObject;
|
||||
|
||||
public get contentObjectData(): ContentObject {
|
||||
return this.content_object;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
|
||||
import { ListOfSpeakersRepositoryService } from 'app/core/repositories/agenda/list-of-speakers-repository.service';
|
||||
import { ListOfSpeakers } from 'app/shared/models/agenda/list-of-speakers';
|
||||
|
@ -12,6 +12,7 @@ export interface ItemTitleInformation {
|
||||
export class ViewItem extends BaseViewModelWithContentObject<Item, BaseViewModelWithAgendaItem>
|
||||
implements ItemTitleInformation {
|
||||
public static COLLECTIONSTRING = Item.COLLECTIONSTRING;
|
||||
protected _collectionString = Item.COLLECTIONSTRING;
|
||||
|
||||
public get item(): Item {
|
||||
return this._model;
|
||||
@ -83,8 +84,4 @@ export class ViewItem extends BaseViewModelWithContentObject<Item, BaseViewModel
|
||||
public get parent_id(): number {
|
||||
return this.item.parent_id;
|
||||
}
|
||||
|
||||
public constructor(item: Item) {
|
||||
super(Item.COLLECTIONSTRING, item);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { Item } from 'app/shared/models/agenda/item';
|
||||
import { ListOfSpeakers } from 'app/shared/models/agenda/list-of-speakers';
|
||||
import { ContentObject } from 'app/shared/models/base/content-object';
|
||||
import { BaseViewModelWithContentObject } from 'app/site/base/base-view-model-with-content-object';
|
||||
@ -18,6 +17,7 @@ export interface ListOfSpeakersTitleInformation {
|
||||
export class ViewListOfSpeakers extends BaseViewModelWithContentObject<ListOfSpeakers, BaseViewModelWithListOfSpeakers>
|
||||
implements ListOfSpeakersTitleInformation, Projectable {
|
||||
public static COLLECTIONSTRING = ListOfSpeakers.COLLECTIONSTRING;
|
||||
protected _collectionString = ListOfSpeakers.COLLECTIONSTRING;
|
||||
|
||||
private _speakers?: ViewSpeaker[];
|
||||
|
||||
@ -48,10 +48,6 @@ export class ViewListOfSpeakers extends BaseViewModelWithContentObject<ListOfSpe
|
||||
return `/agenda/speakers/${this.id}`;
|
||||
}
|
||||
|
||||
public constructor(listOfSpeakers: ListOfSpeakers) {
|
||||
super(Item.COLLECTIONSTRING, listOfSpeakers);
|
||||
}
|
||||
|
||||
public getProjectorTitle(): string {
|
||||
return this.getTitle();
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ export enum SpeakerState {
|
||||
*/
|
||||
export class ViewSpeaker extends BaseViewModel<Speaker> {
|
||||
public static COLLECTIONSTRING = Speaker.COLLECTIONSTRING;
|
||||
protected _collectionString = Speaker.COLLECTIONSTRING;
|
||||
|
||||
private _user?: ViewUser;
|
||||
|
||||
public get speaker(): Speaker {
|
||||
@ -80,10 +82,6 @@ export class ViewSpeaker extends BaseViewModel<Speaker> {
|
||||
return this.user ? this.user.gender : '';
|
||||
}
|
||||
|
||||
public constructor(speaker: Speaker) {
|
||||
super(Speaker.COLLECTIONSTRING, speaker);
|
||||
}
|
||||
|
||||
public getTitle = () => {
|
||||
return this.name;
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
import { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service';
|
||||
import { Assignment } from '../../shared/models/assignments/assignment';
|
||||
import { ViewAssignment } from './models/view-assignment';
|
||||
|
@ -10,6 +10,8 @@ const votesOrder: PollVoteValue[] = ['Votes', 'Yes', 'No', 'Abstain'];
|
||||
|
||||
export class ViewAssignmentPollOption extends BaseViewModel<AssignmentPollOption> {
|
||||
public static COLLECTIONSTRING = AssignmentPollOption.COLLECTIONSTRING;
|
||||
protected _collectionString = AssignmentPollOption.COLLECTIONSTRING;
|
||||
|
||||
private _user?: ViewUser; // This is the "candidate". We'll stay consistent wich user here...
|
||||
|
||||
public get option(): AssignmentPollOption {
|
||||
@ -49,8 +51,4 @@ export class ViewAssignmentPollOption extends BaseViewModel<AssignmentPollOption
|
||||
public get weight(): number {
|
||||
return this.option.weight;
|
||||
}
|
||||
|
||||
public constructor(assignmentPollOption: AssignmentPollOption) {
|
||||
super(AssignmentPollOption.COLLECTIONSTRING, assignmentPollOption);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import { ViewAssignmentPollOption } from './view-assignment-poll-option';
|
||||
|
||||
export class ViewAssignmentPoll extends BaseProjectableViewModel<AssignmentPoll> {
|
||||
public static COLLECTIONSTRING = AssignmentPoll.COLLECTIONSTRING;
|
||||
protected _collectionString = AssignmentPoll.COLLECTIONSTRING;
|
||||
|
||||
private _options: ViewAssignmentPollOption[];
|
||||
|
||||
public get poll(): AssignmentPoll {
|
||||
@ -76,10 +78,6 @@ export class ViewAssignmentPoll extends BaseProjectableViewModel<AssignmentPoll>
|
||||
return this.poll.assignment_id;
|
||||
}
|
||||
|
||||
public constructor(assignmentPoll: AssignmentPoll) {
|
||||
super(AssignmentPoll.COLLECTIONSTRING, assignmentPoll);
|
||||
}
|
||||
|
||||
public getTitle = () => {
|
||||
return 'Poll';
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import { ViewUser } from 'app/site/users/models/view-user';
|
||||
|
||||
export class ViewAssignmentRelatedUser extends BaseViewModel<AssignmentRelatedUser> {
|
||||
public static COLLECTIONSTRING = AssignmentRelatedUser.COLLECTIONSTRING;
|
||||
protected _collectionString = AssignmentRelatedUser.COLLECTIONSTRING;
|
||||
|
||||
private _user?: ViewUser;
|
||||
|
||||
@ -37,10 +38,6 @@ export class ViewAssignmentRelatedUser extends BaseViewModel<AssignmentRelatedUs
|
||||
|
||||
public getListTitle: () => string = this.getTitle;
|
||||
|
||||
public constructor(assignmentRelatedUser: AssignmentRelatedUser) {
|
||||
super(AssignmentRelatedUser.COLLECTIONSTRING, assignmentRelatedUser);
|
||||
}
|
||||
|
||||
public getTitle: () => string = () => {
|
||||
return this.user ? this.user.getFullName() : '';
|
||||
};
|
||||
|
@ -39,6 +39,7 @@ export const AssignmentPhases: { name: string; value: number; display_name: stri
|
||||
export class ViewAssignment extends BaseViewModelWithAgendaItemAndListOfSpeakers<Assignment>
|
||||
implements AssignmentTitleInformation {
|
||||
public static COLLECTIONSTRING = Assignment.COLLECTIONSTRING;
|
||||
protected _collectionString = Assignment.COLLECTIONSTRING;
|
||||
|
||||
private _assignment_related_users?: ViewAssignmentRelatedUser[];
|
||||
private _polls?: ViewAssignmentPoll[];
|
||||
@ -125,10 +126,6 @@ export class ViewAssignment extends BaseViewModelWithAgendaItemAndListOfSpeakers
|
||||
return this._assignment_related_users ? this._assignment_related_users.length : 0;
|
||||
}
|
||||
|
||||
public constructor(assignment: Assignment) {
|
||||
super(Assignment.COLLECTIONSTRING, assignment);
|
||||
}
|
||||
|
||||
public formatForSearch(): SearchRepresentation {
|
||||
return [this.title];
|
||||
}
|
||||
|
@ -49,10 +49,6 @@ export abstract class BaseViewModelWithAgendaItemAndListOfSpeakers<
|
||||
public getListOfSpeakersTitle: () => string;
|
||||
public getListOfSpeakersSlideTitle: () => string;
|
||||
|
||||
public constructor(collectionString: string, model: M) {
|
||||
super(collectionString, model);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns the (optional) descriptive text to be exported in the CSV.
|
||||
* May be overridden by inheriting classes
|
||||
|
@ -85,8 +85,8 @@ export abstract class BaseViewModelWithAgendaItem<M extends BaseModelWithAgendaI
|
||||
*/
|
||||
public getAgendaListTitle: () => string;
|
||||
|
||||
public constructor(collecitonString: string, model: M, item?: any) {
|
||||
super(collecitonString, model);
|
||||
public constructor(model: M, item?: any) {
|
||||
super(model);
|
||||
this._item = item || null; // Explicit set to null instead of undefined, if not given
|
||||
}
|
||||
|
||||
|
@ -22,12 +22,4 @@ export abstract class BaseViewModelWithContentObject<
|
||||
public get contentObject(): C | null {
|
||||
return this._contentObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param collectionString The collection string of this model
|
||||
* @param model the model this view model captures
|
||||
*/
|
||||
public constructor(collectionString: string, model: M) {
|
||||
super(collectionString, model);
|
||||
}
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ export abstract class BaseViewModelWithListOfSpeakers<M extends BaseModelWithLis
|
||||
public getListOfSpeakersTitle: () => string;
|
||||
public getListOfSpeakersSlideTitle: () => string;
|
||||
|
||||
public constructor(collectionString: string, model: M, listOfSpeakers?: any) {
|
||||
super(collectionString, model);
|
||||
public constructor(model: M, listOfSpeakers?: any) {
|
||||
super(model);
|
||||
this._list_of_speakers = listOfSpeakers || null; // Explicit set to null instead of undefined, if not given
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,6 @@ export interface ViewModelConstructor<T extends BaseViewModel> {
|
||||
* Base class for view models. alls view models should have titles.
|
||||
*/
|
||||
export abstract class BaseViewModel<M extends BaseModel = any> implements Displayable, Identifiable, Collection {
|
||||
protected _model: M;
|
||||
|
||||
public get id(): number {
|
||||
return this._model.id;
|
||||
}
|
||||
@ -58,10 +56,7 @@ export abstract class BaseViewModel<M extends BaseModel = any> implements Displa
|
||||
* @param collectionString
|
||||
* @param model
|
||||
*/
|
||||
public constructor(collectionString: string, model: M) {
|
||||
this._collectionString = collectionString;
|
||||
this._model = model;
|
||||
}
|
||||
public constructor(protected _model: M) {}
|
||||
|
||||
/**
|
||||
* @returns the main underlying model of the view model
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
|
||||
export const CommonAppConfig: AppConfig = {
|
||||
name: 'common',
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
import { Config } from '../../shared/models/core/config';
|
||||
import { ConfigRepositoryService } from '../../core/repositories/config/config-repository.service';
|
||||
import { ViewConfig } from './models/view-config';
|
||||
|
@ -41,6 +41,7 @@ export interface ConfigTitleInformation {
|
||||
*/
|
||||
export class ViewConfig extends BaseViewModel<Config> implements ConfigTitleInformation {
|
||||
public static COLLECTIONSTRING = Config.COLLECTIONSTRING;
|
||||
protected _collectionString = Config.COLLECTIONSTRING;
|
||||
|
||||
/* This private members are set by setConstantsInfo. */
|
||||
private _helpText: string;
|
||||
@ -90,10 +91,6 @@ export class ViewConfig extends BaseViewModel<Config> implements ConfigTitleInfo
|
||||
return this._defaultValue;
|
||||
}
|
||||
|
||||
public constructor(config: Config) {
|
||||
super(Config.COLLECTIONSTRING, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time this config field needs to debounce before sending a request to the server.
|
||||
* A little debounce time for all inputs is given here and is usefull, if inputs sends multiple onChange-events,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
|
||||
/**
|
||||
* Config object for history.
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
import { MediafileRepositoryService } from 'app/core/repositories/mediafiles/mediafile-repository.service';
|
||||
import { Mediafile } from '../../shared/models/mediafiles/mediafile';
|
||||
import { ViewMediafile } from './models/view-mediafile';
|
||||
|
@ -16,6 +16,7 @@ export interface MediafileTitleInformation {
|
||||
export class ViewMediafile extends BaseViewModelWithListOfSpeakers<Mediafile>
|
||||
implements MediafileTitleInformation, Searchable {
|
||||
public static COLLECTIONSTRING = Mediafile.COLLECTIONSTRING;
|
||||
protected _collectionString = Mediafile.COLLECTIONSTRING;
|
||||
|
||||
private _parent?: ViewMediafile;
|
||||
private _access_groups?: ViewGroup[];
|
||||
@ -101,10 +102,6 @@ export class ViewMediafile extends BaseViewModelWithListOfSpeakers<Mediafile>
|
||||
return this.mediafile.create_timestamp ? this.mediafile.create_timestamp : null;
|
||||
}
|
||||
|
||||
public constructor(mediafile: Mediafile) {
|
||||
super(Mediafile.COLLECTIONSTRING, mediafile);
|
||||
}
|
||||
|
||||
public formatForSearch(): SearchRepresentation {
|
||||
return [this.title, this.path];
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { SearchRepresentation } from 'app/core/ui-services/search.service';
|
||||
import { Category } from 'app/shared/models/motions/category';
|
||||
import { Searchable } from 'app/site/base/searchable';
|
||||
import { BaseViewModel } from '../../base/base-view-model';
|
||||
import { ViewMotion } from './view-motion';
|
||||
|
||||
export interface CategoryTitleInformation {
|
||||
prefix: string;
|
||||
@ -17,8 +18,11 @@ export interface CategoryTitleInformation {
|
||||
*/
|
||||
export class ViewCategory extends BaseViewModel<Category> implements CategoryTitleInformation, Searchable {
|
||||
public static COLLECTIONSTRING = Category.COLLECTIONSTRING;
|
||||
protected _collectionString = Category.COLLECTIONSTRING;
|
||||
|
||||
private _parent?: ViewCategory;
|
||||
private _children?: ViewCategory[];
|
||||
private _motions?: ViewMotion[];
|
||||
|
||||
public get category(): Category {
|
||||
return this._model;
|
||||
@ -28,6 +32,14 @@ export class ViewCategory extends BaseViewModel<Category> implements CategoryTit
|
||||
return this._parent;
|
||||
}
|
||||
|
||||
public get children(): ViewCategory[] {
|
||||
return this._children || [];
|
||||
}
|
||||
|
||||
public get motions(): ViewMotion[] {
|
||||
return this._motions || [];
|
||||
}
|
||||
|
||||
public get name(): string {
|
||||
return this.category.name;
|
||||
}
|
||||
@ -75,10 +87,6 @@ export class ViewCategory extends BaseViewModel<Category> implements CategoryTit
|
||||
}
|
||||
}
|
||||
|
||||
public constructor(category: Category) {
|
||||
super(Category.COLLECTIONSTRING, category);
|
||||
}
|
||||
|
||||
public formatForSearch(): SearchRepresentation {
|
||||
return [this.name, this.prefix];
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { TitleInformationWithAgendaItem } from 'app/site/base/base-view-model-wi
|
||||
import { BaseViewModelWithAgendaItemAndListOfSpeakers } from 'app/site/base/base-view-model-with-agenda-item-and-list-of-speakers';
|
||||
import { ProjectorElementBuildDeskriptor } from 'app/site/base/projectable';
|
||||
import { Searchable } from 'app/site/base/searchable';
|
||||
import { ViewMotion } from './view-motion';
|
||||
|
||||
export interface MotionBlockTitleInformation extends TitleInformationWithAgendaItem {
|
||||
title: string;
|
||||
@ -16,10 +17,16 @@ export interface MotionBlockTitleInformation extends TitleInformationWithAgendaI
|
||||
export class ViewMotionBlock extends BaseViewModelWithAgendaItemAndListOfSpeakers
|
||||
implements MotionBlockTitleInformation, Searchable {
|
||||
public static COLLECTIONSTRING = MotionBlock.COLLECTIONSTRING;
|
||||
protected _collectionString = MotionBlock.COLLECTIONSTRING;
|
||||
|
||||
private _motions?: ViewMotion[];
|
||||
|
||||
public get motionBlock(): MotionBlock {
|
||||
return this._model;
|
||||
}
|
||||
public get motions(): ViewMotion[] {
|
||||
return this._motions || [];
|
||||
}
|
||||
|
||||
public get title(): string {
|
||||
return this.motionBlock.title;
|
||||
@ -29,10 +36,6 @@ export class ViewMotionBlock extends BaseViewModelWithAgendaItemAndListOfSpeaker
|
||||
return this.motionBlock.internal;
|
||||
}
|
||||
|
||||
public constructor(motionBlock: MotionBlock) {
|
||||
super(MotionBlock.COLLECTIONSTRING, motionBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the category for search
|
||||
*
|
||||
|
@ -15,15 +15,12 @@ export type MotionChangeRecommendationTitleInformation = object;
|
||||
export class ViewMotionChangeRecommendation extends BaseViewModel<MotionChangeRecommendation>
|
||||
implements MotionChangeRecommendationTitleInformation, ViewUnifiedChange {
|
||||
public static COLLECTIONSTRING = MotionChangeRecommendation.COLLECTIONSTRING;
|
||||
protected _collectionString = MotionChangeRecommendation.COLLECTIONSTRING;
|
||||
|
||||
public get changeRecommendation(): MotionChangeRecommendation {
|
||||
return this._model;
|
||||
}
|
||||
|
||||
public constructor(motionChangeRecommendation: MotionChangeRecommendation) {
|
||||
super(MotionChangeRecommendation.COLLECTIONSTRING, motionChangeRecommendation);
|
||||
}
|
||||
|
||||
public updateChangeReco(type: number, text: string, internal: boolean): void {
|
||||
// @TODO HTML sanitazion
|
||||
this.changeRecommendation.type = type;
|
||||
|
@ -16,6 +16,7 @@ export interface MotionCommentSectionTitleInformation {
|
||||
export class ViewMotionCommentSection extends BaseViewModel<MotionCommentSection>
|
||||
implements MotionCommentSectionTitleInformation {
|
||||
public static COLLECTIONSTRING = MotionCommentSection.COLLECTIONSTRING;
|
||||
protected _collectionString = MotionCommentSection.COLLECTIONSTRING;
|
||||
|
||||
private _read_groups: ViewGroup[];
|
||||
private _write_groups: ViewGroup[];
|
||||
@ -59,10 +60,6 @@ export class ViewMotionCommentSection extends BaseViewModel<MotionCommentSection
|
||||
this._model.name = name;
|
||||
}
|
||||
|
||||
public constructor(motionCommentSection: MotionCommentSection) {
|
||||
super(MotionCommentSection.COLLECTIONSTRING, motionCommentSection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the local objects if required
|
||||
* @param section
|
||||
|
@ -62,6 +62,7 @@ export interface MotionTitleInformation extends TitleInformationWithAgendaItem {
|
||||
export class ViewMotion extends BaseViewModelWithAgendaItemAndListOfSpeakers<Motion>
|
||||
implements MotionTitleInformation, Searchable {
|
||||
public static COLLECTIONSTRING = Motion.COLLECTIONSTRING;
|
||||
protected _collectionString = Motion.COLLECTIONSTRING;
|
||||
|
||||
protected _category?: ViewCategory;
|
||||
protected _submitters?: ViewSubmitter[];
|
||||
@ -340,10 +341,6 @@ export class ViewMotion extends BaseViewModelWithAgendaItemAndListOfSpeakers<Mot
|
||||
// This is set by the repository
|
||||
public getIdentifierOrTitle: () => string;
|
||||
|
||||
public constructor(motion: Motion) {
|
||||
super(Motion.COLLECTIONSTRING, motion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the category for search
|
||||
*
|
||||
|
@ -12,6 +12,7 @@ export interface StateTitleInformation {
|
||||
*/
|
||||
export class ViewState extends BaseViewModel<State> implements StateTitleInformation {
|
||||
public static COLLECTIONSTRING = State.COLLECTIONSTRING;
|
||||
protected _collectionString = State.COLLECTIONSTRING;
|
||||
|
||||
private _next_states?: ViewState[];
|
||||
public _workflow?: ViewWorkflow;
|
||||
@ -92,8 +93,4 @@ export class ViewState extends BaseViewModel<State> implements StateTitleInforma
|
||||
return state.next_states_id.includes(this.id);
|
||||
});
|
||||
}
|
||||
|
||||
public constructor(state: State) {
|
||||
super(State.COLLECTIONSTRING, state);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ export interface StatuteParagraphTitleInformation {
|
||||
export class ViewStatuteParagraph extends BaseViewModel<StatuteParagraph>
|
||||
implements StatuteParagraphTitleInformation, Searchable {
|
||||
public static COLLECTIONSTRING = StatuteParagraph.COLLECTIONSTRING;
|
||||
protected _collectionString = StatuteParagraph.COLLECTIONSTRING;
|
||||
|
||||
public get statuteParagraph(): StatuteParagraph {
|
||||
return this._model;
|
||||
@ -34,10 +35,6 @@ export class ViewStatuteParagraph extends BaseViewModel<StatuteParagraph>
|
||||
return this.statuteParagraph.weight;
|
||||
}
|
||||
|
||||
public constructor(statuteParagraph: StatuteParagraph) {
|
||||
super(StatuteParagraph.COLLECTIONSTRING, statuteParagraph);
|
||||
}
|
||||
|
||||
public formatForSearch(): SearchRepresentation {
|
||||
return [this.title];
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import { ViewUser } from 'app/site/users/models/view-user';
|
||||
|
||||
export class ViewSubmitter extends BaseViewModel<Submitter> {
|
||||
public static COLLECTIONSTRING = Submitter.COLLECTIONSTRING;
|
||||
protected _collectionString = Submitter.COLLECTIONSTRING;
|
||||
|
||||
private _user?: ViewUser;
|
||||
|
||||
public get submitter(): Submitter {
|
||||
@ -30,10 +32,6 @@ export class ViewSubmitter extends BaseViewModel<Submitter> {
|
||||
return this.submitter.weight;
|
||||
}
|
||||
|
||||
public constructor(submitter: Submitter) {
|
||||
super(Submitter.COLLECTIONSTRING, submitter);
|
||||
}
|
||||
|
||||
public getTitle = () => {
|
||||
return this.user ? this.user.getTitle() : '';
|
||||
};
|
||||
|
@ -12,6 +12,7 @@ export interface WorkflowTitleInformation {
|
||||
*/
|
||||
export class ViewWorkflow extends BaseViewModel<Workflow> implements WorkflowTitleInformation {
|
||||
public static COLLECTIONSTRING = Workflow.COLLECTIONSTRING;
|
||||
protected _collectionString = Workflow.COLLECTIONSTRING;
|
||||
|
||||
private _states?: ViewState[];
|
||||
private _first_state?: ViewState;
|
||||
@ -39,8 +40,4 @@ export class ViewWorkflow extends BaseViewModel<Workflow> implements WorkflowTit
|
||||
public get first_state(): ViewState | null {
|
||||
return this._first_state;
|
||||
}
|
||||
|
||||
public constructor(workflow: Workflow) {
|
||||
super(Workflow.COLLECTIONSTRING, workflow);
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ export class CategoryDetailComponent extends BaseViewComponent implements OnInit
|
||||
return;
|
||||
}
|
||||
|
||||
// Find index of last child. THis can be easily done by searching, becuase this
|
||||
// Find index of last child. This can be easily done by searching, because this
|
||||
// is the flat sorted tree
|
||||
this.selectedCategory = categories[selectedCategoryIndex];
|
||||
super.setTitle(this.selectedCategory.prefixedName);
|
||||
@ -122,24 +122,10 @@ export class CategoryDetailComponent extends BaseViewComponent implements OnInit
|
||||
this.categories = categories.slice(selectedCategoryIndex, lastChildIndex);
|
||||
|
||||
// setup datasources:
|
||||
const allMotions = this.motionRepo
|
||||
.getViewModelList()
|
||||
.sort((a, b) => a.category_weight - b.category_weight);
|
||||
this.categories.forEach(category => {
|
||||
if (!this.dataSources[category.id]) {
|
||||
const dataSource = new MatTableDataSource<ViewMotion>();
|
||||
dataSource.data = allMotions.filter(motion => motion.category_id === category.id);
|
||||
dataSource.data = category.motions;
|
||||
this.dataSources[category.id] = dataSource;
|
||||
}
|
||||
});
|
||||
}),
|
||||
this.motionRepo.getViewModelListObservable().subscribe(motions => {
|
||||
motions = motions
|
||||
.filter(motion => !!motion.category_id)
|
||||
.sort((a, b) => a.category_weight - b.category_weight);
|
||||
Object.keys(this.dataSources).forEach(_id => {
|
||||
const id = +_id;
|
||||
this.dataSources[id].data = motions.filter(motion => motion.category_id === id);
|
||||
});
|
||||
})
|
||||
);
|
||||
|
@ -66,7 +66,7 @@
|
||||
<span translate>Motions</span>
|
||||
</mat-header-cell>
|
||||
<mat-cell *matCellDef="let category">
|
||||
<span class="os-amount-chip">{{ getMotionAmount(category) }}</span>
|
||||
<span class="os-amount-chip">{{ category.motions.length }}</span>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
|
@ -95,16 +95,6 @@ export class CategoryListComponent extends BaseViewComponent implements OnInit {
|
||||
return ['title', 'amount', 'anchor'];
|
||||
}
|
||||
|
||||
/**
|
||||
* return the amount of motions in a category
|
||||
*
|
||||
* @param category the category to determine the amount of motions for
|
||||
* @returns a number that indicates how many motions are in the given category
|
||||
*/
|
||||
public getMotionAmount(category: ViewCategory): number {
|
||||
return this.repo.getMotionAmountByCategory(category);
|
||||
}
|
||||
|
||||
/**
|
||||
* Click handler for the plus button
|
||||
*/
|
||||
|
@ -132,7 +132,7 @@ export class MotionBlockDetailComponent extends BaseViewComponent implements OnI
|
||||
|
||||
this.dataSource = createDS<ViewMotion>()
|
||||
.onTrigger(() => {
|
||||
return this.repo.getViewMotionsByBlock(this.block.motionBlock);
|
||||
return this.block.motions;
|
||||
})
|
||||
.create();
|
||||
}
|
||||
|
@ -15,22 +15,22 @@
|
||||
(dataSourceChange)="onDataSourceChange($event)"
|
||||
>
|
||||
<!-- Title column -->
|
||||
<div *pblNgridCellDef="'title'; value as title; row as block; rowContext as rowContext" class="cell-slot fill">
|
||||
<div *pblNgridCellDef="'title'; value as title; row as motionBlock; rowContext as rowContext" class="cell-slot fill">
|
||||
<a
|
||||
class="detail-link"
|
||||
(click)="saveScrollIndex('motionBlock', rowContext.identity)"
|
||||
[routerLink]="block.id"
|
||||
[routerLink]="motionBlock.id"
|
||||
*ngIf="!isMultiSelect"
|
||||
></a>
|
||||
<div>
|
||||
<mat-icon matTooltip="Internal" *ngIf="block.internal">lock</mat-icon>
|
||||
<mat-icon matTooltip="Internal" *ngIf="motionBlock.internal">lock</mat-icon>
|
||||
{{ title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Amount -->
|
||||
<div *pblNgridCellDef="'amount'; row as block" class="cell-slot fill">
|
||||
<span class="os-amount-chip">{{ getMotionAmount(block.motionBlock) }}</span>
|
||||
<div *pblNgridCellDef="'amount'; row as motionBlock" class="cell-slot fill">
|
||||
<span class="os-amount-chip">{{ motionBlock.motions.length }}</span>
|
||||
</div>
|
||||
</os-list-view-table>
|
||||
</mat-card>
|
||||
|
@ -12,7 +12,6 @@ import { OperatorService } from 'app/core/core-services/operator.service';
|
||||
import { StorageService } from 'app/core/core-services/storage.service';
|
||||
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
|
||||
import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service';
|
||||
import { MotionBlock } from 'app/shared/models/motions/motion-block';
|
||||
import { infoDialogSettings } from 'app/shared/utils/dialog-settings';
|
||||
import { ViewItem } from 'app/site/agenda/models/view-item';
|
||||
import { BaseListViewComponent } from 'app/site/base/base-list-view';
|
||||
@ -117,16 +116,6 @@ export class MotionBlockListComponent extends BaseListViewComponent<ViewMotionBl
|
||||
this.items = this.itemRepo.getViewModelListBehaviorSubject();
|
||||
}
|
||||
|
||||
/**
|
||||
* return the amount of motions in a motion block
|
||||
*
|
||||
* @param motionBlock the block to determine the amount of motions for
|
||||
* @returns a number that indicates how many motions are in the given block
|
||||
*/
|
||||
public getMotionAmount(motionBlock: MotionBlock): number {
|
||||
return this.repo.getMotionAmountByBlock(motionBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function reset the form and set the default values
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service';
|
||||
import { ChangeRecommendationRepositoryService } from 'app/core/repositories/motions/change-recommendation-repository.service';
|
||||
import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service';
|
||||
|
@ -4,7 +4,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { OpenSlidesStatusService } from 'app/core/core-services/openslides-status.service';
|
||||
import { StorageService } from 'app/core/core-services/storage.service';
|
||||
import { Deferred } from 'app/core/deferred';
|
||||
import { Deferred } from 'app/core/promises/deferred';
|
||||
import { _ } from 'app/core/translate/translation-marker';
|
||||
import { BaseSortListService, OsSortingDefinition, OsSortingOption } from 'app/core/ui-services/base-sort-list.service';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
|
@ -9,6 +9,7 @@ export interface CountdownTitleInformation {
|
||||
|
||||
export class ViewCountdown extends BaseProjectableViewModel<Countdown> implements CountdownTitleInformation {
|
||||
public static COLLECTIONSTRING = Countdown.COLLECTIONSTRING;
|
||||
protected _collectionString = Countdown.COLLECTIONSTRING;
|
||||
|
||||
public get countdown(): Countdown {
|
||||
return this._model;
|
||||
@ -34,10 +35,6 @@ export class ViewCountdown extends BaseProjectableViewModel<Countdown> implement
|
||||
return this.countdown.title;
|
||||
}
|
||||
|
||||
public constructor(countdown: Countdown) {
|
||||
super(Countdown.COLLECTIONSTRING, countdown);
|
||||
}
|
||||
|
||||
public getSlide(): ProjectorElementBuildDeskriptor {
|
||||
return {
|
||||
getBasicProjectorElement: options => ({
|
||||
|
@ -8,6 +8,7 @@ export interface ProjectionDefaultTitleInformation {
|
||||
export class ViewProjectionDefault extends BaseViewModel<ProjectionDefault>
|
||||
implements ProjectionDefaultTitleInformation {
|
||||
public static COLLECTIONSTRING = ProjectionDefault.COLLECTIONSTRING;
|
||||
protected _collectionString = ProjectionDefault.COLLECTIONSTRING;
|
||||
|
||||
public get projectionDefault(): ProjectionDefault {
|
||||
return this._model;
|
||||
@ -24,8 +25,4 @@ export class ViewProjectionDefault extends BaseViewModel<ProjectionDefault>
|
||||
public get display_name(): string {
|
||||
return this.projectionDefault.display_name;
|
||||
}
|
||||
|
||||
public constructor(projectionDefault: ProjectionDefault) {
|
||||
super(ProjectionDefault.COLLECTIONSTRING, projectionDefault);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ export type ProjectorMessageTitleInformation = object;
|
||||
export class ViewProjectorMessage extends BaseProjectableViewModel<ProjectorMessage>
|
||||
implements ProjectorMessageTitleInformation {
|
||||
public static COLLECTIONSTRING = ProjectorMessage.COLLECTIONSTRING;
|
||||
protected _collectionString = ProjectorMessage.COLLECTIONSTRING;
|
||||
|
||||
public get projectormessage(): ProjectorMessage {
|
||||
return this._model;
|
||||
@ -17,10 +18,6 @@ export class ViewProjectorMessage extends BaseProjectableViewModel<ProjectorMess
|
||||
return this.projectormessage.message;
|
||||
}
|
||||
|
||||
public constructor(projectorMessage: ProjectorMessage) {
|
||||
super(ProjectorMessage.COLLECTIONSTRING, projectorMessage);
|
||||
}
|
||||
|
||||
public getSlide(): ProjectorElementBuildDeskriptor {
|
||||
return {
|
||||
getBasicProjectorElement: options => ({
|
||||
|
@ -7,6 +7,7 @@ export interface ProjectorTitleInformation {
|
||||
|
||||
export class ViewProjector extends BaseViewModel<Projector> {
|
||||
public static COLLECTIONSTRING = Projector.COLLECTIONSTRING;
|
||||
protected _collectionString = Projector.COLLECTIONSTRING;
|
||||
|
||||
private _referenceProjector: ViewProjector;
|
||||
|
||||
@ -105,8 +106,4 @@ export class ViewProjector extends BaseViewModel<Projector> {
|
||||
public get show_logo(): boolean {
|
||||
return this.projector.show_logo;
|
||||
}
|
||||
|
||||
public constructor(projector: Projector) {
|
||||
super(Projector.COLLECTIONSTRING, projector);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
import { CountdownRepositoryService } from 'app/core/repositories/projector/countdown-repository.service';
|
||||
import { ProjectionDefaultRepositoryService } from 'app/core/repositories/projector/projection-default-repository.service';
|
||||
import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projector-message-repository.service';
|
||||
|
@ -16,6 +16,7 @@ export interface TagTitleInformation {
|
||||
*/
|
||||
export class ViewTag extends BaseViewModel<Tag> implements TagTitleInformation, Searchable {
|
||||
public static COLLECTIONSTRING = Tag.COLLECTIONSTRING;
|
||||
protected _collectionString = Tag.COLLECTIONSTRING;
|
||||
|
||||
public get tag(): Tag {
|
||||
return this._model;
|
||||
@ -25,10 +26,6 @@ export class ViewTag extends BaseViewModel<Tag> implements TagTitleInformation,
|
||||
return this.tag.name;
|
||||
}
|
||||
|
||||
public constructor(tag: Tag) {
|
||||
super(Tag.COLLECTIONSTRING, tag);
|
||||
}
|
||||
|
||||
public formatForSearch(): SearchRepresentation {
|
||||
return [this.name];
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
import { TagRepositoryService } from 'app/core/repositories/tags/tag-repository.service';
|
||||
import { Tag } from '../../shared/models/core/tag';
|
||||
import { ViewTag } from './models/view-tag';
|
||||
|
@ -16,6 +16,7 @@ export interface TopicTitleInformation extends TitleInformationWithAgendaItem {
|
||||
*/
|
||||
export class ViewTopic extends BaseViewModelWithAgendaItemAndListOfSpeakers implements TopicTitleInformation {
|
||||
public static COLLECTIONSTRING = Topic.COLLECTIONSTRING;
|
||||
protected _collectionString = Topic.COLLECTIONSTRING;
|
||||
|
||||
private _attachments?: ViewMediafile[];
|
||||
|
||||
@ -39,10 +40,6 @@ export class ViewTopic extends BaseViewModelWithAgendaItemAndListOfSpeakers impl
|
||||
return this.topic.text;
|
||||
}
|
||||
|
||||
public constructor(topic: Topic) {
|
||||
super(Topic.COLLECTIONSTRING, topic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the category for search
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
import { TopicRepositoryService } from 'app/core/repositories/topics/topic-repository.service';
|
||||
import { Topic } from '../../shared/models/topics/topic';
|
||||
import { ViewTopic } from './models/view-topic';
|
||||
|
@ -7,6 +7,7 @@ export interface GroupTitleInformation {
|
||||
|
||||
export class ViewGroup extends BaseViewModel<Group> implements GroupTitleInformation {
|
||||
public static COLLECTIONSTRING = Group.COLLECTIONSTRING;
|
||||
protected _collectionString = Group.COLLECTIONSTRING;
|
||||
|
||||
public get group(): Group {
|
||||
return this._model;
|
||||
@ -29,10 +30,6 @@ export class ViewGroup extends BaseViewModel<Group> implements GroupTitleInforma
|
||||
return this.group.permissions;
|
||||
}
|
||||
|
||||
public constructor(group?: Group) {
|
||||
super(Group.COLLECTIONSTRING, group);
|
||||
}
|
||||
|
||||
public hasPermission(perm: string): boolean {
|
||||
return this.permissions.includes(perm);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ export type PersonalNoteTitleInformation = object;
|
||||
|
||||
export class ViewPersonalNote extends BaseViewModel<PersonalNote> implements PersonalNoteTitleInformation {
|
||||
public static COLLECTIONSTRING = PersonalNote.COLLECTIONSTRING;
|
||||
protected _collectionString = PersonalNote.COLLECTIONSTRING;
|
||||
|
||||
public get personalNote(): PersonalNote {
|
||||
return this._model;
|
||||
@ -18,10 +19,6 @@ export class ViewPersonalNote extends BaseViewModel<PersonalNote> implements Per
|
||||
return this.personalNote.notes;
|
||||
}
|
||||
|
||||
public constructor(personalNote: PersonalNote) {
|
||||
super(PersonalNote.COLLECTIONSTRING, personalNote);
|
||||
}
|
||||
|
||||
public getNoteContent(collection: string, id: number): PersonalNoteContent | null {
|
||||
if (this.notes[collection]) {
|
||||
return this.notes[collection][id];
|
||||
|
@ -16,6 +16,7 @@ export interface UserTitleInformation {
|
||||
|
||||
export class ViewUser extends BaseProjectableViewModel<User> implements UserTitleInformation, Searchable {
|
||||
public static COLLECTIONSTRING = User.COLLECTIONSTRING;
|
||||
protected _collectionString = User.COLLECTIONSTRING;
|
||||
|
||||
private _groups: ViewGroup[];
|
||||
|
||||
@ -120,10 +121,6 @@ export class ViewUser extends BaseProjectableViewModel<User> implements UserTitl
|
||||
public getFullName: () => string;
|
||||
public getShortName: () => string;
|
||||
|
||||
public constructor(user: User) {
|
||||
super(User.COLLECTIONSTRING, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the category for search
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppConfig } from '../../core/app-config';
|
||||
import { AppConfig } from '../../core/definitions/app-config';
|
||||
import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service';
|
||||
import { PersonalNoteRepositoryService } from 'app/core/repositories/users/personal-note-repository.service';
|
||||
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
|
||||
|
Loading…
Reference in New Issue
Block a user