Add data-send, option to delete motion
This commit is contained in:
parent
de61505b00
commit
70416df50b
@ -7,10 +7,11 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { AuthGuard } from './services/auth-guard.service';
|
||||
import { AuthService } from './services/auth.service';
|
||||
import { AutoupdateService } from './services/autoupdate.service';
|
||||
import { DataStoreService } from './services/dataStore.service';
|
||||
import { DataStoreService } from './services/data-store.service';
|
||||
import { OperatorService } from './services/operator.service';
|
||||
import { WebsocketService } from './services/websocket.service';
|
||||
import { AddHeaderInterceptor } from './http-interceptor';
|
||||
import { DataSendService } from './services/data-send.service';
|
||||
|
||||
/** Global Core Module. Contains all global (singleton) services
|
||||
*
|
||||
@ -23,6 +24,7 @@ import { AddHeaderInterceptor } from './http-interceptor';
|
||||
AuthService,
|
||||
AutoupdateService,
|
||||
DataStoreService,
|
||||
DataSendService,
|
||||
OperatorService,
|
||||
WebsocketService,
|
||||
{
|
||||
|
@ -68,7 +68,13 @@ export class AutoupdateService extends OpenSlidesComponent {
|
||||
storeResponse(socketResponse): void {
|
||||
socketResponse.forEach(jsonObj => {
|
||||
const targetClass = this.getClassFromCollectionString(jsonObj.collection);
|
||||
this.DS.add(new targetClass().deserialize(jsonObj.data));
|
||||
if (jsonObj.action === 'deleted') {
|
||||
console.log('storeResponse detect delete');
|
||||
|
||||
this.DS.remove(jsonObj.collection, jsonObj.id);
|
||||
} else {
|
||||
this.DS.add(new targetClass().deserialize(jsonObj.data));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
15
client/src/app/core/services/data-send.service.spec.ts
Normal file
15
client/src/app/core/services/data-send.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
import { DataSendService } from './data-send.service';
|
||||
|
||||
describe('DataSendService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [DataSendService]
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created', inject([DataSendService], (service: DataSendService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
});
|
74
client/src/app/core/services/data-send.service.ts
Normal file
74
client/src/app/core/services/data-send.service.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { BaseModel } from '../../shared/models/base.model';
|
||||
import { Observable } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
|
||||
/**
|
||||
* Send data back to server
|
||||
*
|
||||
* Contrast to dataStore service
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DataSendService {
|
||||
/**
|
||||
* Construct a DataSendService
|
||||
*
|
||||
* @param http The HTTP Client
|
||||
*/
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
/**
|
||||
* Save motion in the server
|
||||
*
|
||||
* @return Observable from
|
||||
*/
|
||||
saveModel(model: BaseModel): Observable<BaseModel> {
|
||||
if (!model.id) {
|
||||
return this.http.post<BaseModel>('rest/' + model.collectionString + '/', model).pipe(
|
||||
tap(
|
||||
response => {
|
||||
// TODO: Message, Notify, Etc
|
||||
console.log('New Model added. Response : ', response);
|
||||
},
|
||||
error => console.log('error. ', error)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return this.http.put<BaseModel>('rest/' + model.collectionString + '/' + model.id, model).pipe(
|
||||
tap(
|
||||
response => {
|
||||
console.log('Update model. Response : ', response);
|
||||
},
|
||||
error => console.log('error. ', error)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given model on the server
|
||||
*
|
||||
* @param model the BaseModel that shall be removed
|
||||
* @return Observable of BaseModel
|
||||
*
|
||||
* TODO Not tested
|
||||
*/
|
||||
delete(model: BaseModel): Observable<BaseModel> {
|
||||
if (model.id) {
|
||||
return this.http.delete<BaseModel>('rest/' + model.collectionString + '/' + model.id).pipe(
|
||||
tap(
|
||||
response => {
|
||||
// TODO: Message, Notify, Etc
|
||||
console.log('the response: ', response);
|
||||
},
|
||||
error => console.error('error during delete: ', error)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
console.error('No model ID to delete');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
import { DataStoreService } from './dataStore.service';
|
||||
import { DataStoreService } from './data-store.service';
|
||||
|
||||
describe('DS', () => {
|
||||
beforeEach(() => {
|
@ -1,7 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, BehaviorSubject } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
|
||||
import { ImproperlyConfiguredError } from 'app/core/exceptions';
|
||||
import { BaseModel, ModelId } from 'app/shared/models/base.model';
|
||||
@ -55,9 +53,7 @@ export class DataStoreService {
|
||||
* Empty constructor for dataStore
|
||||
* @param http use HttpClient to send models back to the server
|
||||
*/
|
||||
constructor(private http: HttpClient) {
|
||||
console.log('constructor of dataStore. http: ', this.http);
|
||||
}
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* Read one, multiple or all ID's from dataStore
|
||||
@ -153,62 +149,25 @@ export class DataStoreService {
|
||||
* @param ...ids An or multiple IDs or a list of IDs of BaseModels. use spread operator ("...") for arrays
|
||||
* @example this.DS.remove(User, myUser.id, 3, 4)
|
||||
*/
|
||||
remove(Type, ...ids: ModelId[]): void {
|
||||
remove(collectionType, ...ids: ModelId[]): void {
|
||||
console.log('remove from DS: collection', collectionType);
|
||||
console.log('remove from DS: collection', ids);
|
||||
|
||||
let collectionString: string;
|
||||
if (typeof collectionType === 'string') {
|
||||
collectionString = collectionType;
|
||||
} else {
|
||||
const tempObject = new collectionType();
|
||||
collectionString = tempObject.collectionString;
|
||||
}
|
||||
|
||||
ids.forEach(id => {
|
||||
const tempObject = new Type();
|
||||
if (DataStoreService.store[tempObject.collectionString]) {
|
||||
delete DataStoreService.store[tempObject.collectionString][id];
|
||||
console.log(`did remove "${id}" from Datastore "${tempObject.collectionString}"`);
|
||||
if (DataStoreService.store[collectionString]) {
|
||||
delete DataStoreService.store[collectionString][id];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the given model on the server
|
||||
* @param model the BaseModel that shall be saved
|
||||
* @return Observable of BaseModel
|
||||
*/
|
||||
save(model: BaseModel): Observable<BaseModel> {
|
||||
if (!model.id) {
|
||||
return this.http.post<BaseModel>('rest/' + model.collectionString + '/', model).pipe(
|
||||
tap(
|
||||
response => {
|
||||
console.log('New Model added. Response : ', response);
|
||||
},
|
||||
error => console.log('error. ', error)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return this.http.put<BaseModel>('rest/' + model.collectionString + '/' + model.id, model).pipe(
|
||||
tap(
|
||||
response => {
|
||||
console.log('Update model. Response : ', response);
|
||||
},
|
||||
error => console.log('error. ', error)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given model on the server
|
||||
* @param model the BaseModel that shall be removed
|
||||
* @return Observable of BaseModel
|
||||
*/
|
||||
delete(model: BaseModel): Observable<BaseModel> {
|
||||
if (!model.id) {
|
||||
throw new ImproperlyConfiguredError('The model must have an id!');
|
||||
}
|
||||
|
||||
// TODO not tested
|
||||
return this.http.post<BaseModel>(model.collectionString + '/', model).pipe(
|
||||
tap(response => {
|
||||
console.log('the response: ', response);
|
||||
this.remove(model, model.id);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe the dataStore for changes.
|
||||
* @return an observable behaviorSubject
|
@ -2,7 +2,7 @@ import { Injector } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, of } from 'rxjs';
|
||||
|
||||
import { DataStoreService } from 'app/core/services/dataStore.service';
|
||||
import { DataStoreService } from './core/services/data-store.service';
|
||||
|
||||
/**
|
||||
* injects the {@link DataStoreService} to all its children and provides a generic function to catch errors
|
||||
|
@ -19,6 +19,18 @@
|
||||
<span translate>by</span> {{motion.submitterAsUser}}
|
||||
</div>
|
||||
</div>
|
||||
<span class='spacer'></span>
|
||||
|
||||
<button class='on-transition-fade' mat-icon-button [matMenuTriggerFor]="motionExtraMenu">
|
||||
<fa-icon icon='ellipsis-v'></fa-icon>
|
||||
</button>
|
||||
<mat-menu #motionExtraMenu="matMenu">
|
||||
<!-- TODO the functions for the buttons -->
|
||||
<button mat-menu-item translate>Export As...</button>
|
||||
<button mat-menu-item translate>Project</button>
|
||||
<mat-divider></mat-divider>
|
||||
<button mat-menu-item class='deleteMotionButton' (click)='deleteMotionButton()' translate>DeleteMotion</button>
|
||||
</mat-menu>
|
||||
</mat-toolbar>
|
||||
|
||||
<mat-accordion multi='true' class='on-transition-fade'>
|
||||
@ -85,7 +97,7 @@
|
||||
<h3>{{motion.recomBy}}</h3>
|
||||
{{motion.recommendation.name}}
|
||||
</div>
|
||||
<mat-form-field *ngIf="editMotion">
|
||||
<mat-form-field *ngIf="motion && editMotion">
|
||||
<mat-select placeholder='Recommendation' formControlName='recommendation_id'>
|
||||
<mat-option *ngFor="let state of motion.possible_states" [value]="state.id">{{state}}</mat-option>
|
||||
<mat-divider></mat-divider>
|
||||
@ -103,7 +115,7 @@
|
||||
<h3 translate> Category</h3>
|
||||
{{motion.category}}
|
||||
</div>
|
||||
<mat-form-field *ngIf="editMotion">
|
||||
<mat-form-field *ngIf="motion && editMotion">
|
||||
<mat-select placeholder='Category' formControlName='category_id'>
|
||||
<mat-option>None</mat-option>
|
||||
<mat-divider></mat-divider>
|
||||
|
@ -6,6 +6,10 @@ span {
|
||||
background-color: rgb(77, 243, 86);
|
||||
}
|
||||
|
||||
.deleteMotionButton {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.motion-title {
|
||||
padding-left: 20px;
|
||||
line-height: 100%;
|
||||
|
@ -5,8 +5,7 @@ import { Motion } from '../../../shared/models/motions/motion';
|
||||
import { Category } from '../../../shared/models/motions/category';
|
||||
import { FormGroup, FormBuilder } from '@angular/forms';
|
||||
import { MatExpansionPanel } from '@angular/material';
|
||||
import { DataStoreService } from '../../../core/services/dataStore.service';
|
||||
import { OperatorService } from '../../../core/services/operator.service';
|
||||
import { DataSendService } from '../../../core/services/data-send.service';
|
||||
|
||||
/**
|
||||
* Component for the motion detail view
|
||||
@ -16,8 +15,7 @@ import { OperatorService } from '../../../core/services/operator.service';
|
||||
templateUrl: './motion-detail.component.html',
|
||||
styleUrls: ['./motion-detail.component.scss']
|
||||
})
|
||||
// export class MotionDetailComponent extends BaseComponent implements OnInit {
|
||||
export class MotionDetailComponent implements OnInit {
|
||||
export class MotionDetailComponent extends BaseComponent implements OnInit {
|
||||
/**
|
||||
* MatExpansionPanel for the meta info
|
||||
*/
|
||||
@ -56,8 +54,6 @@ export class MotionDetailComponent implements OnInit {
|
||||
/**
|
||||
* Constuct the detail view.
|
||||
*
|
||||
* TODO: DataStore needs removed and added via the parent.
|
||||
* Own service for put and post required
|
||||
*
|
||||
* @param route determine if this is a new or an existing motion
|
||||
* @param formBuilder For reactive forms. Form Group and Form Control
|
||||
@ -66,11 +62,9 @@ export class MotionDetailComponent implements OnInit {
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private formBuilder: FormBuilder,
|
||||
private operator: OperatorService,
|
||||
private myDataStore: DataStoreService
|
||||
private dataSend: DataSendService
|
||||
) {
|
||||
// TODO: Add super again
|
||||
// super();
|
||||
super();
|
||||
this.createForm();
|
||||
|
||||
if (route.snapshot.url[0].path === 'new') {
|
||||
@ -80,13 +74,11 @@ export class MotionDetailComponent implements OnInit {
|
||||
} else {
|
||||
// load existing motion
|
||||
this.route.params.subscribe(params => {
|
||||
console.log('params ', params);
|
||||
|
||||
// has the motion of the DataStore was initialized before.
|
||||
this.motion = this.myDataStore.get(Motion, params.id) as Motion;
|
||||
this.motion = this.DS.get(Motion, params.id) as Motion;
|
||||
|
||||
// Observe motion to get the motion in the parameter and also get the changes
|
||||
this.myDataStore.getObservable().subscribe(newModel => {
|
||||
this.DS.getObservable().subscribe(newModel => {
|
||||
if (newModel instanceof Motion) {
|
||||
if (newModel.id === +params.id) {
|
||||
this.motion = newModel as Motion;
|
||||
@ -150,8 +142,7 @@ export class MotionDetailComponent implements OnInit {
|
||||
this.motion.title = this.motion.currentTitle;
|
||||
this.motion.text = this.motion.currentText;
|
||||
|
||||
this.myDataStore.save(this.motion).subscribe(answer => {
|
||||
console.log('answer, ', answer);
|
||||
this.dataSend.saveModel(this.motion).subscribe(answer => {
|
||||
if (answer && answer.id && this.newMotion) {
|
||||
this.router.navigate(['./motions/' + answer.id]);
|
||||
}
|
||||
@ -162,7 +153,7 @@ export class MotionDetailComponent implements OnInit {
|
||||
* return all Categories.
|
||||
*/
|
||||
getMotionCategories(): Category[] {
|
||||
const categories = this.myDataStore.get(Category);
|
||||
const categories = this.DS.get(Category);
|
||||
return categories as Category[];
|
||||
}
|
||||
|
||||
@ -171,7 +162,6 @@ export class MotionDetailComponent implements OnInit {
|
||||
*/
|
||||
editMotionButton() {
|
||||
this.editMotion ? (this.editMotion = false) : (this.editMotion = true);
|
||||
|
||||
if (this.editMotion) {
|
||||
this.patchForm();
|
||||
this.metaInfoPanel.open();
|
||||
@ -181,17 +171,17 @@ export class MotionDetailComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger to delete the motion
|
||||
*/
|
||||
deleteMotionButton() {
|
||||
this.dataSend.delete(this.motion).subscribe(answer => {
|
||||
this.router.navigate(['./motions/']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Init. Does nothing here.
|
||||
*/
|
||||
ngOnInit() {}
|
||||
|
||||
/**
|
||||
* Function to download a motion.
|
||||
*
|
||||
* TODO: does nothing yet.
|
||||
*/
|
||||
downloadSingleMotionButton() {
|
||||
console.log('Download this motion');
|
||||
}
|
||||
}
|
||||
|
@ -88,10 +88,8 @@ export class MotionListComponent extends BaseComponent implements OnInit {
|
||||
// The alternative approach is to put the observable as DataSource to the table
|
||||
this.DS.getObservable().subscribe(newModel => {
|
||||
if (newModel instanceof Motion) {
|
||||
if (!this.motionArray.includes(newModel)) {
|
||||
this.motionArray.push(newModel as Motion);
|
||||
this.dataSource.data = this.motionArray;
|
||||
}
|
||||
this.motionArray = this.DS.get(Motion) as Motion[];
|
||||
this.dataSource.data = this.motionArray;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -65,12 +65,12 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
|
||||
//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) => {
|
||||
// console.log('translation of motions in the target language: ' + res);
|
||||
// });
|
||||
// console.log('translation of motions in the target language: ' + res);
|
||||
// });
|
||||
|
||||
//start autoupdate if the user is logged in:
|
||||
// start autoupdate if the user is logged in:
|
||||
this.operator.whoAmI().subscribe(resp => {
|
||||
if (resp.user) {
|
||||
this.autoupdateService.startAutoupdate();
|
||||
|
Loading…
Reference in New Issue
Block a user