opt-cc/static/src/app/services/army-management/rank.service.ts

145 lines
4.1 KiB
TypeScript

import {Injectable} from '@angular/core';
import {Decoration, Rank} from '../../models/model-interfaces';
import {RequestMethod, RequestOptions, URLSearchParams} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {LOAD} from '../stores/decoration.store';
import {ADD, EDIT, RankStore, REMOVE} from '../stores/rank.store';
import {AppConfig} from '../../app.config';
import {HttpClient} from '../http-client';
@Injectable()
export class RankService {
ranks$: Observable<Rank[]>;
constructor(private http: HttpClient,
private rankStore: RankStore,
private config: AppConfig) {
this.ranks$ = rankStore.items$;
}
findRanks(query = '', fractionFilter?) {
const searchParams = new URLSearchParams();
searchParams.append('q', query);
if (fractionFilter) {
searchParams.append('fractFilter', fractionFilter);
}
this.http.get(this.config.apiRankPath, searchParams)
.map(res => res.json())
.do((ranks) => {
this.rankStore.dispatch({type: LOAD, data: ranks});
}).subscribe(_ => {
});
return this.ranks$;
}
getRank(id: number | string): Observable<Decoration> {
return this.http.get(this.config.apiRankPath + id)
.map(res => res.json());
}
/**
* For creating new data with POST or
* update existing with patch PATCH
*/
submitRank(rank: Rank, imageFile?) {
let requestUrl = this.config.apiRankPath;
let requestMethod: RequestMethod;
let accessType;
let body;
if (rank._id) {
requestUrl += rank._id;
requestMethod = RequestMethod.Patch;
accessType = EDIT;
} else {
requestMethod = RequestMethod.Post;
accessType = ADD;
}
if (imageFile) {
body = new FormData();
Object.keys(rank).map((objectKey) => {
if (rank[objectKey] !== undefined) {
body.append(objectKey, rank[objectKey]);
}
});
body.append('image', imageFile, imageFile.name);
} else {
body = rank;
}
const options = new RequestOptions({
body: body,
method: requestMethod
});
return this.http.request(requestUrl, options)
.map(res => res.json())
.do(savedRank => {
const action = {type: accessType, data: savedRank};
// leave some time to save image file before accessing it through listview
setTimeout(() => {
this.rankStore.dispatch(action);
}, 300);
});
}
/**
* send PATCH request to update db entry
*
* @param rank - Rank object with data to update, must contain _id
* @returns {Observable<T>}
*/
updateRank(rank: Rank) {
const options = new RequestOptions({
body: rank,
method: RequestMethod.Patch
});
return this.http.request(this.config.apiRankPath + rank._id, options)
.map(res => res.json())
.do(savedRank => {
const action = {type: EDIT, data: savedRank};
this.rankStore.dispatch(action);
});
}
/**
* sends PATCH with multiform data to
* update rank graphic with newly provided file
*
* @param rankID - id of rank to be updated
* @param imageFile - new image file to upload
*/
updateRankGraphic(rankId: string, imageFile: File) {
const formData: FormData = new FormData();
formData.append('_id', rankId);
formData.append('image', imageFile, imageFile.name);
// provide token as query value, because there is no actual body
// and x-access-token is ignored in multipart request
return this.http.patch(this.config.apiRankPath + rankId, formData)
.map(res => res.json())
.do(savedDecoration => {
const action = {type: EDIT, data: savedDecoration};
this.rankStore.dispatch(action);
});
}
deleteRank(rank: Rank) {
return this.http.delete(this.config.apiRankPath + rank._id)
.do(res => {
this.rankStore.dispatch({type: REMOVE, data: rank});
});
}
}