Fixed two little issues with relations and reverse mapping
- Reverse setup for normal autoupdates (no initial loading) - reverse "set null" to be reflected to the mapping Also fixed a bug with redis
This commit is contained in:
parent
a1b7b1c69d
commit
1d718dcb74
@ -97,7 +97,7 @@ export class AutoupdateService {
|
||||
elements = elements.concat(this.mapObjectsToBaseModels(collection, autoupdate.changed[collection]));
|
||||
});
|
||||
|
||||
const updateSlot = await this.DSUpdateManager.getNewUpdateSlot(this.DS);
|
||||
const updateSlot = await this.DSUpdateManager.getNewUpdateSlot(this.DS, true);
|
||||
await this.DS.set(elements, autoupdate.to_change_id);
|
||||
this.DSUpdateManager.commit(updateSlot);
|
||||
}
|
||||
@ -172,7 +172,7 @@ export class AutoupdateService {
|
||||
const oldChangeId = this.DS.maxChangeId;
|
||||
const response = await this.websocketService.sendAndGetResponse<{}, AutoupdateFormat>('getElements', {});
|
||||
|
||||
const updateSlot = await this.DSUpdateManager.getNewUpdateSlot(this.DS);
|
||||
const updateSlot = await this.DSUpdateManager.getNewUpdateSlot(this.DS, true);
|
||||
let allModels: BaseModel[] = [];
|
||||
for (const collection of Object.keys(response.changed)) {
|
||||
if (this.modelMapper.isCollectionRegistered(collection)) {
|
||||
|
@ -49,7 +49,7 @@ export class UpdateSlot {
|
||||
/**
|
||||
* @param DS Carries the DataStore: TODO (see below `DataStoreUpdateManagerService.getNewUpdateSlot`)
|
||||
*/
|
||||
public constructor(public readonly DS: DataStoreService) {
|
||||
public constructor(public readonly DS: DataStoreService, public readonly initialLoading: boolean) {
|
||||
this._id = UpdateSlot.ID_COUTNER++;
|
||||
}
|
||||
|
||||
@ -185,13 +185,13 @@ export class DataStoreUpdateManagerService {
|
||||
* @param DS The DataStore. This is a hack, becuase we cannot use the DataStore
|
||||
* here, because these are cyclic dependencies... --> TODO
|
||||
*/
|
||||
public async getNewUpdateSlot(DS: DataStoreService): Promise<UpdateSlot> {
|
||||
public async getNewUpdateSlot(DS: DataStoreService, initialLoading: boolean = false): Promise<UpdateSlot> {
|
||||
if (this.currentUpdateSlot) {
|
||||
const request = new Deferred();
|
||||
this.updateSlotRequests.push(request);
|
||||
await request;
|
||||
}
|
||||
this.currentUpdateSlot = new UpdateSlot(DS);
|
||||
this.currentUpdateSlot = new UpdateSlot(DS, initialLoading);
|
||||
return this.currentUpdateSlot;
|
||||
}
|
||||
|
||||
@ -221,7 +221,7 @@ export class DataStoreUpdateManagerService {
|
||||
const deletedModelIds = slot.getDeletedModelIdsForCollection(repo.collectionString);
|
||||
repo.deleteModels(deletedModelIds);
|
||||
const changedModelIds = slot.getChangedModelIdsForCollection(repo.collectionString);
|
||||
repo.changedModels(changedModelIds);
|
||||
repo.changedModels(changedModelIds, slot.initialLoading);
|
||||
|
||||
if (deletedModelIds.length || changedModelIds.length) {
|
||||
affectedRepos[repo.collectionString] = repo;
|
||||
@ -350,7 +350,7 @@ export class DataStoreService {
|
||||
// This promise will be resolved with cached datastore.
|
||||
const store = await this.storageService.get<JsonStorage>(DataStoreService.cachePrefix + 'DS');
|
||||
if (store) {
|
||||
const updateSlot = await this.DSUpdateManager.getNewUpdateSlot(this);
|
||||
const updateSlot = await this.DSUpdateManager.getNewUpdateSlot(this, true);
|
||||
|
||||
// There is a store. Deserialize it
|
||||
this.jsonStore = store;
|
||||
|
@ -48,12 +48,13 @@ export class RelationManagerService {
|
||||
public createViewModel<M extends BaseModel, V extends BaseViewModel>(
|
||||
model: M,
|
||||
modelCtor: ViewModelConstructor<V>,
|
||||
relations: RelationDefinition[]
|
||||
relations: RelationDefinition[],
|
||||
initialLoading: boolean
|
||||
): V {
|
||||
const viewModel = new modelCtor(model) as V;
|
||||
|
||||
relations.forEach(relation => {
|
||||
this.setRelationsInViewModel(model, viewModel, relation);
|
||||
this.setRelationsInViewModel(model, viewModel, relation, initialLoading);
|
||||
});
|
||||
|
||||
return viewModel;
|
||||
@ -66,30 +67,65 @@ export class RelationManagerService {
|
||||
protected setRelationsInViewModel<M extends BaseModel, V extends BaseViewModel>(
|
||||
model: M,
|
||||
viewModel: V,
|
||||
relation: RelationDefinition
|
||||
relation: RelationDefinition,
|
||||
initialLoading: boolean
|
||||
): void {
|
||||
// no reverse setting needed. This is done in the second phase of the ds-upgrade-manager
|
||||
if (isReverseRelationDefinition(relation)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNormalRelationDefinition(relation)) {
|
||||
if (
|
||||
(relation.type === 'M2M' || relation.type === 'O2M') &&
|
||||
model[relation.ownIdKey] &&
|
||||
model[relation.ownIdKey].constructor === Array
|
||||
) {
|
||||
const foreignViewModels = this.viewModelStoreService.getMany(
|
||||
relation.foreignModel,
|
||||
relation.foreignViewModel,
|
||||
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]);
|
||||
const foreignViewModel = this.viewModelStoreService.get(
|
||||
relation.foreignViewModel,
|
||||
model[relation.ownIdKey]
|
||||
);
|
||||
viewModel['_' + relation.ownKey] = foreignViewModel;
|
||||
}
|
||||
} else if (isReverseRelationDefinition(relation) && !initialLoading) {
|
||||
if (relation.type === 'M2M') {
|
||||
const foreignViewModels = this.viewModelStoreService.filter(
|
||||
relation.foreignViewModel,
|
||||
foreignViewModel =>
|
||||
foreignViewModel[relation.foreignIdKey] &&
|
||||
foreignViewModel[relation.foreignIdKey].constructor === Array &&
|
||||
foreignViewModel[relation.foreignIdKey].includes(model.id)
|
||||
);
|
||||
viewModel['_' + relation.ownKey] = foreignViewModels;
|
||||
this.sortByRelation(relation, viewModel);
|
||||
} else if (relation.type === 'O2M') {
|
||||
const foreignViewModels = this.viewModelStoreService.filter(
|
||||
relation.foreignViewModel,
|
||||
foreignViewModel =>
|
||||
foreignViewModel[relation.foreignIdKey] && foreignViewModel[relation.foreignIdKey] === model.id
|
||||
);
|
||||
viewModel['_' + relation.ownKey] = foreignViewModels;
|
||||
this.sortByRelation(relation, viewModel);
|
||||
} else if (relation.type === 'M2O') {
|
||||
const foreignViewModel = this.viewModelStoreService.find(
|
||||
relation.foreignViewModel,
|
||||
_foreignViewModel =>
|
||||
_foreignViewModel[relation.foreignIdKey] &&
|
||||
_foreignViewModel[relation.foreignIdKey] === model.id
|
||||
);
|
||||
viewModel['_' + relation.ownKey] = foreignViewModel;
|
||||
}
|
||||
} else if (isNestedRelationDefinition(relation)) {
|
||||
const foreignViewModels: BaseViewModel[] = model[relation.ownKey].map(foreignModel =>
|
||||
this.createViewModel(foreignModel, relation.foreignModel, relation.relationDefinition || [])
|
||||
const foreignModels = model[relation.ownKey].map(m => new relation.foreignModel(m));
|
||||
const foreignViewModels: BaseViewModel[] = foreignModels.map((foreignModel: BaseModel) =>
|
||||
this.createViewModel(
|
||||
foreignModel,
|
||||
relation.foreignViewModel,
|
||||
relation.relationDefinition || [],
|
||||
initialLoading
|
||||
)
|
||||
);
|
||||
viewModel['_' + relation.ownKey] = foreignViewModels;
|
||||
this.sortByRelation(relation, viewModel);
|
||||
@ -181,15 +217,29 @@ export class RelationManagerService {
|
||||
|
||||
// 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 not, check, if the model _was_ in our foreignViewModel array and remove it.
|
||||
if (relation.type === 'O2M') {
|
||||
if (foreignViewModel[relation.foreignIdKey] === ownViewModel.id) {
|
||||
this.setForeingViewModelInOwnViewModelArray(foreignViewModel, ownViewModel, relation.ownKey);
|
||||
return true;
|
||||
} else {
|
||||
const ownViewModelArray = <any>ownViewModel['_' + relation.ownKey];
|
||||
if (ownViewModelArray) {
|
||||
// We have the array of foreign view models for our own view model. Remove the foreignViewModel (if it was there).
|
||||
const index = ownViewModelArray.findIndex(
|
||||
_foreignViewModel => _foreignViewModel.id === foreignViewModel.id
|
||||
);
|
||||
if (index > -1) {
|
||||
ownViewModelArray.splice(index, 1);
|
||||
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)
|
||||
// be included into the array from the ownViewModel (with many foreignViewModels).
|
||||
// If not, check, if the model _was_ in our foreignViewModel array and remove it.
|
||||
else if (relation.type === 'M2M') {
|
||||
if (
|
||||
foreignViewModel[relation.foreignIdKey] &&
|
||||
@ -198,11 +248,24 @@ export class RelationManagerService {
|
||||
) {
|
||||
this.setForeingViewModelInOwnViewModelArray(foreignViewModel, ownViewModel, relation.ownKey);
|
||||
return true;
|
||||
} else {
|
||||
const ownViewModelArray = <any>ownViewModel['_' + relation.ownKey];
|
||||
if (ownViewModelArray) {
|
||||
// We have the array of foreign view models for our own view model. Remove the foreignViewModel (if it was there).
|
||||
const index = ownViewModelArray.findIndex(
|
||||
_foreignViewModel => _foreignViewModel.id === foreignViewModel.id
|
||||
);
|
||||
if (index > -1) {
|
||||
ownViewModelArray.splice(index, 1);
|
||||
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
|
||||
// one and only matching model for the ownViewModel. If the ownViewModel is not in it, check if the
|
||||
// foreignViewModel _was_ the matching model. If so, set the reference to null.
|
||||
else if (relation.type === 'M2O') {
|
||||
if (
|
||||
foreignViewModel[relation.foreignIdKey] &&
|
||||
@ -211,6 +274,11 @@ export class RelationManagerService {
|
||||
) {
|
||||
ownViewModel['_' + relation.ownKey] = foreignViewModel;
|
||||
return true;
|
||||
} else if (
|
||||
ownViewModel['_' + relation.ownKey] &&
|
||||
ownViewModel['_' + relation.ownKey].id === foreignViewModel.id
|
||||
) {
|
||||
ownViewModel['_' + relation.ownKey] = null;
|
||||
}
|
||||
}
|
||||
} else if (isNestedRelationDefinition(relation)) {
|
||||
|
@ -53,7 +53,7 @@ export class TimeTravelService {
|
||||
* @param history the desired point in the history of OpenSlides
|
||||
*/
|
||||
public async loadHistoryPoint(history: History): Promise<void> {
|
||||
const updateSlot = await this.DSUpdateManager.getNewUpdateSlot(this.DS);
|
||||
const updateSlot = await this.DSUpdateManager.getNewUpdateSlot(this.DS, true);
|
||||
|
||||
await this.stopTime(history);
|
||||
const historyData: HistoryData = await this.getHistoryData(history);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { BaseModel } from 'app/shared/models/base/base-model';
|
||||
import { BaseModel, ModelConstructor } from 'app/shared/models/base/base-model';
|
||||
import { BaseViewModel, ViewModelConstructor } from 'app/site/base/base-view-model';
|
||||
|
||||
// All "standard" relations.
|
||||
@ -21,7 +21,7 @@ interface BaseRelationDefinition<VForeign extends BaseViewModel> {
|
||||
/**
|
||||
* The model on the other side of the relation.
|
||||
*/
|
||||
foreignModel: ViewModelConstructor<VForeign>;
|
||||
foreignViewModel: ViewModelConstructor<VForeign>;
|
||||
}
|
||||
|
||||
export interface BaseOrderedRelation<VForeign extends BaseViewModel> extends BaseRelationDefinition<VForeign> {
|
||||
@ -97,7 +97,7 @@ interface BaseReverseRelationDefinition<VForeign extends BaseViewModel> {
|
||||
/**
|
||||
* The model on the other side of the relation.
|
||||
*/
|
||||
foreignModel: ViewModelConstructor<VForeign>;
|
||||
foreignViewModel: ViewModelConstructor<VForeign>;
|
||||
}
|
||||
|
||||
interface ReverseM2MRelationDefinition<VForeign extends BaseViewModel>
|
||||
@ -130,7 +130,7 @@ export function isReverseRelationDefinition(obj: RelationDefinition): obj is Rev
|
||||
* Nested relations in the REST-API. For the most values see
|
||||
* `NormalRelationDefinition`.
|
||||
*/
|
||||
interface NestedRelationDefinition<VForeign extends BaseViewModel> extends BaseOrderedRelation<VForeign> {
|
||||
export interface NestedRelationDefinition<VForeign extends BaseViewModel> extends BaseOrderedRelation<VForeign> {
|
||||
type: 'nested';
|
||||
ownKey: string;
|
||||
|
||||
@ -138,6 +138,11 @@ interface NestedRelationDefinition<VForeign extends BaseViewModel> extends BaseO
|
||||
* The nested relations.
|
||||
*/
|
||||
relationDefinition?: RelationDefinition[];
|
||||
|
||||
/**
|
||||
* The matching model for the foreignViewModel.
|
||||
*/
|
||||
foreignModel: ModelConstructor<BaseModel>;
|
||||
}
|
||||
|
||||
export function isNestedRelationDefinition(obj: RelationDefinition): obj is NestedRelationDefinition<BaseViewModel> {
|
||||
@ -172,7 +177,7 @@ export function isGenericRelationDefinition(obj: RelationDefinition): obj is Gen
|
||||
*/
|
||||
interface CustomRelationDefinition<VForeign extends BaseViewModel> {
|
||||
type: 'custom';
|
||||
foreignModel: ViewModelConstructor<VForeign>;
|
||||
foreignViewModel: ViewModelConstructor<VForeign>;
|
||||
|
||||
/**
|
||||
* Called, when the view model is created from the model.
|
||||
|
@ -8,6 +8,7 @@ import { RelationManagerService } from 'app/core/core-services/relation-manager.
|
||||
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 { Speaker } from 'app/shared/models/agenda/speaker';
|
||||
import { Identifiable } from 'app/shared/models/base/identifiable';
|
||||
import { ListOfSpeakersTitleInformation, ViewListOfSpeakers } from 'app/site/agenda/models/view-list-of-speakers';
|
||||
import { ViewSpeaker } from 'app/site/agenda/models/view-speaker';
|
||||
@ -39,14 +40,15 @@ const ListOfSpeakersRelations: RelationDefinition[] = [
|
||||
{
|
||||
type: 'nested',
|
||||
ownKey: 'speakers',
|
||||
foreignModel: ViewSpeaker,
|
||||
foreignViewModel: ViewSpeaker,
|
||||
foreignModel: Speaker,
|
||||
order: 'weight',
|
||||
relationDefinition: [
|
||||
{
|
||||
type: 'M2O',
|
||||
ownIdKey: 'user_id',
|
||||
ownKey: 'user',
|
||||
foreignModel: ViewUser
|
||||
foreignViewModel: ViewUser
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import { ViewModelStoreService } from 'app/core/core-services/view-model-store.s
|
||||
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 { AssignmentPollOption } from 'app/shared/models/assignments/assignment-poll-option';
|
||||
import { AssignmentRelatedUser } from 'app/shared/models/assignments/assignment-related-user';
|
||||
import { AssignmentTitleInformation, ViewAssignment } from 'app/site/assignments/models/view-assignment';
|
||||
import { ViewAssignmentPoll } from 'app/site/assignments/models/view-assignment-poll';
|
||||
import { ViewAssignmentPollOption } from 'app/site/assignments/models/view-assignment-poll-option';
|
||||
@ -25,44 +27,47 @@ const AssignmentRelations: RelationDefinition[] = [
|
||||
type: 'M2M',
|
||||
ownIdKey: 'tags_id',
|
||||
ownKey: 'tags',
|
||||
foreignModel: ViewTag
|
||||
foreignViewModel: ViewTag
|
||||
},
|
||||
{
|
||||
type: 'M2M',
|
||||
ownIdKey: 'attachments_id',
|
||||
ownKey: 'attachments',
|
||||
foreignModel: ViewMediafile
|
||||
foreignViewModel: ViewMediafile
|
||||
},
|
||||
{
|
||||
type: 'nested',
|
||||
ownKey: 'assignment_related_users',
|
||||
foreignModel: ViewAssignmentRelatedUser,
|
||||
foreignViewModel: ViewAssignmentRelatedUser,
|
||||
foreignModel: AssignmentRelatedUser,
|
||||
order: 'weight',
|
||||
relationDefinition: [
|
||||
{
|
||||
type: 'M2O',
|
||||
ownIdKey: 'user_id',
|
||||
ownKey: 'user',
|
||||
foreignModel: ViewUser
|
||||
foreignViewModel: ViewUser
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'nested',
|
||||
ownKey: 'polls',
|
||||
foreignModel: ViewAssignmentPoll,
|
||||
foreignViewModel: ViewAssignmentPoll,
|
||||
foreignModel: AssignmentPoll,
|
||||
relationDefinition: [
|
||||
{
|
||||
type: 'nested',
|
||||
ownKey: 'options',
|
||||
foreignModel: ViewAssignmentPollOption,
|
||||
foreignViewModel: ViewAssignmentPollOption,
|
||||
foreignModel: AssignmentPollOption,
|
||||
order: 'weight',
|
||||
relationDefinition: [
|
||||
{
|
||||
type: 'M2O',
|
||||
ownIdKey: 'user_id',
|
||||
ownKey: 'user',
|
||||
foreignModel: ViewUser
|
||||
foreignViewModel: ViewUser
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -40,9 +40,9 @@ export abstract class BaseHasContentObjectRepository<
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public changedModels(ids: number[]): void {
|
||||
public changedModels(ids: number[], initialLoading: boolean): void {
|
||||
ids.forEach(id => {
|
||||
const v = this.createViewModelWithTitles(this.DS.get(this.collectionString, id));
|
||||
const v = this.createViewModelWithTitles(this.DS.get(this.collectionString, id), initialLoading);
|
||||
this.viewModelStore[id] = v;
|
||||
|
||||
const contentObject = v.contentObjectData;
|
||||
|
@ -42,13 +42,13 @@ export abstract class BaseIsAgendaItemAndListOfSpeakersContentObjectRepository<
|
||||
type: 'M2O',
|
||||
ownIdKey: 'agenda_item_id',
|
||||
ownKey: 'item',
|
||||
foreignModel: ViewItem
|
||||
foreignViewModel: ViewItem
|
||||
});
|
||||
this.relationDefinitions.push({
|
||||
type: 'M2O',
|
||||
ownIdKey: 'list_of_speakers_id',
|
||||
ownKey: 'list_of_speakers',
|
||||
foreignModel: ViewListOfSpeakers
|
||||
foreignViewModel: ViewListOfSpeakers
|
||||
});
|
||||
super.groupRelationsByCollections();
|
||||
}
|
||||
@ -72,8 +72,8 @@ export abstract class BaseIsAgendaItemAndListOfSpeakersContentObjectRepository<
|
||||
return this.getAgendaSlideTitle(titleInformation);
|
||||
};
|
||||
|
||||
protected createViewModelWithTitles(model: M): V {
|
||||
const viewModel = super.createViewModelWithTitles(model);
|
||||
protected createViewModelWithTitles(model: M, initialLoading: boolean): V {
|
||||
const viewModel = super.createViewModelWithTitles(model, initialLoading);
|
||||
viewModel.getAgendaListTitle = () => this.getAgendaListTitle(viewModel);
|
||||
viewModel.getAgendaSlideTitle = () => this.getAgendaSlideTitle(viewModel);
|
||||
viewModel.getListOfSpeakersTitle = () => this.getListOfSpeakersTitle(viewModel);
|
||||
|
@ -68,7 +68,7 @@ export abstract class BaseIsAgendaItemContentObjectRepository<
|
||||
type: 'M2O',
|
||||
ownIdKey: 'agenda_item_id',
|
||||
ownKey: 'item',
|
||||
foreignModel: ViewItem
|
||||
foreignViewModel: ViewItem
|
||||
});
|
||||
super.groupRelationsByCollections();
|
||||
}
|
||||
@ -93,8 +93,8 @@ export abstract class BaseIsAgendaItemContentObjectRepository<
|
||||
/**
|
||||
* Adds the agenda titles to the viewmodel.
|
||||
*/
|
||||
protected createViewModelWithTitles(model: M): V {
|
||||
const viewModel = super.createViewModelWithTitles(model);
|
||||
protected createViewModelWithTitles(model: M, initialLoading: boolean): V {
|
||||
const viewModel = super.createViewModelWithTitles(model, initialLoading);
|
||||
viewModel.getAgendaListTitle = () => this.getAgendaListTitle(viewModel);
|
||||
viewModel.getAgendaSlideTitle = () => this.getAgendaSlideTitle(viewModel);
|
||||
return viewModel;
|
||||
|
@ -66,7 +66,7 @@ export abstract class BaseIsListOfSpeakersContentObjectRepository<
|
||||
type: 'M2O',
|
||||
ownIdKey: 'list_of_speakers_id',
|
||||
ownKey: 'list_of_speakers',
|
||||
foreignModel: ViewListOfSpeakers
|
||||
foreignViewModel: ViewListOfSpeakers
|
||||
});
|
||||
super.groupRelationsByCollections();
|
||||
}
|
||||
@ -82,8 +82,8 @@ export abstract class BaseIsListOfSpeakersContentObjectRepository<
|
||||
/**
|
||||
* Adds the list of speakers titles to the view model
|
||||
*/
|
||||
protected createViewModelWithTitles(model: M): V {
|
||||
const viewModel = super.createViewModelWithTitles(model);
|
||||
protected createViewModelWithTitles(model: M, initialLoading: boolean): V {
|
||||
const viewModel = super.createViewModelWithTitles(model, initialLoading);
|
||||
viewModel.getListOfSpeakersTitle = () => this.getListOfSpeakersTitle(viewModel);
|
||||
viewModel.getListOfSpeakersSlideTitle = () => this.getListOfSpeakersSlideTitle(viewModel);
|
||||
return viewModel;
|
||||
|
@ -153,7 +153,7 @@ export abstract class BaseRepository<V extends BaseViewModel & T, M extends Base
|
||||
relation.type === 'O2M' ||
|
||||
relation.type === 'custom'
|
||||
) {
|
||||
const collection = relation.foreignModel.COLLECTIONSTRING;
|
||||
const collection = relation.foreignViewModel.COLLECTIONSTRING;
|
||||
if (!this.relationsByCollection[collection]) {
|
||||
this.relationsByCollection[collection] = [];
|
||||
}
|
||||
@ -214,9 +214,12 @@ export abstract class BaseRepository<V extends BaseViewModel & T, M extends Base
|
||||
*
|
||||
* @param ids All model ids.
|
||||
*/
|
||||
public changedModels(ids: number[]): void {
|
||||
public changedModels(ids: number[], initialLoading: boolean): void {
|
||||
ids.forEach(id => {
|
||||
this.viewModelStore[id] = this.createViewModelWithTitles(this.DS.get(this.collectionString, id));
|
||||
this.viewModelStore[id] = this.createViewModelWithTitles(
|
||||
this.DS.get(this.collectionString, id),
|
||||
initialLoading
|
||||
);
|
||||
this.updateViewModelObservable(id);
|
||||
});
|
||||
}
|
||||
@ -225,8 +228,13 @@ export abstract class BaseRepository<V extends BaseViewModel & T, M extends Base
|
||||
* After creating a view model, all functions for models form the repo
|
||||
* are assigned to the new view model.
|
||||
*/
|
||||
protected createViewModelWithTitles(model: M): V {
|
||||
const viewModel = this.relationManager.createViewModel(model, this.baseViewModelCtor, this.relationDefinitions);
|
||||
protected createViewModelWithTitles(model: M, initialLoading: boolean): V {
|
||||
const viewModel = this.relationManager.createViewModel(
|
||||
model,
|
||||
this.baseViewModelCtor,
|
||||
this.relationDefinitions,
|
||||
initialLoading
|
||||
);
|
||||
viewModel.getTitle = () => this.getTitle(viewModel);
|
||||
viewModel.getListTitle = () => this.getListTitle(viewModel);
|
||||
viewModel.getVerboseName = this.getVerboseName;
|
||||
|
@ -154,8 +154,8 @@ export class ConfigRepositoryService extends BaseRepository<ViewConfig, Config,
|
||||
throw new Error('Config variables cannot be created');
|
||||
}
|
||||
|
||||
public changedModels(ids: number[]): void {
|
||||
super.changedModels(ids);
|
||||
public changedModels(ids: number[], initialLoading: boolean): void {
|
||||
super.changedModels(ids, initialLoading);
|
||||
|
||||
ids.forEach(id => {
|
||||
this.updateConfigStructure(false, this.viewModelStore[id]);
|
||||
|
@ -23,19 +23,19 @@ const MediafileRelations: RelationDefinition[] = [
|
||||
type: 'M2O',
|
||||
ownIdKey: 'parent_id',
|
||||
ownKey: 'parent',
|
||||
foreignModel: ViewMediafile
|
||||
foreignViewModel: ViewMediafile
|
||||
},
|
||||
{
|
||||
type: 'M2M',
|
||||
ownIdKey: 'access_groups_id',
|
||||
ownKey: 'access_groups',
|
||||
foreignModel: ViewGroup
|
||||
foreignViewModel: ViewGroup
|
||||
},
|
||||
{
|
||||
type: 'M2M',
|
||||
ownIdKey: 'inherited_access_groups_id',
|
||||
ownKey: 'inherited_access_groups',
|
||||
foreignModel: ViewGroup
|
||||
foreignViewModel: ViewGroup
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -20,20 +20,20 @@ const CategoryRelations: RelationDefinition[] = [
|
||||
type: 'M2O',
|
||||
ownIdKey: 'parent_id',
|
||||
ownKey: 'parent',
|
||||
foreignModel: ViewCategory
|
||||
foreignViewModel: ViewCategory
|
||||
},
|
||||
{
|
||||
type: 'O2M',
|
||||
foreignIdKey: 'category_id',
|
||||
ownKey: 'motions',
|
||||
foreignModel: ViewMotion,
|
||||
foreignViewModel: ViewMotion,
|
||||
order: 'category_weight'
|
||||
},
|
||||
{
|
||||
type: 'O2M',
|
||||
foreignIdKey: 'parent_id',
|
||||
ownKey: 'children',
|
||||
foreignModel: ViewCategory,
|
||||
foreignViewModel: ViewCategory,
|
||||
order: 'weight'
|
||||
}
|
||||
];
|
||||
|
@ -20,7 +20,7 @@ const MotionBlockRelations: RelationDefinition[] = [
|
||||
type: 'O2M',
|
||||
foreignIdKey: 'motion_block_id',
|
||||
ownKey: 'motions',
|
||||
foreignModel: ViewMotion
|
||||
foreignViewModel: ViewMotion
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -23,13 +23,13 @@ const MotionCommentSectionRelations: RelationDefinition[] = [
|
||||
type: 'M2M',
|
||||
ownIdKey: 'read_groups_id',
|
||||
ownKey: 'read_groups',
|
||||
foreignModel: ViewGroup
|
||||
foreignViewModel: ViewGroup
|
||||
},
|
||||
{
|
||||
type: 'M2M',
|
||||
ownIdKey: 'write_groups_id',
|
||||
ownKey: 'write_groups',
|
||||
foreignModel: ViewGroup
|
||||
foreignViewModel: ViewGroup
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -16,6 +16,7 @@ import { DiffLinesInParagraph, DiffService } from 'app/core/ui-services/diff.ser
|
||||
import { TreeIdNode } from 'app/core/ui-services/tree.service';
|
||||
import { Motion } from 'app/shared/models/motions/motion';
|
||||
import { MotionPoll } from 'app/shared/models/motions/motion-poll';
|
||||
import { Submitter } from 'app/shared/models/motions/submitter';
|
||||
import { ViewUnifiedChange } from 'app/shared/models/motions/view-unified-change';
|
||||
import { PersonalNoteContent } from 'app/shared/models/users/personal-note';
|
||||
import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
|
||||
@ -73,43 +74,44 @@ const MotionRelations: RelationDefinition[] = [
|
||||
type: 'M2O',
|
||||
ownIdKey: 'state_id',
|
||||
ownKey: 'state',
|
||||
foreignModel: ViewState
|
||||
foreignViewModel: ViewState
|
||||
},
|
||||
{
|
||||
type: 'M2O',
|
||||
ownIdKey: 'recommendation_id',
|
||||
ownKey: 'recommendation',
|
||||
foreignModel: ViewState
|
||||
foreignViewModel: ViewState
|
||||
},
|
||||
{
|
||||
type: 'M2O',
|
||||
ownIdKey: 'workflow_id',
|
||||
ownKey: 'workflow',
|
||||
foreignModel: ViewWorkflow
|
||||
foreignViewModel: ViewWorkflow
|
||||
},
|
||||
{
|
||||
type: 'M2O',
|
||||
ownIdKey: 'category_id',
|
||||
ownKey: 'category',
|
||||
foreignModel: ViewCategory
|
||||
foreignViewModel: ViewCategory
|
||||
},
|
||||
{
|
||||
type: 'M2O',
|
||||
ownIdKey: 'motion_block_id',
|
||||
ownKey: 'motion_block',
|
||||
foreignModel: ViewMotionBlock
|
||||
foreignViewModel: ViewMotionBlock
|
||||
},
|
||||
{
|
||||
type: 'nested',
|
||||
ownKey: 'submitters',
|
||||
foreignModel: ViewSubmitter,
|
||||
foreignViewModel: ViewSubmitter,
|
||||
foreignModel: Submitter,
|
||||
order: 'weight',
|
||||
relationDefinition: [
|
||||
{
|
||||
type: 'M2O',
|
||||
ownIdKey: 'user_id',
|
||||
ownKey: 'user',
|
||||
foreignModel: ViewUser
|
||||
foreignViewModel: ViewUser
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -117,31 +119,31 @@ const MotionRelations: RelationDefinition[] = [
|
||||
type: 'M2M',
|
||||
ownIdKey: 'supporters_id',
|
||||
ownKey: 'supporters',
|
||||
foreignModel: ViewUser
|
||||
foreignViewModel: ViewUser
|
||||
},
|
||||
{
|
||||
type: 'M2M',
|
||||
ownIdKey: 'attachments_id',
|
||||
ownKey: 'attachments',
|
||||
foreignModel: ViewMediafile
|
||||
foreignViewModel: ViewMediafile
|
||||
},
|
||||
{
|
||||
type: 'M2M',
|
||||
ownIdKey: 'tags_id',
|
||||
ownKey: 'tags',
|
||||
foreignModel: ViewTag
|
||||
foreignViewModel: ViewTag
|
||||
},
|
||||
{
|
||||
type: 'M2O',
|
||||
ownIdKey: 'parent_id',
|
||||
ownKey: 'parent',
|
||||
foreignModel: ViewMotion
|
||||
foreignViewModel: ViewMotion
|
||||
},
|
||||
{
|
||||
type: 'M2M',
|
||||
ownIdKey: 'change_recommendations_id',
|
||||
ownKey: 'changeRecommendations',
|
||||
foreignModel: ViewMotionChangeRecommendation
|
||||
foreignViewModel: ViewMotionChangeRecommendation
|
||||
}
|
||||
// Personal notes are dynamically added in the repo.
|
||||
];
|
||||
@ -212,7 +214,7 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
|
||||
protected groupRelationsByCollections(): void {
|
||||
this.relationDefinitions.push({
|
||||
type: 'custom',
|
||||
foreignModel: ViewPersonalNote,
|
||||
foreignViewModel: ViewPersonalNote,
|
||||
setRelations: (motion: Motion, viewMotion: ViewMotion) => {
|
||||
viewMotion.personalNote = this.getPersonalNoteForMotion(motion);
|
||||
},
|
||||
@ -269,8 +271,8 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
|
||||
return this.translate.instant(plural ? 'Motions' : 'Motion');
|
||||
};
|
||||
|
||||
protected createViewModelWithTitles(model: Motion): ViewMotion {
|
||||
const viewModel = super.createViewModelWithTitles(model);
|
||||
protected createViewModelWithTitles(model: Motion, initialLoading: boolean): ViewMotion {
|
||||
const viewModel = super.createViewModelWithTitles(model, initialLoading);
|
||||
viewModel.getIdentifierOrTitle = () => this.getIdentifierOrTitle(viewModel);
|
||||
viewModel.getProjectorTitle = () => this.getAgendaSlideTitle(viewModel);
|
||||
return viewModel;
|
||||
|
@ -18,13 +18,13 @@ const StateRelations: RelationDefinition[] = [
|
||||
type: 'M2O',
|
||||
ownIdKey: 'workflow_id',
|
||||
ownKey: 'workflow',
|
||||
foreignModel: ViewWorkflow
|
||||
foreignViewModel: ViewWorkflow
|
||||
},
|
||||
{
|
||||
type: 'M2M',
|
||||
ownIdKey: 'next_states_id',
|
||||
ownKey: 'next_states',
|
||||
foreignModel: ViewState
|
||||
foreignViewModel: ViewState
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -19,13 +19,13 @@ const WorkflowRelations: RelationDefinition[] = [
|
||||
type: 'M2M',
|
||||
ownIdKey: 'states_id',
|
||||
ownKey: 'states',
|
||||
foreignModel: ViewState
|
||||
foreignViewModel: ViewState
|
||||
},
|
||||
{
|
||||
type: 'M2O',
|
||||
ownIdKey: 'first_state_id',
|
||||
ownKey: 'first_state',
|
||||
foreignModel: ViewState
|
||||
foreignViewModel: ViewState
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -28,7 +28,7 @@ const ProjectorRelations: RelationDefinition[] = [
|
||||
type: 'M2O',
|
||||
ownIdKey: 'reference_projector_id',
|
||||
ownKey: 'referenceProjector',
|
||||
foreignModel: ViewProjector
|
||||
foreignViewModel: ViewProjector
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -18,7 +18,7 @@ const TopicRelations: RelationDefinition[] = [
|
||||
type: 'M2M',
|
||||
ownIdKey: 'attachments_id',
|
||||
ownKey: 'attachments',
|
||||
foreignModel: ViewMediafile
|
||||
foreignViewModel: ViewMediafile
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -30,7 +30,7 @@ const UserRelations: RelationDefinition[] = [
|
||||
type: 'M2M',
|
||||
ownIdKey: 'groups_id',
|
||||
ownKey: 'groups',
|
||||
foreignModel: ViewGroup
|
||||
foreignViewModel: ViewGroup
|
||||
}
|
||||
];
|
||||
|
||||
@ -147,8 +147,8 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User, UserTi
|
||||
/**
|
||||
* Adds teh short and full name to the view user.
|
||||
*/
|
||||
protected createViewModelWithTitles(model: User): ViewUser {
|
||||
const viewModel = super.createViewModelWithTitles(model);
|
||||
protected createViewModelWithTitles(model: User, initialLoading: boolean): ViewUser {
|
||||
const viewModel = super.createViewModelWithTitles(model, initialLoading);
|
||||
viewModel.getFullName = () => this.getFullName(viewModel);
|
||||
viewModel.getShortName = () => this.getShortName(viewModel);
|
||||
return viewModel;
|
||||
|
@ -15,8 +15,12 @@ export interface AssignmentOptionVote {
|
||||
export class AssignmentPollOption extends BaseModel<AssignmentPollOption> {
|
||||
public static COLLECTIONSTRING = 'assignments/assignment-poll-option';
|
||||
|
||||
public id: number; // The AssignmentUser id of the candidate
|
||||
public candidate_id: number; // the User id of the candidate
|
||||
public id: number; // The AssignmentPollOption id
|
||||
public candidate_id: number; // the user id of the candidate
|
||||
public get user_id(): number {
|
||||
// to be consistent with user...
|
||||
return this.candidate_id;
|
||||
}
|
||||
public is_elected: boolean;
|
||||
public votes: AssignmentOptionVote[];
|
||||
public poll_id: number;
|
||||
|
@ -29,11 +29,8 @@ export class ViewAssignmentPollOption extends BaseViewModel<AssignmentPollOption
|
||||
return this.option.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: "User" instead of "candidate" to be consistent.
|
||||
*/
|
||||
public get user_id(): number {
|
||||
return this.option.candidate_id;
|
||||
return this.option.user_id;
|
||||
}
|
||||
|
||||
public get is_elected(): boolean {
|
||||
|
@ -186,7 +186,7 @@ class RedisCacheProvider:
|
||||
if (nd > 0) then
|
||||
max = 3 + nc + nd
|
||||
redis.call('hdel', KEYS[1], unpack(ARGV, 4 + nc, max))
|
||||
for i = 4 + nc, max, 2 do
|
||||
for i = 4 + nc, max, 1 do
|
||||
redis.call('zadd', KEYS[2], change_id, ARGV[i])
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user