import {Injectable} from '@angular/core'; import {PollConfig} from '../config/PollConfig'; import {HttpClient, HttpHeaders} from "@angular/common/http"; import {environment} from "../../environments/environment"; import {ConfirmationService, MessageService} from 'primeng/api'; import {Router} from "@angular/router"; /** * le service transverse à chaque page qui permet de syncroniser la configuration de sondage souhaitée */ @Injectable({ providedIn: 'root' }) export class ConfigService extends PollConfig { loading: boolean = false; baseHref: any = environment.baseApiHref; constructor(private http: HttpClient, private messageService: MessageService, private router: Router, private confirmationService: ConfirmationService, ) { super(); } set(key, val) { this[key] = val; } clear() { this.messageService.clear(); } /** * generate unique id to have a default url for future poll */ makeUuid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } makeSlug(str?: string) { if (!str) { str = this.creationDate.getFullYear() + '_' + (this.creationDate.getMonth() + 1) + '_' + this.creationDate.getDate() + '_' + this.myName + '_' + this.title; } str = str.replace(/^\s+|\s+$/g, ''); // trim str = str.toLowerCase(); // remove accents, swap ñ for n, etc var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;"; var to = "aaaaeeeeiiiioooouuuunc------"; for (var i = 0, l = from.length; i < l; i++) { str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i)); } str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars .replace(/\s+/g, '-') // collapse whitespace and replace by - .replace(/-+/g, '-'); // collapse dashes return str; } /** * add some days to a date, to compute intervals * @param days * @param date */ addDaysToDate(days: number, date: Date) { date = new Date(date.valueOf()); date.setDate(date.getDate() + days); return date; }; /** ================================== * * poll public calls to get non authenticated info * * ==================================/ /** * convert current poll config to a payload to send to the backend API */ getPollConfig() { const jsonConfig = { method: 'POST', data: { owner: { email: this.myEmail, pseudo: this.myName, }, title: this.title, description: this.description, type: this.pollType, visibility: this.visibility, voteChoices: this.voteChoices, allowSeveralHours: this.allowSeveralHours, expirationDate: this.expirationDate, passwordAccess: this.passwordAccess, password: this.password, customUrl: this.customUrl, canModifyAnswers: this.canModifyAnswers, whoModifiesAnswers: this.whoModifiesAnswers, dateList: this.dateList, timeList: this.timeList, answers: this.answers, } }; return jsonConfig } makeHeaders(bodyContent?: any) { const headerDict = { 'Charset': 'UTF-8', 'Content-Type': 'application/json', 'Accept': 'application/json', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE', 'Access-Control-Allow-Origin': '*' }; const requestOptions = { headers: new HttpHeaders(headerDict), body: bodyContent }; return requestOptions; } checkIfSlugIsUniqueInDatabase(slug: string) { this.customUrlIsUnique = null; this.loading = true; this.http.get(`${this.baseHref}/check-slug-is-uniq`, this.makeHeaders({slug: this.customUrl}), ) .subscribe((res: any) => { this.customUrlIsUnique = res.data.isUnique; this.loading = false; }, (e) => this.handleError(e)) ; } /** * search in localstorage, fallback asking the backend to send an email to the owner if it exists * @param email */ findPollsByEmail(email: string) { this.findLocalStorageData(); // If no key is found in the localstorage, ask the backend to send an email to the user this.myEmail = email; this.loading = true; this.http.get(`${this.baseHref}/my-polls`, this.makeHeaders({email: this.myEmail}), ) .subscribe(res => { // message: 'Trouvé! Allez voir votre boite email', this.myPolls = res; this.loading = false; this.messageService.add({ severity: 'success', summary: 'Service Message', detail: 'Via MessageService' }); }, (e) => { this.handleError(e) } ) } /** * display error message depending on the response of the backend * @param err */ handleError(err: any) { console.error('err', err); this.loading = false; this.messageService.add({severity: 'warning', summary: "Erreur lors de l'appel ", detail: err.message}); } findLocalStorageData() { // TODO check if the person has a key to retrieve her polls if (localStorage) { console.log('localStorage', localStorage) } } /** * get one poll by its slug name * @param url */ getPollByURL(url: string) { this.http.get(`${this.baseHref}/poll/${url}`, this.makeHeaders()).subscribe( (res: any) => { this.myPolls = res.data; }, (e) => { this.handleError(e) } ); } /** * GET * api/v1/poll/{id} * @param id */ getPollById(id: string, password: string) { this.http .get(`${this.baseHref}/poll/${id}`, this.makeHeaders({body: password})) .subscribe( (res: any) => { this.myPolls = res.data; }, (e) => { this.handleError(e) } ); } /** * GET * api/v1/my-polls * @param ownerEmail */ getMyPolls(ownerEmail: string) { this.http .get(`${this.baseHref}/my-polls`, this.makeHeaders({ownerEmail: ownerEmail}) ) .subscribe( (res: any) => { this.myPolls = res.data; }, (e) => { this.handleError(e) } ); } /** * launch creation call to the api */ createPoll() { this.loading = true; return this.http.get(`${this.baseHref}/`, this.makeHeaders()) .subscribe((res) => { this.createPollFromConfig(this.getPollConfig()) }, (e) => { this.handleError(e) } ) ; } /** * POST * /api/v1/poll/{id}/poll * @param config */ createPollFromConfig(config: any) { this.loading= true; return this.http.post(`${this.baseHref}/poll`, this.makeHeaders({config: config})) .subscribe((res: any) => { // redirect to the page to administrate the new poll this.messageService.add({severity: 'success', summary: 'Sondage Créé',}); this.selectedPoll = res; this.pollId = res.pollId; this.loading = false; this.router.navigate(['step/end']); }, (e) => { this.handleError(e) } ); } /** * POST * /api/v1/poll/{id}/vote * @param voteStack */ addVote(voteStack?: any) { if (!voteStack) { voteStack = { pseudo: this.myName, answers: this.answers } } this.http.post( `${this.baseHref}/poll/${this.pollId}/vote`, voteStack, this.makeHeaders()) .subscribe((res: any) => { this.messageService.add({severity: 'success', summary: 'Vote ajouté'}); alert("succès!"); this.myPolls = res; }, (e) => { this.handleError(e) } ); } /** * UPDATE * /api/v1/poll/{id}/vote * @param voteStack */ updateVote(voteStack: any) { this.http.put( `${this.baseHref}/poll/${this.pollId}/vote`, voteStack, this.makeHeaders()) .subscribe((res: any) => { this.messageService.add({severity: 'success', summary: 'Vote mis à jour'}); this.myPolls = res; }, (e) => { this.handleError(e) } ); } /** * POST * /api/v1/poll/{id}/comment * @param comment */ addComment(comment?: any) { if (!comment) { comment = { pseudo: this.myName, comment: this.myComment, } } this.http.post( `${this.baseHref}/poll/${this.pollId}/comment`, comment, this.makeHeaders()) .subscribe((res: any) => { this.messageService.add({ severity: 'success', summary: 'Commentaire Créé', detail: 'Via MessageService' }); // empty comment after success this.myComment = ''; }, (e) => { this.handleError(e) } ); } /** * administrator calls */ deleteComments() { // prompt for confirmation this.confirmationService.confirm({ message: 'Are you sure that you want to completely delete the comments of this poll (' + this.title + ') permanentely?', accept: () => { this.http.delete( `${this.baseHref}/poll/${this.pollId}/comments`, this.makeHeaders()) .subscribe((res: any) => { this.messageService.add({ severity: 'success', summary: 'Commentaires bien supprimés', detail: 'Commentaires du sondage "' + this.title + '" supprimé' }); }, (e) => { this.handleError(e) } ); } }); } deleteVotes() { // prompt for confirmation this.confirmationService.confirm({ message: 'Are you sure that you want to completely delete the votes of this poll (' + this.title + ') permanentely?', accept: () => { this.http.delete( `${this.baseHref}/poll/${this.pollId}/votes`, this.makeHeaders()) .subscribe((res: any) => { this.messageService.add({ severity: 'success', summary: 'Votes bien supprimés', detail: 'Votes du sondage "' + this.title + '" supprimé' }); }, (e) => { this.handleError(e) } ); } }); } deletePoll() { if (!this.pollId) { this.messageService.add({ summary: 'this poll is not administrable, it has no ID', severity: 'warning' }); return; } let self = this; // prompt for confirmation this.confirmationService.confirm({ message: 'Are you sure that you want to completely delete this poll (' + self.title + ') and all is data permanentely?', accept: () => { this.http.delete( `${this.baseHref}/poll/${this.pollId}`, this.makeHeaders()) .subscribe((res: any) => { this.messageService.add({ severity: 'success', summary: 'Sondage bien supprimé', detail: 'sondage "' + this.title + '" supprimé' }); this.router.navigate(['home']); }, (e) => { this.handleError(e) } ); } }); } /** * UPDATE * /api/v1/poll/{id}/vote * @param voteStack */ updatePoll(voteStack: any) { this.http.put( `${this.baseHref}/poll/${this.pollId}`, voteStack, this.makeHeaders() ) .subscribe((res: any) => { this.messageService.add({ severity: 'success', summary: 'Sondage mis à jour', }); this.myPolls = res; }, (e) => { this.handleError(e) } ); } /** * export all the poll data available to the public as a CSV single file */ exportCSV() { // TODO const rows = [ ["name1", "city1", "some other info"], ["name2", "city2", "more info"] ]; let csvContent = "data:text/csv;charset=utf-8," + rows.map(e => e.join(",")).join("\n"); var encodedUri = encodeURI(csvContent); var link = document.createElement("a"); link.setAttribute("href", encodedUri); link.setAttribute("download", this.makeSlug() + "_export_" + new Date() + ".csv"); document.body.appendChild(link); // Required for FF this.todo(); link.click(); // This will download the data file named "my_data.csv". } print() { alert('TODO'); } todo() { this.messageService.add({ severity: 'info', detail: "cette fonctionnalité n'est pas encore disponible. Venez en discuter sur framateam.org / Ux et design libre / Framasoft", summary: "Work in progress", }); } }