Fix issues with minification

This commit is contained in:
FinnStutzenstein 2019-02-12 09:25:56 +01:00
parent 841d80a35b
commit cc4d5a5739
30 changed files with 120 additions and 113 deletions

View File

@ -17,7 +17,7 @@ export interface ModelEntry extends BaseModelEntry {
} }
export interface SearchableModelEntry extends BaseModelEntry { export interface SearchableModelEntry extends BaseModelEntry {
viewModel: new (...args: any[]) => BaseViewModel & Searchable; viewModel: ViewModelConstructor<BaseViewModel & Searchable>;
searchOrder: number; searchOrder: number;
} }

View File

@ -129,7 +129,7 @@ export class AutoupdateService {
* @returns A list of basemodels constructed from the given models. * @returns A list of basemodels constructed from the given models.
*/ */
private mapObjectsToBaseModels(collection: string, models: object[]): BaseModel[] { private mapObjectsToBaseModels(collection: string, models: object[]): BaseModel[] {
const targetClass = this.modelMapper.getModelConstructorFromCollectionString(collection); const targetClass = this.modelMapper.getModelConstructor(collection);
if (!targetClass) { if (!targetClass) {
throw new Error(`Unregistered resource ${collection}`); throw new Error(`Unregistered resource ${collection}`);
} }

View File

@ -5,20 +5,22 @@ import { BaseRepository } from 'app/core/repositories/base-repository';
import { ViewModelConstructor, BaseViewModel } from 'app/site/base/base-view-model'; import { ViewModelConstructor, BaseViewModel } from 'app/site/base/base-view-model';
/** /**
* Holds a mapping entry with the matching collection string, * Unifies the ModelConstructor and ViewModelConstructor.
* model constructor, view model constructor and the repository
*/ */
type MappingEntry = [ interface UnifiedConstructors {
string, COLLECTIONSTRING: string;
ModelConstructor<BaseModel>, new (...args: any[]): any;
ViewModelConstructor<BaseViewModel>, }
BaseRepository<BaseViewModel, BaseModel>
]; /**
* Every types supported: (View)ModelConstructors, repos and collectionstrings.
*/
type TypeIdentifier = UnifiedConstructors | BaseRepository<any, any> | string;
/** /**
* Registeres the mapping between collection strings, models constructors, view * Registeres the mapping between collection strings, models constructors, view
* model constructors and repositories. * model constructors and repositories.
* All models ned to be registered! * All models need to be registered!
*/ */
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -28,28 +30,11 @@ export class CollectionStringMapperService {
* Maps collection strings to mapping entries * Maps collection strings to mapping entries
*/ */
private collectionStringMapping: { private collectionStringMapping: {
[collectionString: string]: MappingEntry; [collectionString: string]: [
} = {}; ModelConstructor<BaseModel>,
ViewModelConstructor<BaseViewModel>,
/** BaseRepository<BaseViewModel, BaseModel>
* Maps models to mapping entries ];
*/
private modelMapping: {
[modelName: string]: MappingEntry;
} = {};
/**
* Maps view models to mapping entries
*/
private viewModelMapping: {
[viewModelname: string]: MappingEntry;
} = {};
/**
* Maps repositories to mapping entries
*/
private repositoryMapping: {
[repositoryName: string]: MappingEntry;
} = {}; } = {};
public constructor() {} public constructor() {}
@ -65,71 +50,42 @@ export class CollectionStringMapperService {
viewModel: ViewModelConstructor<V>, viewModel: ViewModelConstructor<V>,
repository: BaseRepository<V, M> repository: BaseRepository<V, M>
): void { ): void {
const entry: MappingEntry = [collectionString, model, viewModel, repository]; this.collectionStringMapping[collectionString] = [model, viewModel, repository];
this.collectionStringMapping[collectionString] = entry;
this.modelMapping[model.name] = entry;
this.viewModelMapping[viewModel.name] = entry;
this.repositoryMapping[repository.name] = entry;
} }
// The following accessors are for giving one of EntryType by given a different object /**
// of EntryType. * @param obj The object to get the collection string from.
* @returns the collectionstring
public getCollectionStringFromModelConstructor<M extends BaseModel>(ctor: ModelConstructor<M>): string { */
return this.modelMapping[ctor.name][0]; public getCollectionString(obj: TypeIdentifier): string {
} if (typeof obj === 'string') {
public getCollectionStringFromViewModelConstructor<V extends BaseViewModel>(ctor: ViewModelConstructor<V>): string { return obj;
return this.viewModelMapping[ctor.name][0]; } else {
} return obj.COLLECTIONSTRING;
public getCollectionStringFromRepository<M extends BaseModel, V extends BaseViewModel>( }
repository: BaseRepository<V, M>
): string {
return this.repositoryMapping[repository.name][0];
} }
public getModelConstructorFromCollectionString<M extends BaseModel>(collectionString: string): ModelConstructor<M> { /**
return this.collectionStringMapping[collectionString][1] as ModelConstructor<M>; * @param obj The object to get the model constructor from.
} * @returns the model constructor
public getModelConstructorFromViewModelConstructor<V extends BaseViewModel, M extends BaseModel>( */
ctor: ViewModelConstructor<V> public getModelConstructor<M extends BaseModel>(obj: TypeIdentifier): ModelConstructor<M> {
): ModelConstructor<M> { return this.collectionStringMapping[this.getCollectionString(obj)][0] as ModelConstructor<M>;
return this.viewModelMapping[ctor.name][1] as ModelConstructor<M>;
}
public getModelConstructorFromRepository<V extends BaseViewModel, M extends BaseModel>(
repository: BaseRepository<V, M>
): ModelConstructor<M> {
return this.repositoryMapping[repository.name][1] as ModelConstructor<M>;
} }
public getViewModelConstructorFromCollectionString<M extends BaseViewModel>( /**
collectionString: string * @param obj The object to get the view model constructor from.
): ViewModelConstructor<M> { * @returns the view model constructor
return this.collectionStringMapping[collectionString][2] as ViewModelConstructor<M>; */
} public getViewModelConstructor<M extends BaseViewModel>(obj: TypeIdentifier): ViewModelConstructor<M> {
public getViewModelConstructorFromModelConstructor<V extends BaseViewModel, M extends BaseModel>( return this.collectionStringMapping[this.getCollectionString(obj)][1] as ViewModelConstructor<M>;
ctor: ModelConstructor<M>
): ViewModelConstructor<V> {
return this.modelMapping[ctor.name][2] as ViewModelConstructor<V>;
}
public getViewModelConstructorFromRepository<V extends BaseViewModel, M extends BaseModel>(
repository: BaseRepository<V, M>
): ViewModelConstructor<V> {
return this.repositoryMapping[repository.name][2] as ViewModelConstructor<V>;
} }
public getRepositoryFromCollectionString<V extends BaseViewModel, M extends BaseModel>( /**
collectionString: string * @param obj The object to get the repository from.
): BaseRepository<V, M> { * @returns the repository
return this.collectionStringMapping[collectionString][3] as BaseRepository<V, M>; */
} public getRepository<V extends BaseViewModel, M extends BaseModel>(obj: TypeIdentifier): BaseRepository<V, M> {
public getRepositoryFromModelConstructor<V extends BaseViewModel, M extends BaseModel>( return this.collectionStringMapping[this.getCollectionString(obj)][2] as BaseRepository<V, M>;
ctor: ModelConstructor<M>
): BaseRepository<V, M> {
return this.modelMapping[ctor.name][3] as BaseRepository<V, M>;
}
public getRepositoryFromViewModelConstructor<V extends BaseViewModel, M extends BaseModel>(
ctor: ViewModelConstructor<V>
): BaseRepository<V, M> {
return this.viewModelMapping[ctor.name][3] as BaseRepository<V, M>;
} }
} }

View File

@ -187,7 +187,7 @@ export class DataStoreService {
const storage: ModelStorage = {}; const storage: ModelStorage = {};
Object.keys(serializedStore).forEach(collectionString => { Object.keys(serializedStore).forEach(collectionString => {
storage[collectionString] = {} as ModelCollection; storage[collectionString] = {} as ModelCollection;
const target = this.modelMapper.getModelConstructorFromCollectionString(collectionString); const target = this.modelMapper.getModelConstructor(collectionString);
if (target) { if (target) {
Object.keys(serializedStore[collectionString]).forEach(id => { Object.keys(serializedStore[collectionString]).forEach(id => {
const data = JSON.parse(serializedStore[collectionString][id]); const data = JSON.parse(serializedStore[collectionString][id]);
@ -218,7 +218,7 @@ export class DataStoreService {
if (typeof collectionType === 'string') { if (typeof collectionType === 'string') {
return collectionType; return collectionType;
} else { } else {
return this.modelMapper.getCollectionStringFromModelConstructor(collectionType); return this.modelMapper.getCollectionString(collectionType);
} }
} }

View File

@ -68,7 +68,7 @@ export class TimeTravelService {
[collectionString, id] = historyObject.element_id.split(':'); [collectionString, id] = historyObject.element_id.split(':');
if (historyObject.full_data) { if (historyObject.full_data) {
const targetClass = this.modelMapperService.getModelConstructorFromCollectionString(collectionString); const targetClass = this.modelMapperService.getModelConstructor(collectionString);
await this.DS.add([new targetClass(historyObject.full_data)]); await this.DS.add([new targetClass(historyObject.full_data)]);
} else { } else {
await this.DS.remove(collectionString, [+id]); await this.DS.remove(collectionString, [+id]);

View File

@ -23,11 +23,7 @@ export class ViewModelStoreService {
private getRepository<T extends BaseViewModel>( private getRepository<T extends BaseViewModel>(
collectionType: ViewModelConstructor<T> | string collectionType: ViewModelConstructor<T> | string
): BaseRepository<T, any> { ): BaseRepository<T, any> {
if (typeof collectionType === 'string') { return this.mapperService.getRepository(collectionType) as BaseRepository<T, any>;
return this.mapperService.getRepositoryFromCollectionString(collectionType) as BaseRepository<T, any>;
} else {
return this.mapperService.getRepositoryFromViewModelConstructor(collectionType as ViewModelConstructor<T>);
}
} }
/** /**

View File

@ -8,8 +8,10 @@ import { Identifiable } from '../../shared/models/base/identifiable';
import { auditTime } from 'rxjs/operators'; import { auditTime } from 'rxjs/operators';
import { ViewModelStoreService } from '../core-services/view-model-store.service'; import { ViewModelStoreService } from '../core-services/view-model-store.service';
import { OnAfterAppsLoaded } from '../onAfterAppsLoaded'; import { OnAfterAppsLoaded } from '../onAfterAppsLoaded';
import { Collection } from 'app/shared/models/base/collection';
export abstract class BaseRepository<V extends BaseViewModel, M extends BaseModel> implements OnAfterAppsLoaded { export abstract class BaseRepository<V extends BaseViewModel, M extends BaseModel>
implements OnAfterAppsLoaded, Collection {
/** /**
* Stores all the viewModel in an object * Stores all the viewModel in an object
*/ */
@ -30,10 +32,18 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
*/ */
protected readonly generalViewModelSubject: Subject<V> = new Subject<V>(); protected readonly generalViewModelSubject: Subject<V> = new Subject<V>();
private _name: string; private _collectionString: string;
public get name(): string { public get collectionString(): string {
return this._name; return this._collectionString;
}
/**
* Needed for the collectionStringMapper service to treat repositories the same as
* ModelConstructors and ViewModelConstructors.
*/
public get COLLECTIONSTRING(): string {
return this._collectionString;
} }
/** /**
@ -52,7 +62,7 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
protected baseModelCtor: ModelConstructor<M>, protected baseModelCtor: ModelConstructor<M>,
protected depsModelCtors?: ModelConstructor<BaseModel>[] protected depsModelCtors?: ModelConstructor<BaseModel>[]
) { ) {
this._name = baseModelCtor.name; this._collectionString = baseModelCtor.COLLECTIONSTRING;
} }
public onAfterAppsLoaded(): void { public onAfterAppsLoaded(): void {
@ -82,10 +92,7 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
// My quess: This must trigger an autoupdate also for this model, because some IDs changed, so the // My quess: This must trigger an autoupdate also for this model, because some IDs changed, so the
// affected models will be newly created by the primaryModelChangeSubject. // affected models will be newly created by the primaryModelChangeSubject.
this.DS.deletedObservable.subscribe(model => { this.DS.deletedObservable.subscribe(model => {
if ( if (model.collection === this.collectionStringMapperService.getCollectionString(this.baseModelCtor)) {
model.collection ===
this.collectionStringMapperService.getCollectionStringFromModelConstructor(this.baseModelCtor)
) {
delete this.viewModelStore[model.id]; delete this.viewModelStore[model.id];
this.updateAllObservables(model.id); this.updateAllObservables(model.id);
} }

View File

@ -2,7 +2,10 @@ import { Deserializable } from './deserializable';
import { Identifiable } from './identifiable'; import { Identifiable } from './identifiable';
import { Collection } from './collection'; import { Collection } from './collection';
export type ModelConstructor<T extends BaseModel<T>> = new (...args: any[]) => T; export interface ModelConstructor<T extends BaseModel<T>> {
COLLECTIONSTRING: string;
new (...args: any[]): T;
}
/** /**
* Abstract parent class to set rules and functions for all models. * Abstract parent class to set rules and functions for all models.

View File

@ -4,6 +4,8 @@ import { Speaker } from 'app/shared/models/agenda/speaker';
import { BaseAgendaViewModel, isAgendaBaseModel } from 'app/site/base/base-agenda-view-model'; import { BaseAgendaViewModel, isAgendaBaseModel } from 'app/site/base/base-agenda-view-model';
export class ViewItem extends BaseViewModel { export class ViewItem extends BaseViewModel {
public static COLLECTIONSTRING = Item.COLLECTIONSTRING;
private _item: Item; private _item: Item;
private _contentObject: BaseAgendaViewModel; private _contentObject: BaseAgendaViewModel;

View File

@ -11,6 +11,8 @@ import { BaseViewModel } from 'app/site/base/base-view-model';
* @ignore * @ignore
*/ */
export class ViewTopic extends BaseAgendaViewModel { export class ViewTopic extends BaseAgendaViewModel {
public static COLLECTIONSTRING = Topic.COLLECTIONSTRING;
protected _topic: Topic; protected _topic: Topic;
private _attachments: ViewMediafile[]; private _attachments: ViewMediafile[];
private _agendaItem: ViewItem; private _agendaItem: ViewItem;

View File

@ -8,6 +8,8 @@ import { ViewTag } from 'app/site/tags/models/view-tag';
import { BaseViewModel } from 'app/site/base/base-view-model'; import { BaseViewModel } from 'app/site/base/base-view-model';
export class ViewAssignment extends BaseAgendaViewModel { export class ViewAssignment extends BaseAgendaViewModel {
public static COLLECTIONSTRING = Assignment.COLLECTIONSTRING;
private _assignment: Assignment; private _assignment: Assignment;
private _relatedUser: ViewUser[]; private _relatedUser: ViewUser[];
private _agendaItem: ViewItem; private _agendaItem: ViewItem;

View File

@ -2,7 +2,10 @@ import { Displayable } from './displayable';
import { Identifiable } from '../../shared/models/base/identifiable'; import { Identifiable } from '../../shared/models/base/identifiable';
import { Collection } from 'app/shared/models/base/collection'; import { Collection } from 'app/shared/models/base/collection';
export type ViewModelConstructor<T extends BaseViewModel> = new (...args: any[]) => T; export interface ViewModelConstructor<T extends BaseViewModel> {
COLLECTIONSTRING: string;
new (...args: any[]): T;
}
/** /**
* Base class for view models. alls view models should have titles. * Base class for view models. alls view models should have titles.

View File

@ -2,6 +2,8 @@ import { ChatMessage } from 'app/shared/models/core/chat-message';
import { BaseViewModel } from 'app/site/base/base-view-model'; import { BaseViewModel } from 'app/site/base/base-view-model';
export class ViewChatMessage extends BaseViewModel { export class ViewChatMessage extends BaseViewModel {
public static COLLECTIONSTRING = ChatMessage.COLLECTIONSTRING;
private _chatMessage: ChatMessage; private _chatMessage: ChatMessage;
/** /**

View File

@ -36,6 +36,8 @@ interface ConfigConstant {
* The view model for configs. * The view model for configs.
*/ */
export class ViewConfig extends BaseViewModel { export class ViewConfig extends BaseViewModel {
public static COLLECTIONSTRING = Config.COLLECTIONSTRING;
/** /**
* The underlying config. * The underlying config.
*/ */
@ -62,15 +64,15 @@ export class ViewConfig extends BaseViewModel {
} }
public get id(): number { public get id(): number {
return this.config ? this.config.id : null; return this.config.id;
} }
public get key(): string { public get key(): string {
return this.config ? this.config.key : null; return this.config.key;
} }
public get value(): Object { public get value(): Object {
return this.config ? this.config.value : null; return this.config.value;
} }
public get label(): string { public get label(): string {

View File

@ -6,6 +6,8 @@ import { ViewUser } from 'app/site/users/models/view-user';
* View model for history objects * View model for history objects
*/ */
export class ViewHistory extends BaseViewModel { export class ViewHistory extends BaseViewModel {
public static COLLECTIONSTRING = History.COLLECTIONSTRING;
/** /**
* Private BaseModel of the history * Private BaseModel of the history
*/ */

View File

@ -5,6 +5,8 @@ import { SearchRepresentation } from 'app/core/ui-services/search.service';
import { ViewUser } from 'app/site/users/models/view-user'; import { ViewUser } from 'app/site/users/models/view-user';
export class ViewMediafile extends BaseViewModel implements Searchable { export class ViewMediafile extends BaseViewModel implements Searchable {
public static COLLECTIONSTRING = Mediafile.COLLECTIONSTRING;
private _mediafile: Mediafile; private _mediafile: Mediafile;
private _uploader: ViewUser; private _uploader: ViewUser;

View File

@ -11,6 +11,8 @@ import { Searchable } from 'app/site/base/searchable';
* @ignore * @ignore
*/ */
export class ViewCategory extends BaseViewModel implements Searchable { export class ViewCategory extends BaseViewModel implements Searchable {
public static COLLECTIONSTRING = Category.COLLECTIONSTRING;
private _category: Category; private _category: Category;
public get category(): Category { public get category(): Category {

View File

@ -11,6 +11,8 @@ import { ViewUnifiedChange, ViewUnifiedChangeType } from './view-unified-change'
* @ignore * @ignore
*/ */
export class ViewMotionChangeRecommendation extends BaseViewModel implements ViewUnifiedChange { export class ViewMotionChangeRecommendation extends BaseViewModel implements ViewUnifiedChange {
public static COLLECTIONSTRING = MotionChangeRecommendation.COLLECTIONSTRING;
private _changeRecommendation: MotionChangeRecommendation; private _changeRecommendation: MotionChangeRecommendation;
public get id(): number { public get id(): number {

View File

@ -11,6 +11,8 @@ import { BaseViewModel } from 'app/site/base/base-view-model';
* @ignore * @ignore
*/ */
export class ViewMotionBlock extends BaseAgendaViewModel implements Searchable { export class ViewMotionBlock extends BaseAgendaViewModel implements Searchable {
public static COLLECTIONSTRING = MotionBlock.COLLECTIONSTRING;
private _motionBlock: MotionBlock; private _motionBlock: MotionBlock;
private _agendaItem: ViewItem; private _agendaItem: ViewItem;

View File

@ -10,6 +10,8 @@ import { ViewGroup } from 'app/site/users/models/view-group';
* @ignore * @ignore
*/ */
export class ViewMotionCommentSection extends BaseViewModel { export class ViewMotionCommentSection extends BaseViewModel {
public static COLLECTIONSTRING = MotionCommentSection.COLLECTIONSTRING;
private _section: MotionCommentSection; private _section: MotionCommentSection;
private _readGroups: ViewGroup[]; private _readGroups: ViewGroup[];

View File

@ -45,6 +45,8 @@ export enum ChangeRecoMode {
* @ignore * @ignore
*/ */
export class ViewMotion extends BaseAgendaViewModel implements Searchable { export class ViewMotion extends BaseAgendaViewModel implements Searchable {
public static COLLECTIONSTRING = Motion.COLLECTIONSTRING;
protected _motion: Motion; protected _motion: Motion;
protected _category: ViewCategory; protected _category: ViewCategory;
protected _submitters: ViewUser[]; protected _submitters: ViewUser[];

View File

@ -11,6 +11,8 @@ import { SearchRepresentation } from 'app/core/ui-services/search.service';
* @ignore * @ignore
*/ */
export class ViewStatuteParagraph extends BaseViewModel implements Searchable { export class ViewStatuteParagraph extends BaseViewModel implements Searchable {
public static COLLECTIONSTRING = StatuteParagraph.COLLECTIONSTRING;
private _paragraph: StatuteParagraph; private _paragraph: StatuteParagraph;
public get statuteParagraph(): StatuteParagraph { public get statuteParagraph(): StatuteParagraph {

View File

@ -7,6 +7,8 @@ import { BaseViewModel } from '../../base/base-view-model';
* @ignore * @ignore
*/ */
export class ViewWorkflow extends BaseViewModel { export class ViewWorkflow extends BaseViewModel {
public static COLLECTIONSTRING = Workflow.COLLECTIONSTRING;
private _workflow: Workflow; private _workflow: Workflow;
public get workflow(): Workflow { public get workflow(): Workflow {

View File

@ -4,6 +4,8 @@ import { ProjectorElementBuildDeskriptor } from 'app/site/base/projectable';
import { BaseViewModel } from 'app/site/base/base-view-model'; import { BaseViewModel } from 'app/site/base/base-view-model';
export class ViewCountdown extends BaseProjectableViewModel { export class ViewCountdown extends BaseProjectableViewModel {
public static COLLECTIONSTRING = Countdown.COLLECTIONSTRING;
private _countdown: Countdown; private _countdown: Countdown;
public get countdown(): Countdown { public get countdown(): Countdown {

View File

@ -2,6 +2,8 @@ import { BaseViewModel } from '../../base/base-view-model';
import { Projector, ProjectorElements } from 'app/shared/models/core/projector'; import { Projector, ProjectorElements } from 'app/shared/models/core/projector';
export class ViewProjector extends BaseViewModel { export class ViewProjector extends BaseViewModel {
public static COLLECTIONSTRING = Projector.COLLECTIONSTRING;
private _projector: Projector; private _projector: Projector;
public get projector(): Projector { public get projector(): Projector {

View File

@ -4,6 +4,8 @@ import { ProjectorMessage } from 'app/shared/models/core/projector-message';
import { BaseViewModel } from 'app/site/base/base-view-model'; import { BaseViewModel } from 'app/site/base/base-view-model';
export class ViewProjectorMessage extends BaseProjectableViewModel { export class ViewProjectorMessage extends BaseProjectableViewModel {
public static COLLECTIONSTRING = ProjectorMessage.COLLECTIONSTRING;
private _message: ProjectorMessage; private _message: ProjectorMessage;
public get projctormessage(): ProjectorMessage { public get projctormessage(): ProjectorMessage {

View File

@ -11,6 +11,8 @@ import { Searchable } from 'app/site/base/searchable';
* @ignore * @ignore
*/ */
export class ViewTag extends BaseViewModel implements Searchable { export class ViewTag extends BaseViewModel implements Searchable {
public static COLLECTIONSTRING = Tag.COLLECTIONSTRING;
private _tag: Tag; private _tag: Tag;
public get tag(): Tag { public get tag(): Tag {

View File

@ -2,6 +2,8 @@ import { BaseViewModel } from '../../base/base-view-model';
import { Group } from 'app/shared/models/users/group'; import { Group } from 'app/shared/models/users/group';
export class ViewGroup extends BaseViewModel { export class ViewGroup extends BaseViewModel {
public static COLLECTIONSTRING = Group.COLLECTIONSTRING;
private _group: Group; private _group: Group;
public get group(): Group { public get group(): Group {

View File

@ -2,6 +2,8 @@ import { BaseViewModel } from 'app/site/base/base-view-model';
import { PersonalNote } from 'app/shared/models/users/personal-note'; import { PersonalNote } from 'app/shared/models/users/personal-note';
export class ViewPersonalNote extends BaseViewModel { export class ViewPersonalNote extends BaseViewModel {
public static COLLECTIONSTRING = PersonalNote.COLLECTIONSTRING;
private _personalNote: PersonalNote; private _personalNote: PersonalNote;
public get personalNote(): PersonalNote { public get personalNote(): PersonalNote {

View File

@ -7,6 +7,8 @@ import { ViewGroup } from './view-group';
import { BaseViewModel } from 'app/site/base/base-view-model'; import { BaseViewModel } from 'app/site/base/base-view-model';
export class ViewUser extends BaseProjectableViewModel implements Searchable { export class ViewUser extends BaseProjectableViewModel implements Searchable {
public static COLLECTIONSTRING = User.COLLECTIONSTRING;
private _user: User; private _user: User;
private _groups: ViewGroup[]; private _groups: ViewGroup[];