File

src/app/services/config.service.ts

Description

le service transverse à chaque page qui permet de syncroniser la configuration de sondage souhaitée

Extends

PollConfig

Index

Properties
Methods

Constructor

constructor(http: HttpClient, messageService: MessageService, router: Router, utils: PollUtilities, confirmationService: ConfirmationService)
Parameters :
Name Type Optional
http HttpClient No
messageService MessageService No
router Router No
utils PollUtilities No
confirmationService ConfirmationService No

Methods

addComment
addComment(comment?: any)

POST /api/v1/poll/{id}/comment

Parameters :
Name Type Optional
comment any Yes
Returns : void
addDaysToDate
addDaysToDate(days: number, date: Date)

add some days to a date, to compute intervals

Parameters :
Name Type Optional
days number No
date Date No
Returns : any
addVote
addVote(voteStack?: any)

POST /api/v1/poll/{id}/vote

Parameters :
Name Type Optional
voteStack any Yes
Returns : void
checkIfSlugIsUniqueInDatabase
checkIfSlugIsUniqueInDatabase(slug: string)
Parameters :
Name Type Optional Default value
slug string No ''
Returns : void
convertChoicesAnsweredToSend
convertChoicesAnsweredToSend(choiceList)

conversion to send to back

Parameters :
Name Optional
choiceList No
Returns : any
createPoll
createPoll()

launch creation call to the api

Returns : void
createPollFromConfig
createPollFromConfig(config: any)

POST /api/v1/poll/{id}/poll

Parameters :
Name Type Optional
config any No
Returns : any
deleteComments
deleteComments()

administrator calls

Returns : void
deletePoll
deletePoll()
Returns : void
deleteVotes
deleteVotes()
Returns : void
exportCSV
exportCSV()

TODO export all the poll data available to the public as a CSV single file

Returns : void
fetchPollFromRoute
fetchPollFromRoute(event)
Parameters :
Name Optional
event No
Returns : void
fillValuesOnDevEnv
fillValuesOnDevEnv()
Returns : void
findLocalStorageData
findLocalStorageData()
Returns : void
findPollsByEmail
findPollsByEmail(email: string)

search in localstorage, fallback asking the backend to send an email to the owner if it exists

Parameters :
Name Type Optional
email string No
Returns : void
getMyPolls
getMyPolls(ownerEmail: string)

GET api/v1/my-polls

Parameters :
Name Type Optional
ownerEmail string No
Returns : void
getPollById
getPollById(id: string, password?: string)

GET api/v1/poll/{id}

Parameters :
Name Type Optional
id string No
password string Yes
Returns : any
getPollByURL
getPollByURL(url: string)

get one poll by its slug name

Parameters :
Name Type Optional
url string No
Returns : any
getPollConfig
getPollConfig()

==================================

poll public calls to get non authenticated info

==================================/ /** convert current poll config to a payload to send to the backend API

Returns : { owner: { email: any; pseudo: any; }; title: any; description: any; pollType: any; visibility: a...
handleError
handleError(err: any)

display error message depending on the response of the backend

Parameters :
Name Type Optional
err any No
Returns : void
handleVoteAdded
handleVoteAdded(res)
Parameters :
Name Optional
res No
Returns : void
loadVoteStack
loadVoteStack(voteStack: any)

update current answers with a previous vote

Parameters :
Name Type Optional
voteStack any No
Returns : void
print
print()
Returns : void
resetCurrentChoicesAnswers
resetCurrentChoicesAnswers()
Returns : void
set
set(key, val)
Parameters :
Name Optional
key No
val No
Returns : void
todo
todo(message: string)
Parameters :
Name Type Optional Default value
message string No ''
Returns : void
updateCurrentPollFromResponse
updateCurrentPollFromResponse(res: any)
Parameters :
Name Type Optional
res any No
Returns : void
updatePoll
updatePoll(voteStack: any)

UPDATE /api/v1/poll/{id}/vote

Parameters :
Name Type Optional Description
voteStack any No

TODO

Returns : void
updateVote
updateVote(voteStack?: any)

UPDATE /api/v1/poll/{id}/vote

Parameters :
Name Type Optional
voteStack any Yes
Returns : void
resetConfig
resetConfig()
Inherited from PollConfig
Defined in PollConfig:68
Returns : void

Properties

baseHref
Type : any
Default value : environment.baseApiHref
loading
Type : boolean
Default value : false
adminKey
Type : string
Default value : ''
Inherited from PollConfig
Defined in PollConfig:58
allowSeveralHours
Type : string
Default value : 'true'
Inherited from PollConfig
Defined in PollConfig:41
answers
Type : PollAnswer[]
Default value : defaultAnswers
Inherited from PollConfig
Defined in PollConfig:66
canModifyAnswers
Type : boolean
Default value : true
Inherited from PollConfig
Defined in PollConfig:60
creationDate
Default value : new Date()
Inherited from PollConfig
Defined in PollConfig:45
currentPoll
Inherited from PollConfig
Defined in PollConfig:50
customUrl
Type : string
Default value : ''
Inherited from PollConfig
Defined in PollConfig:53
customUrlIsUnique
Type : null
Default value : null
Inherited from PollConfig
Defined in PollConfig:54
dateList
Type : any
Default value : otherDefaultDates
Inherited from PollConfig
Defined in PollConfig:63
deletionDateAfterLastModification
Type : number
Default value : 180
Inherited from PollConfig
Defined in PollConfig:27
description
Type : string
Default value : 'ma description'
Inherited from PollConfig
Defined in PollConfig:32
expiracyDateDefaultInDays
Type : number
Default value : 60
Inherited from PollConfig
Defined in PollConfig:26
expirationDate
Type : string
Default value : ''
Inherited from PollConfig
Defined in PollConfig:46
isAdmin
Type : boolean
Default value : true
Inherited from PollConfig
Defined in PollConfig:35
myComment
Type : string
Default value : 'wouah trop bien framadate!'
Inherited from PollConfig
Defined in PollConfig:34
myEmail
Type : string
Default value : "tktest@tktest.com"
Inherited from PollConfig
Defined in PollConfig:38
myName
Type : string
Default value : 'mon pseudo'
Inherited from PollConfig
Defined in PollConfig:33
myPolls
Type : any
Default value : []
Inherited from PollConfig
Defined in PollConfig:39
myTempVoteStack
Type : number
Default value : 0
Inherited from PollConfig
Defined in PollConfig:37
myVoteStack
Type : any
Inherited from PollConfig
Defined in PollConfig:36
owner_modifier_token
Type : string
Default value : ''
Inherited from PollConfig
Defined in PollConfig:59
password
Type : string
Default value : ''
Inherited from PollConfig
Defined in PollConfig:52
passwordAccess
Type : number
Default value : 0
Inherited from PollConfig
Defined in PollConfig:51
pollId
Type : null
Default value : null
Inherited from PollConfig
Defined in PollConfig:48
pollSlug
Type : null
Default value : null
Inherited from PollConfig
Defined in PollConfig:49
pollType
Type : string
Default value : 'dates'
Inherited from PollConfig
Defined in PollConfig:30
step
Type : number
Default value : 0
Inherited from PollConfig
Defined in PollConfig:28
stepMax
Type : number
Default value : 3
Inherited from PollConfig
Defined in PollConfig:29
timeList
Type : DateChoice[]
Default value : otherDefaultDates
Inherited from PollConfig
Defined in PollConfig:64
title
Type : string
Default value : 'titre'
Inherited from PollConfig
Defined in PollConfig:31
urlAdmin
Default value : environment.baseHref + '/#/admin/d65es45fd45sdf45sd345f312sdf31sgfd345'
Inherited from PollConfig
Defined in PollConfig:57
urlPublic
Default value : environment.baseHref + '/#/poll/id/4'
Inherited from PollConfig
Defined in PollConfig:56
urlSlugPublic
Type : null
Default value : null
Inherited from PollConfig
Defined in PollConfig:55
visibility
Type : string
Default value : 'link_only'
Inherited from PollConfig
Defined in PollConfig:43
voteChoices
Type : string
Default value : 'only_yes'
Inherited from PollConfig
Defined in PollConfig:44
voteStackId
Type : null
Default value : null
Inherited from PollConfig
Defined in PollConfig:47
whoCanChangeAnswers
Type : string
Default value : 'everybody'
Inherited from PollConfig
Defined in PollConfig:62
whoModifiesAnswers
Type : string
Default value : "everybody"
Inherited from PollConfig
Defined in PollConfig:61
import {Injectable} from '@angular/core';
import {PollConfig} from '../config/PollConfig';
import {HttpClient} from "@angular/common/http";
import {environment} from "../../environments/environment";
import {ConfirmationService, MessageService} from 'primeng/api';
import {Router} from "@angular/router";
import {mockMyPolls} from "../config/mocks/mockmypolls";
import {mockPoll3} from "../config/mocks/mock-poll3";
import {mockSuccessVote} from "../config/mocks/mock-success-vote";
import {PollUtilities} from "../config/PollUtilities";

/**
 * 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 utils: PollUtilities,
                private confirmationService: ConfirmationService,
    ) {
        super();
        this.fillValuesOnDevEnv();
    }

    set(key, val) {
        this[key] = val;
    }

    // fill in mock values if we are not in production environment
    fillValuesOnDevEnv() {

        if (!environment.production) {
            console.info(' ######### framadate ######### we are not in production env, filling with mock values');
            this.currentPoll = mockPoll3;
            this.myPolls = mockMyPolls;
        }
    }

    /**
     * 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 = {
            owner: {
                email: this.myEmail,
                pseudo: this.myName,
            },
            title: this.title,
            description: this.description,
            pollType: 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,
            expiracyDateDefaultInDays: this.expiracyDateDefaultInDays,
            deletionDateAfterLastModification: this.deletionDateAfterLastModification,
        };
        return jsonConfig
    }


    checkIfSlugIsUniqueInDatabase(slug: string = '') {
        this.customUrlIsUnique = null;
        if (!slug) {
            slug = this.utils.makeSlug(this);
        }

        this.loading = true;
        // TODO
        this.todo('check slug is unique');
        this.http.get(`${this.baseHref}/check-slug-is-uniq/${slug}`,
            this.utils.makeHeaders({slug: this.customUrl}),
        )
            .subscribe((res: any) => {

                    this.customUrlIsUnique = res.poll.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.todo('send email for real : TODO');
        this.loading = true;
        this.http.get(`${this.baseHref}/send-polls-to-user/${this.myEmail}`,
            this.utils.makeHeaders(),
        )
            .subscribe(res => {
                    //     message: 'Trouvé! Allez voir votre boite email',
                    this.myPolls = res;
                    this.loading = false;
                    this.messageService.add({
                        severity: 'success',
                        summary: 'Succès',
                        detail: `Vos infos de sondages vous ont été transmises. Allez voir votre boite email ${this.myEmail}`
                    });
                }, (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
        console.log('localStorage', localStorage);
        if (localStorage) {
            console.log('localStorage', localStorage)
        }
    }


    /**
     * get one poll by its slug name
     * @param url
     */
    getPollByURL(url: string) {

        this.todo();
        return this.http.get(`${this.baseHref}/poll/slug/${url}`, this.utils.makeHeaders())
    }

    /**
     * GET
     * api/v1/poll/{id}
     * @param id
     */
    getPollById(id: string, password?: string) {

        return this.http
            .get(`${this.baseHref}/poll/${id}`,
                this.utils.makeHeaders({body: password}))
    }

    fetchPollFromRoute(event) {
        console.log('time to fetch poll', event)
    }

    /**
     * GET
     * api/v1/my-polls
     * @param ownerEmail
     */
    getMyPolls(ownerEmail: string) {
        this.http
            .get(`${this.baseHref}/my-polls`,
                this.utils.makeHeaders({ownerEmail: ownerEmail})
            )
            .subscribe(
                (res: any) => {
                    // this.myPolls = res.poll;
                }, (e) => {
                    this.handleError(e)
                }
            );
    }


    /**
     * launch creation call to the api
     */
    createPoll() {
        this.loading = true;
        this.createPollFromConfig(this.getPollConfig())
    }

    updateCurrentPollFromResponse(res: any) {
        console.log('update res', res);
        this.currentPoll = res;
        this.pollId = res.poll.id;
        this.owner_modifier_token = res.owner_modifier_token;
        this.urlPublic = this.baseHref + '#/vote/poll/id/' + res.poll.id;
        this.urlSlugPublic = this.baseHref + '#/vote/poll/slug/' + res.poll.id;
        if (res.poll.customUrl) {
            this.urlSlugPublic = this.baseHref + '#/vote/poll/id/' + res.poll.customUrl;
        }
        if (res.voteStack) {
            this.loadVoteStack(res.voteStack);
        }
        this.adminKey = res.admin_key;
        this.urlAdmin = this.baseHref + '#/admin/' + res.admin_key;
    }

    resetCurrentChoicesAnswers() {
        this.currentPoll.choices.map(choice => {
            choice.answer = null;
        })
    }

    /**
     * update current answers with a previous vote
     * @param voteStack
     */
    loadVoteStack(voteStack: any) {

        // load the pseudo and email
        this.myName = voteStack.pseudo;
        this.myEmail = voteStack.email;
        this.voteStackId = voteStack.id;
        this.myVoteStack = voteStack;
        let keys = Object.keys(voteStack.votes);
        console.log('voteStack', voteStack);
        this.resetCurrentChoicesAnswers();
        keys.forEach((id: any) => {
            let voteItem = voteStack.votes[id];

            /**
             * the display of the poll uses the choices data, so we update the choices answers of the current poll to reflect the vote stack we have taken
             */
            if (voteItem.choice_id && voteItem.value) {
                let foundChoiceToModify = this.currentPoll.choices.find(choicesItem => {
                    return voteItem.choice_id == choicesItem.id
                });
                console.log('foundChoiceToModify', foundChoiceToModify);
                if (foundChoiceToModify) {
                    foundChoiceToModify.answer = voteItem.value;
                }
            }
        })
    }

    /**
     * POST
     * /api/v1/poll/{id}/poll
     * @param config
     */
    createPollFromConfig(config: any) {
        this.loading = true;
        console.log('config', config);
        return this.http.post(`${this.baseHref}/poll`,
            config,
            this.utils.makeHeaders())
            .subscribe((res: any) => {
                    // redirect to the page to administrate the new poll
                    this.messageService.add({severity: 'success', summary: 'Sondage Créé',});

                    this.updateCurrentPollFromResponse(res);

                    this.loading = false;
                    if (!this.myPolls) {
                        this.myPolls = [];
                    }
                    this.myPolls.push(res);
                    this.router.navigate(['step/end']);
                    // TODO save new poll to localstorage
                    // reset all fields in current config
                    this.resetConfig();
                }, (e) => {
                    this.handleError(e)
                }
            );
    }

    /**
     * conversion to send to back
     * @param choiceList
     */
    convertChoicesAnsweredToSend(choiceList) {
        choiceList = choiceList.filter(c => c.answer ? c : null); // remove choices where we did not answer
        const converted = choiceList.map(elem => {
            if (elem.answer) {
                return {
                    choice_id: elem.id,
                    value: elem.answer
                }
            }
        });
        console.log('converted', converted);
        return converted;
    }

    /**
     * POST
     * /api/v1/poll/{id}/vote
     * @param voteStack
     */
    addVote(voteStack?: any) {
        if (!voteStack) {
            voteStack = {
                pseudo: this.myName,
                email: this.myEmail,
                votes: this.convertChoicesAnsweredToSend(this.currentPoll.choices),
            }
        }
        this.myVoteStack = voteStack;

        if (!environment.production) {
            this.handleVoteAdded(mockSuccessVote);
            return;
        }
        this.http.post(
            `${this.baseHref}/poll/${this.pollId}/vote`,
            voteStack,
            this.utils.makeHeaders())
            .subscribe((res: any) => {

                    this.handleVoteAdded(res);
                }, (e) => {
                    this.handleError(e)
                }
            );
    }

    handleVoteAdded(res) {
        this.messageService.add({severity: 'success', summary: 'Vote ajouté'});
        // save modifier token
        this.myVoteStack['modifier_token'] = res.modifier_token;
        this.myVoteStack['id'] = res.vote_stack.id;
        this.updateCurrentPollFromResponse(res);
    }

    /**
     * UPDATE
     * /api/v1/poll/{id}/vote
     * @param voteStack
     */
    updateVote(voteStack?: any) {
        if (!this.myVoteStack) {
            return;

        } else {
            voteStack = this.myVoteStack;
        }
        this.http.patch(
            `${this.baseHref}/vote-stack/${voteStack.id}/token/${this.owner_modifier_token}`,
            voteStack,
            this.utils.makeHeaders())
            .subscribe((res: any) => {
                    this.messageService.add({severity: 'success', summary: 'Vote mis à jour'});
                    this.updateCurrentPollFromResponse(res);
                }, (e) => {
                    this.handleError(e)
                }
            );
    }

    /**
     * POST
     * /api/v1/poll/{id}/comment
     * @param comment
     */
    addComment(comment?: any) {
        if (!comment && this.myComment) {
            comment = {
                name: this.myName,
                pseudo: this.myName,
                email: this.myEmail,
                date: new Date(),
                text: this.myComment,
            }
        }
        console.log('comment', comment);
        this.http.post(
            `${this.baseHref}/poll/${this.pollId}/comment`,
            comment,
            this.utils.makeHeaders())
            .subscribe((res: any) => {
                    this.messageService.add({
                        severity: 'success',
                        summary: 'Commentaire Créé',
                        detail: comment.text
                    });
                    // empty comment after success
                    this.myComment = '';
                    comment.date = {
                        date: comment.date
                    };
                    this.currentPoll.comments.push(comment);
                }, (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.utils.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.utils.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.utils.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
     * TODO
     */
    updatePoll(voteStack: any) {
        this.http.put(
            `${this.baseHref}/poll/${this.pollId}`,
            voteStack,
            this.utils.makeHeaders()
        )
            .subscribe((res: any) => {
                    this.messageService.add({
                        severity: 'success',
                        summary: 'Sondage mis à jour',
                    });
                    this.updateCurrentPollFromResponse(res);
                }, (e) => {
                    this.handleError(e)
                }
            );
    }

    /**
     *  TODO
     * export all the poll data available to the public as a CSV single file
     */
    exportCSV() {


        let rows = [];
        let now = new Date();
        const headers = [
            ['export de sondage Framadate ', this.customUrl],
            ['le', now.toISOString()],
            [this.currentPoll.pollId, this.currentPoll.title, this.customUrl, this.creationDate],
            ['pseudo']];


        let listOfChoices = ['choices : '];
        this.currentPoll.choices.map(choice => {
            listOfChoices.push(choice.text)
        });
        listOfChoices.push('pseudo');

        this.currentPoll.stacks.map(voteStack => {
            let voteStackInArray = [voteStack.pseudo];
            let keysVotes = Object.keys(voteStack.votes);

            keysVotes.map(id => {
                voteStackInArray.push(voteStack.votes[id].value ? voteStack.votes[id].value : "")
            });
            rows.push(
                voteStackInArray
            );
        });
        const headersComments = [
            ['comments'],
            ['pseudo', 'text', 'creation_date'],
        ];
        const comments = [];
        this.currentPoll.comments.map(item => {
            comments.push(
                [item.pseudo,
                    item.text,
                    item.date.date,
                    '\n']
            )
        });
        headers.push(listOfChoices);
        rows = [headers, listOfChoices, rows, headersComments, comments];

        let convertedCsv = rows.map(elem => {
            console.log('elem', elem);
            return elem.map(item => {
                console.log('item', item);
                if (typeof item === typeof Array) {
                    return item.join('\n')
                }
                return item;
            }).join('\n')
        }).join('\n');
        console.log('rows', rows);
        console.log('convertedCsv', convertedCsv);

        let csvContent = "data:text/csv;charset=utf-8,"
            + convertedCsv;
        console.log('csvContent', csvContent);
        var encodedUri = encodeURI(csvContent);
        var link = document.createElement("a");
        link.setAttribute("href", encodedUri);
        let exportFileName = (this.urlPublic ? this.urlPublic : this.utils.makeSlug(this)) + "_export_" + new Date() + ".csv";
        link.setAttribute("download", exportFileName);
        document.body.appendChild(link); // Required for FF
        link.click(); // This will download the data file named "my_data.csv".
    }

    print() {
        alert('TODO');
    }

    todo(message = '') {
        this.messageService.add({
            severity: 'info' + message,
            detail: "cette fonctionnalité n'est pas encore disponible. Venez en discuter sur framateam.org / Ux et design libre / Framasoft",
            summary: "Work in progress",
        });
    }
}

result-matching ""

    No results matching ""