Add classes for models, rework datastore, injections
- Basic construction and datatypes of all objects - create objects out of websocket response - autoupdate service - re-structure core models - DataStore is easier to use
This commit is contained in:
parent
2b60b4ef4f
commit
2331ecd6b8
@ -1,6 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { OpenslidesService } from './core/services/openslides.service';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { OpenslidesService } from 'app/core/services/openslides.service';
|
||||||
|
import { AutoupdateService } from 'app/core/services/autoupdate.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -8,7 +9,11 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
styleUrls: ['./app.component.css']
|
styleUrls: ['./app.component.css']
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
constructor(private openSlides: OpenslidesService, public translate: TranslateService) {
|
constructor(
|
||||||
|
private openSlides: OpenslidesService,
|
||||||
|
private autoupdate: AutoupdateService,
|
||||||
|
private translate: TranslateService
|
||||||
|
) {
|
||||||
// manually add the supported languages
|
// manually add the supported languages
|
||||||
translate.addLangs(['en', 'de', 'fr']);
|
translate.addLangs(['en', 'de', 'fr']);
|
||||||
// this language will be used as a fallback when a translation isn't found in the current language
|
// this language will be used as a fallback when a translation isn't found in the current language
|
||||||
|
@ -34,10 +34,7 @@ import { MotionsComponent } from './site/motions/motions.component';
|
|||||||
import { AgendaComponent } from './site/agenda/agenda.component';
|
import { AgendaComponent } from './site/agenda/agenda.component';
|
||||||
import { SiteComponent } from './site/site.component';
|
import { SiteComponent } from './site/site.component';
|
||||||
import { StartComponent } from './site/start/start.component';
|
import { StartComponent } from './site/start/start.component';
|
||||||
import { ToastComponent } from './core/directives/toast/toast.component';
|
|
||||||
import { ToastService } from './core/services/toast.service';
|
|
||||||
import { WebsocketService } from './core/services/websocket.service';
|
import { WebsocketService } from './core/services/websocket.service';
|
||||||
import { DS } from './core/services/DS.service';
|
|
||||||
import { ProjectorContainerComponent } from './projector-container/projector-container.component';
|
import { ProjectorContainerComponent } from './projector-container/projector-container.component';
|
||||||
import { AlertComponent } from './core/directives/alert/alert.component';
|
import { AlertComponent } from './core/directives/alert/alert.component';
|
||||||
|
|
||||||
@ -62,7 +59,6 @@ library.add(fas);
|
|||||||
AgendaComponent,
|
AgendaComponent,
|
||||||
SiteComponent,
|
SiteComponent,
|
||||||
StartComponent,
|
StartComponent,
|
||||||
ToastComponent,
|
|
||||||
ProjectorContainerComponent,
|
ProjectorContainerComponent,
|
||||||
AlertComponent
|
AlertComponent
|
||||||
],
|
],
|
||||||
@ -96,7 +92,7 @@ library.add(fas);
|
|||||||
}),
|
}),
|
||||||
AppRoutingModule
|
AppRoutingModule
|
||||||
],
|
],
|
||||||
providers: [Title, ToastService, WebsocketService, DS],
|
providers: [Title, WebsocketService],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
@ -1,12 +1,39 @@
|
|||||||
|
import { Injector } from '@angular/core';
|
||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
|
import { DataStoreService } from 'app/core/services/DS.service';
|
||||||
|
// import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
//provides functions that might be used by a lot of components
|
// provides functions that might be used by a lot of components
|
||||||
export abstract class BaseComponent {
|
export abstract class BaseComponent {
|
||||||
|
protected injector: Injector;
|
||||||
|
protected dataStore: DataStoreService;
|
||||||
|
// would die in every scope change. disabled for now
|
||||||
|
// protected _translateService: TranslateService;
|
||||||
private titleSuffix = ' - OpenSlides 3';
|
private titleSuffix = ' - OpenSlides 3';
|
||||||
|
|
||||||
constructor(protected titleService: Title) {}
|
constructor(protected titleService?: Title) {
|
||||||
|
// throws a warning even tho it is the new syntax. Ignored for now.
|
||||||
|
this.injector = Injector.create([{ provide: DataStoreService, useClass: DataStoreService, deps: [] }]);
|
||||||
|
// this._injector = Injector.create([{ provide: TranslateService, useClass: TranslateService, deps: [] }]);
|
||||||
|
}
|
||||||
|
|
||||||
setTitle(prefix: string) {
|
setTitle(prefix: string) {
|
||||||
this.titleService.setTitle(prefix + this.titleSuffix);
|
this.titleService.setTitle(prefix + this.titleSuffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static injection of DataStore (ds) in all child instancces of BaseComponent
|
||||||
|
// use this.DS[...]
|
||||||
|
get DS(): DataStoreService {
|
||||||
|
if (this.dataStore == null) {
|
||||||
|
this.dataStore = this.injector.get(DataStoreService);
|
||||||
|
}
|
||||||
|
return this.dataStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get translate(): TranslateService {
|
||||||
|
// if (this._translateService == null) {
|
||||||
|
// this._translateService = this._injector.get(TranslateService);
|
||||||
|
// }
|
||||||
|
// return this._translateService;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
54
client/src/app/core/models/agenda/item.ts
Normal file
54
client/src/app/core/models/agenda/item.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Item extends BaseModel {
|
||||||
|
static collectionString = 'agenda/item';
|
||||||
|
id: number;
|
||||||
|
closed: boolean;
|
||||||
|
comment: string;
|
||||||
|
content_object: Object;
|
||||||
|
duration: number; //time?
|
||||||
|
is_hidden: boolean;
|
||||||
|
item_number: string;
|
||||||
|
list_view_title: string;
|
||||||
|
parent_id: number;
|
||||||
|
speaker_list_closed: boolean;
|
||||||
|
speakers: BaseModel[]; //we should not know users just yet
|
||||||
|
title: string;
|
||||||
|
type: number;
|
||||||
|
weight: number;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: number,
|
||||||
|
closed?: boolean,
|
||||||
|
comment?: string,
|
||||||
|
content_object?: Object,
|
||||||
|
duration?: number,
|
||||||
|
is_hidden?: boolean,
|
||||||
|
item_number?: string,
|
||||||
|
list_view_title?: string,
|
||||||
|
parent_id?: number,
|
||||||
|
speaker_list_closed?: boolean,
|
||||||
|
speakers?: BaseModel[],
|
||||||
|
title?: string,
|
||||||
|
type?: number,
|
||||||
|
weight?: number
|
||||||
|
) {
|
||||||
|
super(id);
|
||||||
|
this.comment = comment;
|
||||||
|
this.content_object = content_object;
|
||||||
|
this.duration = duration;
|
||||||
|
this.is_hidden = is_hidden;
|
||||||
|
this.item_number = item_number;
|
||||||
|
this.list_view_title = list_view_title;
|
||||||
|
this.parent_id = parent_id;
|
||||||
|
this.speaker_list_closed = speaker_list_closed;
|
||||||
|
this.speakers = speakers;
|
||||||
|
this.title = title;
|
||||||
|
this.type = type;
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Item.collectionString;
|
||||||
|
}
|
||||||
|
}
|
41
client/src/app/core/models/assignments/assignment.ts
Normal file
41
client/src/app/core/models/assignments/assignment.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Assignment extends BaseModel {
|
||||||
|
static collectionString = 'assignments/assignment';
|
||||||
|
id: number;
|
||||||
|
agenda_item_id: number;
|
||||||
|
description: string;
|
||||||
|
open_posts: number;
|
||||||
|
phase: number;
|
||||||
|
poll_description_default: number;
|
||||||
|
polls: Object[];
|
||||||
|
tags_id: number[];
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: number,
|
||||||
|
agenda_item_id?: number,
|
||||||
|
description?: string,
|
||||||
|
open_posts?: number,
|
||||||
|
phase?: number,
|
||||||
|
poll_description_default?: number,
|
||||||
|
polls?: Object[],
|
||||||
|
tags_id?: number[],
|
||||||
|
title?: string
|
||||||
|
) {
|
||||||
|
super(id);
|
||||||
|
this.id = id;
|
||||||
|
this.agenda_item_id = agenda_item_id;
|
||||||
|
this.description = description;
|
||||||
|
this.open_posts = open_posts;
|
||||||
|
this.phase = phase;
|
||||||
|
this.poll_description_default = poll_description_default;
|
||||||
|
this.polls = polls;
|
||||||
|
this.tags_id = tags_id;
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Assignment.collectionString;
|
||||||
|
}
|
||||||
|
}
|
@ -8,35 +8,35 @@ const INVALID_COLLECTION_STRING = 'invalid-collection-string';
|
|||||||
export type ModelId = number | string;
|
export type ModelId = number | string;
|
||||||
|
|
||||||
export abstract class BaseModel {
|
export abstract class BaseModel {
|
||||||
|
static collectionString = INVALID_COLLECTION_STRING;
|
||||||
id: ModelId;
|
id: ModelId;
|
||||||
|
|
||||||
constructor() {}
|
constructor(id: ModelId) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
// convert an serialized version of the model to an instance of the class
|
// convert an serialized version of the model to an instance of the class
|
||||||
// jsonString is usually the server respince
|
// jsonString is usually the server respince
|
||||||
// T is the target model, User, Motion, Whatever
|
// T is the target model, User, Motion, Whatever
|
||||||
// demands full functionening Models with constructors
|
// demands full functionening Models with constructors
|
||||||
static fromJSON(jsonString: {}, T): BaseModel {
|
static fromJSON(jsonString: {}, Type): BaseModel {
|
||||||
// create an instance of the User class
|
// create an instance of the User class
|
||||||
const model = Object.create(T.prototype);
|
const model = Object.create(Type.prototype);
|
||||||
// copy all the fields from the json object
|
// copy all the fields from the json object
|
||||||
return Object.assign(model, jsonString);
|
return Object.assign(model, jsonString);
|
||||||
}
|
}
|
||||||
|
|
||||||
//hast to be overwritten by the children.
|
|
||||||
//Could be more generic: e.g. a model-enum
|
|
||||||
public getCollectionString(): string {
|
public getCollectionString(): string {
|
||||||
return INVALID_COLLECTION_STRING;
|
return BaseModel.collectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO document this function.
|
//TODO document this function.
|
||||||
public getCheckedCollectionString(): string {
|
// public getCheckedCollectionString(): string {
|
||||||
const collectionString: string = this.getCollectionString();
|
// if (this.collectionString === INVALID_COLLECTION_STRING) {
|
||||||
if (collectionString === INVALID_COLLECTION_STRING) {
|
// throw new ImproperlyConfiguredError(
|
||||||
throw new ImproperlyConfiguredError(
|
// 'Invalid collection string: Please override the static getCollectionString method!'
|
||||||
'Invalid collection string: Please override the static getCollectionString method!'
|
// );
|
||||||
);
|
// }
|
||||||
}
|
// return collectionString;
|
||||||
return collectionString;
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
19
client/src/app/core/models/core/chat-message.ts
Normal file
19
client/src/app/core/models/core/chat-message.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class ChatMessage extends BaseModel {
|
||||||
|
static collectionString = 'core/chat-message';
|
||||||
|
id: number;
|
||||||
|
message: string;
|
||||||
|
timestamp: string; // TODO: Type for timestamp
|
||||||
|
user_id: number;
|
||||||
|
|
||||||
|
constructor(id: number, message?: string, timestamp?: string, user_id?: number) {
|
||||||
|
super(id);
|
||||||
|
this.message = message;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return ChatMessage.collectionString;
|
||||||
|
}
|
||||||
|
}
|
18
client/src/app/core/models/core/config.ts
Normal file
18
client/src/app/core/models/core/config.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Config extends BaseModel {
|
||||||
|
static collectionString = 'core/config';
|
||||||
|
id: number;
|
||||||
|
key: string;
|
||||||
|
value: Object;
|
||||||
|
|
||||||
|
constructor(id: number, key?: string, value?: Object) {
|
||||||
|
super(id);
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Config.collectionString;
|
||||||
|
}
|
||||||
|
}
|
21
client/src/app/core/models/core/countdown.ts
Normal file
21
client/src/app/core/models/core/countdown.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Countdown extends BaseModel {
|
||||||
|
static collectionString = 'core/countdown';
|
||||||
|
id: number;
|
||||||
|
countdown_time: number;
|
||||||
|
default_time: number;
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
constructor(id: number, countdown_time?: number, default_time?: number, description?: string) {
|
||||||
|
super(id);
|
||||||
|
this.id = id;
|
||||||
|
this.countdown_time = countdown_time;
|
||||||
|
this.default_time = default_time;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Countdown.collectionString;
|
||||||
|
}
|
||||||
|
}
|
16
client/src/app/core/models/core/projector-message.ts
Normal file
16
client/src/app/core/models/core/projector-message.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class ProjectorMessage extends BaseModel {
|
||||||
|
static collectionString = 'core/projector-message';
|
||||||
|
id: number;
|
||||||
|
message: string;
|
||||||
|
|
||||||
|
constructor(id: number, message?: string) {
|
||||||
|
super(id);
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return ProjectorMessage.collectionString;
|
||||||
|
}
|
||||||
|
}
|
40
client/src/app/core/models/core/projector.ts
Normal file
40
client/src/app/core/models/core/projector.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Projector extends BaseModel {
|
||||||
|
static collectionString = 'core/projector';
|
||||||
|
id: number;
|
||||||
|
blank: boolean;
|
||||||
|
elements: Object;
|
||||||
|
height: number;
|
||||||
|
name: string;
|
||||||
|
projectiondefaults: BaseModel[];
|
||||||
|
scale: number;
|
||||||
|
scroll: number;
|
||||||
|
width: number;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: number,
|
||||||
|
blank?: boolean,
|
||||||
|
elements?: Object,
|
||||||
|
height?: number,
|
||||||
|
name?: string,
|
||||||
|
projectiondefaults?: BaseModel[],
|
||||||
|
scale?: number,
|
||||||
|
scroll?: number,
|
||||||
|
width?: number
|
||||||
|
) {
|
||||||
|
super(id);
|
||||||
|
this.blank = blank;
|
||||||
|
this.elements = elements;
|
||||||
|
this.height = height;
|
||||||
|
this.name = name;
|
||||||
|
this.projectiondefaults = projectiondefaults;
|
||||||
|
this.scale = scale;
|
||||||
|
this.scroll = scroll;
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Projector.collectionString;
|
||||||
|
}
|
||||||
|
}
|
16
client/src/app/core/models/core/tag.ts
Normal file
16
client/src/app/core/models/core/tag.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Tag extends BaseModel {
|
||||||
|
static collectionString = 'core/tag';
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
constructor(id: number, name?: string) {
|
||||||
|
super(id);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Tag.collectionString;
|
||||||
|
}
|
||||||
|
}
|
37
client/src/app/core/models/mediafiles/mediafile.ts
Normal file
37
client/src/app/core/models/mediafiles/mediafile.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Mediafile extends BaseModel {
|
||||||
|
static collectionString = 'mediafiles/mediafile';
|
||||||
|
id: number;
|
||||||
|
filesize: string;
|
||||||
|
hidden: boolean;
|
||||||
|
media_url_prefix: string;
|
||||||
|
mediafile: Object;
|
||||||
|
timestamp: string;
|
||||||
|
title: string;
|
||||||
|
uploader_id: number;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: number,
|
||||||
|
filesize?: string,
|
||||||
|
hidden?: boolean,
|
||||||
|
media_url_prefix?: string,
|
||||||
|
mediafile?: Object,
|
||||||
|
timestamp?: string,
|
||||||
|
title?: string,
|
||||||
|
uploader_id?: number
|
||||||
|
) {
|
||||||
|
super(id);
|
||||||
|
this.filesize = filesize;
|
||||||
|
this.hidden = hidden;
|
||||||
|
this.media_url_prefix = media_url_prefix;
|
||||||
|
this.mediafile = mediafile;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.title = title;
|
||||||
|
this.uploader_id = uploader_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Mediafile.collectionString;
|
||||||
|
}
|
||||||
|
}
|
18
client/src/app/core/models/motions/category.ts
Normal file
18
client/src/app/core/models/motions/category.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Category extends BaseModel {
|
||||||
|
static collectionString = 'motions/category';
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
prefix: string;
|
||||||
|
|
||||||
|
constructor(id: number, name?: string, prefix?: string) {
|
||||||
|
super(id);
|
||||||
|
this.name = name;
|
||||||
|
this.prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Category.collectionString;
|
||||||
|
}
|
||||||
|
}
|
18
client/src/app/core/models/motions/motion-block.ts
Normal file
18
client/src/app/core/models/motions/motion-block.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class MotionBlock extends BaseModel {
|
||||||
|
static collectionString = 'motions/motion-block';
|
||||||
|
id: number;
|
||||||
|
agenda_item_id: number;
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
constructor(id: number, agenda_item_id?: number, title?: string) {
|
||||||
|
super(id);
|
||||||
|
this.agenda_item_id = agenda_item_id;
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return MotionBlock.collectionString;
|
||||||
|
}
|
||||||
|
}
|
40
client/src/app/core/models/motions/motion-change-reco.ts
Normal file
40
client/src/app/core/models/motions/motion-change-reco.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class MotionChangeReco extends BaseModel {
|
||||||
|
static collectionString = 'motions/motion-change-recommendation';
|
||||||
|
id: number;
|
||||||
|
creation_time: string;
|
||||||
|
line_from: number;
|
||||||
|
line_to: number;
|
||||||
|
motion_version_id: number;
|
||||||
|
other_description: string;
|
||||||
|
rejected: boolean;
|
||||||
|
text: string;
|
||||||
|
type: number;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: number,
|
||||||
|
creation_time?: string,
|
||||||
|
line_from?: number,
|
||||||
|
line_to?: number,
|
||||||
|
motion_version_id?: number,
|
||||||
|
other_description?: string,
|
||||||
|
rejected?: boolean,
|
||||||
|
text?: string,
|
||||||
|
type?: number
|
||||||
|
) {
|
||||||
|
super(id);
|
||||||
|
this.creation_time = creation_time;
|
||||||
|
this.line_from = line_from;
|
||||||
|
this.line_to = line_to;
|
||||||
|
this.motion_version_id = motion_version_id;
|
||||||
|
this.other_description = other_description;
|
||||||
|
this.rejected = rejected;
|
||||||
|
this.text = text;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return MotionChangeReco.collectionString;
|
||||||
|
}
|
||||||
|
}
|
70
client/src/app/core/models/motions/motion.ts
Normal file
70
client/src/app/core/models/motions/motion.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Motion extends BaseModel {
|
||||||
|
static collectionString = 'motions/motion';
|
||||||
|
id: number;
|
||||||
|
active_version: number;
|
||||||
|
agenda_item_id: number;
|
||||||
|
attachments_id: number[];
|
||||||
|
category_id: number;
|
||||||
|
comments: Object;
|
||||||
|
identifier: string;
|
||||||
|
log_messages: Object[];
|
||||||
|
motion_block_id: number;
|
||||||
|
origin: string;
|
||||||
|
parent_id: number;
|
||||||
|
polls: BaseModel[];
|
||||||
|
recommendation_id: number;
|
||||||
|
state_id: number;
|
||||||
|
state_required_permission_to_see: string;
|
||||||
|
submitters: Object[];
|
||||||
|
supporters_id: number[];
|
||||||
|
tags_id: number[];
|
||||||
|
versions: Object[];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: number,
|
||||||
|
active_version?: number,
|
||||||
|
agenda_item_id?: number,
|
||||||
|
attachments_id?: number[],
|
||||||
|
category_id?: number,
|
||||||
|
comments?: Object,
|
||||||
|
identifier?: string,
|
||||||
|
log_messages?: Object[],
|
||||||
|
motion_block_id?: number,
|
||||||
|
origin?: string,
|
||||||
|
parent_id?: number,
|
||||||
|
polls?: BaseModel[],
|
||||||
|
recommendation_id?: number,
|
||||||
|
state_id?: number,
|
||||||
|
state_required_permission_to_see?: string,
|
||||||
|
submitters?: Object[],
|
||||||
|
supporters_id?: number[],
|
||||||
|
tags_id?: number[],
|
||||||
|
versions?: Object[]
|
||||||
|
) {
|
||||||
|
super(id);
|
||||||
|
this.active_version = active_version;
|
||||||
|
this.agenda_item_id = agenda_item_id;
|
||||||
|
this.attachments_id = attachments_id;
|
||||||
|
this.category_id = category_id;
|
||||||
|
this.comments = comments;
|
||||||
|
this.identifier = identifier;
|
||||||
|
this.log_messages = log_messages;
|
||||||
|
this.motion_block_id = motion_block_id;
|
||||||
|
this.origin = origin;
|
||||||
|
this.parent_id = parent_id;
|
||||||
|
this.polls = polls;
|
||||||
|
this.recommendation_id = recommendation_id;
|
||||||
|
this.state_id = state_id;
|
||||||
|
this.state_required_permission_to_see = state_required_permission_to_see;
|
||||||
|
this.submitters = submitters;
|
||||||
|
this.supporters_id = supporters_id;
|
||||||
|
this.tags_id = tags_id;
|
||||||
|
this.versions = versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Motion.collectionString;
|
||||||
|
}
|
||||||
|
}
|
20
client/src/app/core/models/motions/workflow.ts
Normal file
20
client/src/app/core/models/motions/workflow.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Workflow extends BaseModel {
|
||||||
|
static collectionString = 'motions/workflow';
|
||||||
|
id: number;
|
||||||
|
first_state: number;
|
||||||
|
name: string;
|
||||||
|
states: Object[];
|
||||||
|
|
||||||
|
constructor(id: number, first_state?, name?, states?) {
|
||||||
|
super(id);
|
||||||
|
this.first_state = first_state;
|
||||||
|
this.name = name;
|
||||||
|
this.states = states;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Workflow.collectionString;
|
||||||
|
}
|
||||||
|
}
|
22
client/src/app/core/models/topics/topic.ts
Normal file
22
client/src/app/core/models/topics/topic.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class Topic extends BaseModel {
|
||||||
|
static collectionString = 'topics/topic';
|
||||||
|
id: number;
|
||||||
|
agenda_item_id: number;
|
||||||
|
attachments_id: number[];
|
||||||
|
text: string;
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
constructor(id: number, agenda_item_id?: number, attachments_id?: number[], text?: string, title?: string) {
|
||||||
|
super(id);
|
||||||
|
this.agenda_item_id = agenda_item_id;
|
||||||
|
this.attachments_id = attachments_id;
|
||||||
|
this.text = text;
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return Topic.collectionString;
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,19 @@
|
|||||||
import { BaseModel } from './baseModel';
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
export class Group extends BaseModel {
|
export class Group extends BaseModel {
|
||||||
|
static collectionString = 'users/group';
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
permissions: string[]; //TODO permissions could be an own model?
|
permissions: string[]; //TODO permissions could be an own model?
|
||||||
|
|
||||||
constructor(id: number, name?: string, permissions?: string[]) {
|
constructor(id: number, name?: string, permissions?: string[]) {
|
||||||
super();
|
super(id);
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.permissions = permissions;
|
this.permissions = permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCollectionString(): string {
|
public getCollectionString(): string {
|
||||||
return 'users/group';
|
return Group.collectionString;
|
||||||
}
|
}
|
||||||
}
|
}
|
18
client/src/app/core/models/users/personal-note.ts
Normal file
18
client/src/app/core/models/users/personal-note.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
|
export class PersonalNote extends BaseModel {
|
||||||
|
static collectionString = 'users/personal-note';
|
||||||
|
id: number;
|
||||||
|
notes: Object;
|
||||||
|
user_id: number;
|
||||||
|
|
||||||
|
constructor(id: number, notes?: Object, user_id?: number) {
|
||||||
|
super(id);
|
||||||
|
this.notes = notes;
|
||||||
|
this.user_id = user_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCollectionString(): string {
|
||||||
|
return PersonalNote.collectionString;
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import { BaseModel } from './baseModel';
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
|
||||||
// import { DS } from 'app/core/services/DS.service';
|
// import { DS } from 'app/core/services/DS.service';
|
||||||
|
|
||||||
export class User extends BaseModel {
|
export class User extends BaseModel {
|
||||||
//TODO potentially make them private and use getters and setters
|
static collectionString = 'users/user';
|
||||||
id: number;
|
id: number;
|
||||||
username: string;
|
username: string;
|
||||||
title: string;
|
title: string;
|
||||||
@ -40,8 +40,7 @@ export class User extends BaseModel {
|
|||||||
is_active?: boolean,
|
is_active?: boolean,
|
||||||
default_password?: string
|
default_password?: string
|
||||||
) {
|
) {
|
||||||
super();
|
super(id);
|
||||||
this.id = id;
|
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.first_name = first_name;
|
this.first_name = first_name;
|
||||||
@ -59,15 +58,7 @@ export class User extends BaseModel {
|
|||||||
this.default_password = default_password;
|
this.default_password = default_password;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCollectionString(): string {
|
public getCollectionString(): string {
|
||||||
return 'users/user';
|
return User.collectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// // convert an serialized version of the User to an instance of the class
|
|
||||||
// static fromJSON(jsonString: {}): User {
|
|
||||||
// // create an instance of the User class
|
|
||||||
// let user = Object.create(User.prototype);
|
|
||||||
// // copy all the fields from the json object
|
|
||||||
// return Object.assign(user, jsonString);
|
|
||||||
// }
|
|
||||||
}
|
}
|
@ -1,11 +1,11 @@
|
|||||||
import { TestBed, inject } from '@angular/core/testing';
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
import { DS } from './DS.service';
|
import { DataStoreService } from './DS.service';
|
||||||
|
|
||||||
describe('DS', () => {
|
describe('DS', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [DS]
|
providers: [DataStoreService]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -10,11 +10,11 @@ interface Collection {
|
|||||||
[id: number]: BaseModel;
|
[id: number]: BaseModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DataStore {
|
interface Storrage {
|
||||||
[collectionString: string]: Collection;
|
[collectionString: string]: Collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Todo: DRY. This is a copy from /authService. probably repository service necessary
|
// Todo: DRY. This is a copy from /authService. probably repository service necessary
|
||||||
const httpOptions = {
|
const httpOptions = {
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
headers: new HttpHeaders({
|
headers: new HttpHeaders({
|
||||||
@ -25,67 +25,81 @@ const httpOptions = {
|
|||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class DS {
|
export class DataStoreService {
|
||||||
private store: DataStore = {};
|
// needs to be static cause becauseusing dependency injection, services are unique for a scope.
|
||||||
|
private static store: Storrage = {};
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
constructor(private http: HttpClient) {}
|
||||||
|
|
||||||
get(collectionString: string, id: ModelId): BaseModel | undefined {
|
// read one, multiple or all ID's from DataStore
|
||||||
const collection: Collection = this.store[collectionString];
|
// example: this.DS.get(User) || (User, 1) || (User, 1, 2) || (User, ...[1,2,3,4,5])
|
||||||
if (!collection) {
|
get(Type, ...ids: ModelId[]): BaseModel[] | BaseModel {
|
||||||
return;
|
const collection: Collection = DataStoreService.store[Type.collectionString];
|
||||||
}
|
const models = [];
|
||||||
const model: BaseModel = collection[id];
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
//todo return observable of base model
|
|
||||||
getAll(collectionString: string): BaseModel[] {
|
|
||||||
const collection: Collection = this.store[collectionString];
|
|
||||||
if (!collection) {
|
if (!collection) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return Object.values(collection);
|
|
||||||
|
if (ids.length === 0) {
|
||||||
|
return Object.values(collection);
|
||||||
|
} else {
|
||||||
|
ids.forEach(id => {
|
||||||
|
const model: BaseModel = collection[id];
|
||||||
|
models.push(model);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return models.length === 1 ? models[0] : models;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print the whole store for debug purposes
|
||||||
|
printWhole(): void {
|
||||||
|
console.log('Everythin in DataStore: ', DataStoreService.store);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: type for callback function
|
// TODO: type for callback function
|
||||||
filter(collectionString: string, callback): BaseModel[] {
|
// example: this.DS.filder(User, myUser => myUser.first_name === "Max")
|
||||||
return this.getAll(collectionString).filter(callback);
|
filter(Type, callback): BaseModel[] {
|
||||||
|
let filterCollection = [];
|
||||||
|
const typeCollection = this.get(Type);
|
||||||
|
|
||||||
|
if (Array.isArray(typeCollection)) {
|
||||||
|
filterCollection = [...filterCollection, ...typeCollection];
|
||||||
|
} else {
|
||||||
|
filterCollection.push(typeCollection);
|
||||||
|
}
|
||||||
|
return filterCollection.filter(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
inject(model: BaseModel): void {
|
// add one or moultiple models to DataStore
|
||||||
const collectionString = model.getCollectionString();
|
// use spread operator ("...") for arrays
|
||||||
console.log('the collection string: ', collectionString);
|
// example: this.DS.add(new User(1)) || (new User(2), new User(3)) || (arrayWithUsers)
|
||||||
|
add(...models: BaseModel[]): void {
|
||||||
if (!model.id) {
|
|
||||||
throw new ImproperlyConfiguredError('The model must have an id!');
|
|
||||||
} else if (collectionString === 'invalid-collection-string') {
|
|
||||||
throw new ImproperlyConfiguredError('Cannot save a BaseModel');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof this.store[collectionString] === 'undefined') {
|
|
||||||
this.store[collectionString] = {};
|
|
||||||
console.log('made new collection: ', collectionString);
|
|
||||||
}
|
|
||||||
this.store[collectionString][model.id] = model;
|
|
||||||
console.log('injected ; ', model);
|
|
||||||
}
|
|
||||||
|
|
||||||
injectMany(models: BaseModel[]): void {
|
|
||||||
models.forEach(model => {
|
models.forEach(model => {
|
||||||
this.inject(model);
|
const collectionString = model.getCollectionString();
|
||||||
|
if (!model.id) {
|
||||||
|
throw new ImproperlyConfiguredError('The model must have an id!');
|
||||||
|
} else if (collectionString === 'invalid-collection-string') {
|
||||||
|
throw new ImproperlyConfiguredError('Cannot save a BaseModel');
|
||||||
|
}
|
||||||
|
if (typeof DataStoreService.store[collectionString] === 'undefined') {
|
||||||
|
DataStoreService.store[collectionString] = {};
|
||||||
|
}
|
||||||
|
DataStoreService.store[collectionString][model.id] = model;
|
||||||
|
// console.log('add model ', model, ' into Datastore');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
eject(collectionString: string, id: ModelId) {
|
// removes one or moultiple models from DataStore
|
||||||
if (this.store[collectionString]) {
|
// use spread operator ("...") for arrays
|
||||||
delete this.store[collectionString][id];
|
// Type should be any BaseModel
|
||||||
}
|
// example: this.DS.remove(User, 1) || this.DS.remove(User, myUser.id, 3, 4)
|
||||||
}
|
remove(Type, ...ids: ModelId[]): void {
|
||||||
|
|
||||||
ejectMany(collectionString: string, ids: ModelId[]) {
|
|
||||||
ids.forEach(id => {
|
ids.forEach(id => {
|
||||||
this.eject(collectionString, id);
|
if (DataStoreService.store[Type.collectionString]) {
|
||||||
|
delete DataStoreService.store[Type.collectionString][id];
|
||||||
|
console.log(`did remove "${id}" from Datastore "${Type.collectionString}"`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,29 +108,27 @@ export class DS {
|
|||||||
if (!model.id) {
|
if (!model.id) {
|
||||||
throw new ImproperlyConfiguredError('The model must have an id!');
|
throw new ImproperlyConfiguredError('The model must have an id!');
|
||||||
}
|
}
|
||||||
const collectionString: string = model.getCollectionString();
|
|
||||||
|
|
||||||
//TODO not tested
|
// TODO not tested
|
||||||
return this.http.post<BaseModel>(collectionString + '/', model, httpOptions).pipe(
|
return this.http.post<BaseModel>(model.getCollectionString() + '/', model, httpOptions).pipe(
|
||||||
tap(response => {
|
tap(response => {
|
||||||
console.log('the response: ', response);
|
console.log('the response: ', response);
|
||||||
this.inject(model);
|
this.add(model);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove the any there and in BaseModel.
|
// send a http request to the server to delete the given model
|
||||||
delete(model: BaseModel): Observable<any> {
|
delete(model: BaseModel): Observable<BaseModel> {
|
||||||
if (!model.id) {
|
if (!model.id) {
|
||||||
throw new ImproperlyConfiguredError('The model must have an id!');
|
throw new ImproperlyConfiguredError('The model must have an id!');
|
||||||
}
|
}
|
||||||
const collectionString: string = model.getCollectionString();
|
|
||||||
|
|
||||||
//TODO not tested
|
// TODO not tested
|
||||||
return this.http.post<BaseModel>(collectionString + '/', model, httpOptions).pipe(
|
return this.http.post<BaseModel>(model.getCollectionString() + '/', model, httpOptions).pipe(
|
||||||
tap(response => {
|
tap(response => {
|
||||||
console.log('the response: ', response);
|
console.log('the response: ', response);
|
||||||
this.eject(collectionString, model.id);
|
this.remove(model, model.id);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { HttpClient, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angul
|
|||||||
import { Observable, of, throwError } from 'rxjs';
|
import { Observable, of, throwError } from 'rxjs';
|
||||||
import { catchError, tap } from 'rxjs/operators';
|
import { catchError, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { User } from 'app/core/models/user';
|
import { User } from 'app/core/models/users/user';
|
||||||
|
|
||||||
const httpOptions = {
|
const httpOptions = {
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
|
15
client/src/app/core/services/autoupdate.service.spec.ts
Normal file
15
client/src/app/core/services/autoupdate.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AutoupdateService } from './autoupdate.service';
|
||||||
|
|
||||||
|
describe('AutoupdateService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [AutoupdateService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([AutoupdateService], (service: AutoupdateService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
126
client/src/app/core/services/autoupdate.service.ts
Normal file
126
client/src/app/core/services/autoupdate.service.ts
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { BaseComponent } from 'app/base.component';
|
||||||
|
import { WebsocketService } from './websocket.service';
|
||||||
|
|
||||||
|
import { BaseModel } from 'app/core/models/baseModel';
|
||||||
|
import { Item } from 'app/core/models/agenda/item';
|
||||||
|
import { Assignment } from 'app/core/models/assignments/assignment';
|
||||||
|
import { ChatMessage } from 'app/core/models/core/chat-message';
|
||||||
|
import { Config } from 'app/core/models/core/config';
|
||||||
|
import { Countdown } from 'app/core/models/core/countdown';
|
||||||
|
import { ProjectorMessage } from 'app/core/models/core/projector-message';
|
||||||
|
import { Projector } from 'app/core/models/core/projector';
|
||||||
|
import { Tag } from 'app/core/models/core/tag';
|
||||||
|
import { Mediafile } from 'app/core/models/mediafiles/mediafile';
|
||||||
|
import { Category } from 'app/core/models/motions/category';
|
||||||
|
import { MotionBlock } from 'app/core/models/motions/motion-block';
|
||||||
|
import { MotionChangeReco } from 'app/core/models/motions/motion-change-reco';
|
||||||
|
import { Motion } from 'app/core/models/motions/motion';
|
||||||
|
import { Workflow } from 'app/core/models/motions/workflow';
|
||||||
|
import { Topic } from 'app/core/models/topics/topic';
|
||||||
|
import { Group } from 'app/core/models/users/group';
|
||||||
|
import { PersonalNote } from 'app/core/models/users/personal-note';
|
||||||
|
import { User } from 'app/core/models/users/user';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basically handles the inital update and all automatic updates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AutoupdateService extends BaseComponent {
|
||||||
|
private socket;
|
||||||
|
|
||||||
|
constructor(private websocketService: WebsocketService) {
|
||||||
|
super();
|
||||||
|
this.socket = this.websocketService.connect();
|
||||||
|
this.socket.subscribe(response => {
|
||||||
|
this.storeResponse(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//create models out of socket answer
|
||||||
|
storeResponse(socketResponse): void {
|
||||||
|
socketResponse.forEach(model => {
|
||||||
|
switch (model.collection) {
|
||||||
|
case 'core/projector': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Projector));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'core/chat-message': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, ChatMessage));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'core/tag': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Tag));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'core/projector-message': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, ProjectorMessage));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'core/countdown': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Countdown));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'core/config': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Config));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'users/user': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, User));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'users/group': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Group));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'users/personal-note': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, PersonalNote));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'agenda/item': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Item));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'topics/topic': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Topic));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'motions/category': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Category));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'motions/motion': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Motion));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'motions/motion-block': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, MotionBlock));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'motions/workflow': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Workflow));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'motions/motion-change-recommendation': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, MotionChangeReco));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'assignments/assignment': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Assignment));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'mediafiles/mediafile': {
|
||||||
|
this.DS.add(BaseModel.fromJSON(model.data, Mediafile));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
console.error('No rule for ', model.collection, '\n object was: ', model);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -3,34 +3,28 @@ import { Router } from '@angular/router';
|
|||||||
import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout';
|
import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout';
|
||||||
|
|
||||||
import { AuthService } from 'app/core/services/auth.service';
|
import { AuthService } from 'app/core/services/auth.service';
|
||||||
import { WebsocketService } from 'app/core/services/websocket.service';
|
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { tap } from 'rxjs/operators';
|
import { tap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core'; //showcase
|
import { TranslateService } from '@ngx-translate/core'; //showcase
|
||||||
|
import { BaseComponent } from 'app/base.component';
|
||||||
//into own service
|
|
||||||
import { DS } from 'app/core/services/DS.service';
|
|
||||||
import { User } from 'app/core/models/user';
|
|
||||||
import { Group } from 'app/core/models/group';
|
|
||||||
import { BaseModel } from '../core/models/baseModel';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-site',
|
selector: 'app-site',
|
||||||
templateUrl: './site.component.html',
|
templateUrl: './site.component.html',
|
||||||
styleUrls: ['./site.component.css']
|
styleUrls: ['./site.component.css']
|
||||||
})
|
})
|
||||||
export class SiteComponent implements OnInit {
|
export class SiteComponent extends BaseComponent implements OnInit {
|
||||||
isMobile = false;
|
isMobile = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private websocketService: WebsocketService,
|
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private breakpointObserver: BreakpointObserver,
|
private breakpointObserver: BreakpointObserver,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService
|
||||||
private dS: DS
|
) {
|
||||||
) {}
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.breakpointObserver
|
this.breakpointObserver
|
||||||
@ -43,47 +37,12 @@ export class SiteComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// connect to a the websocket
|
|
||||||
const socket = this.websocketService.connect();
|
|
||||||
|
|
||||||
// subscribe to the socket
|
|
||||||
socket.subscribe(response => {
|
|
||||||
console.log('log : ', response); // will contain all the config variables
|
|
||||||
this.storeResponse(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
// basically everything needed for AutoUpdate
|
|
||||||
socket.next(val => {
|
|
||||||
console.log('socket.next: ', val);
|
|
||||||
});
|
|
||||||
|
|
||||||
//get a translation via code: use the translation service
|
//get a translation via code: use the translation service
|
||||||
this.translate.get('Motions').subscribe((res: string) => {
|
this.translate.get('Motions').subscribe((res: string) => {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//test. will move to an own service later
|
|
||||||
//create models out of socket answer
|
|
||||||
storeResponse(socketResponse): void {
|
|
||||||
socketResponse.forEach(model => {
|
|
||||||
switch (model.collection) {
|
|
||||||
case 'users/group': {
|
|
||||||
this.dS.inject(BaseModel.fromJSON(model.data, Group));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'users/user': {
|
|
||||||
this.dS.inject(BaseModel.fromJSON(model.data, User));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
console.log('collection: "' + model.collection + '" is not yet parsed');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
selectLang(lang: string): void {
|
selectLang(lang: string): void {
|
||||||
console.log('selected langauge: ', lang);
|
console.log('selected langauge: ', lang);
|
||||||
console.log('get Langs : ', this.translate.getLangs());
|
console.log('get Langs : ', this.translate.getLangs());
|
||||||
|
@ -6,5 +6,9 @@
|
|||||||
<span>{{'Welcome to OpenSlides' | translate}}</span>
|
<span>{{'Welcome to OpenSlides' | translate}}</span>
|
||||||
<br/>
|
<br/>
|
||||||
<p translate [translateParams]="{user: 'Tim'}">Hello user</p>
|
<p translate [translateParams]="{user: 'Tim'}">Hello user</p>
|
||||||
<button type="button" (click)="test()">test</button>
|
<button type="button" (click)="DataStoreTest()">DataStoreTest</button>
|
||||||
|
<br/>
|
||||||
|
<button type="button" (click)="TranslateTest()">Translate in console</button>
|
||||||
|
<br/>
|
||||||
|
<button type="button" (click)="giveDataStore()">print the dataStore</button>
|
||||||
</div>
|
</div>
|
@ -2,9 +2,11 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
import { BaseComponent } from 'app/base.component';
|
import { BaseComponent } from 'app/base.component';
|
||||||
|
|
||||||
|
import { TranslateService } from '@ngx-translate/core'; //showcase
|
||||||
|
|
||||||
// for testing the DS and BaseModel
|
// for testing the DS and BaseModel
|
||||||
import { User } from 'app/core/models/user';
|
import { User } from 'app/core/models/users/user';
|
||||||
import { DS } from 'app/core/services/DS.service';
|
import { Group } from 'app/core/models/users/group';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-start',
|
selector: 'app-start',
|
||||||
@ -12,42 +14,49 @@ import { DS } from 'app/core/services/DS.service';
|
|||||||
styleUrls: ['./start.component.css']
|
styleUrls: ['./start.component.css']
|
||||||
})
|
})
|
||||||
export class StartComponent extends BaseComponent implements OnInit {
|
export class StartComponent extends BaseComponent implements OnInit {
|
||||||
private dS: DS;
|
constructor(titleService: Title, private translate: TranslateService) {
|
||||||
|
|
||||||
constructor(titleService: Title, dS: DS) {
|
|
||||||
super(titleService);
|
super(titleService);
|
||||||
this.dS = dS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
super.setTitle('Start page');
|
super.setTitle('Start page');
|
||||||
}
|
}
|
||||||
|
|
||||||
test() {
|
//quick testing of some data store functions
|
||||||
// This can be a basic unit test ;)
|
DataStoreTest() {
|
||||||
// console.log(User.get(1));
|
console.log('add a user to dataStore');
|
||||||
const user1: User = new User(32, 'testuser');
|
this.DS.add(new User(100));
|
||||||
const user2: User = new User(42, 'testuser 2');
|
console.log('add three users to dataStore');
|
||||||
|
this.DS.add(new User(200), new User(201), new User(202));
|
||||||
console.log(`User1 | ID ${user1.id}, Name: ${user1.username}`);
|
console.log('use the spread operator "..." to add an array');
|
||||||
console.log(`User2 | ID ${user2.id}, Name: ${user2.username}`);
|
const userArray = [];
|
||||||
|
for (let i = 300; i < 400; i++) {
|
||||||
this.dS.inject(user1);
|
userArray.push(new User(i));
|
||||||
this.dS.inject(user2);
|
}
|
||||||
console.log('All users = ', this.dS.getAll('users/user'));
|
this.DS.add(...userArray);
|
||||||
|
|
||||||
console.log('try to get user with ID 1:');
|
console.log('try to get user with ID 1:');
|
||||||
const user1fromStore = this.dS.get('users/user', 1);
|
const user1fromStore = this.DS.get(User, 1);
|
||||||
console.log('the user: ', user1fromStore);
|
console.log('the user: ', user1fromStore);
|
||||||
|
|
||||||
console.log('inject many:');
|
console.log('remove a single user:');
|
||||||
this.dS.injectMany([user1, user2]);
|
this.DS.remove(User, 100);
|
||||||
|
console.log('remove more users');
|
||||||
|
this.DS.remove(User, 200, 201, 202);
|
||||||
|
console.log('remove an array of users');
|
||||||
|
this.DS.remove(User, ...[321, 363, 399]);
|
||||||
|
|
||||||
console.log('eject user 1');
|
console.log('test filter: ');
|
||||||
this.dS.eject('users/user', user1.id);
|
console.log(this.DS.filter(User, user => user.id === 1));
|
||||||
console.log(this.dS.getAll('users/user'));
|
}
|
||||||
|
|
||||||
// console.log(User.filter(user => user.id === 1));
|
giveDataStore() {
|
||||||
// console.log(User.filter(user => user.id === 2));
|
this.DS.printWhole();
|
||||||
|
}
|
||||||
|
|
||||||
|
// shows how to use synchronous translations:
|
||||||
|
TranslateTest() {
|
||||||
|
console.log('lets translate the word "motion" in the current in the current lang');
|
||||||
|
console.log('Motions in ' + this.translate.currentLang + ' is ' + this.translate.instant('Motions'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user