diff --git a/src/app/config/DateUtilities.ts b/src/app/config/DateUtilities.ts
new file mode 100644
index 00000000..7184242d
--- /dev/null
+++ b/src/app/config/DateUtilities.ts
@@ -0,0 +1,59 @@
+export class DateUtilities {
+
+ /**
+ * 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;
+ };
+
+ /**
+ *
+ * @param d1
+ * @param d2
+ * @param interval
+ */
+ getDatesInRange(d1: Date, d2: Date, interval: number) {
+ d1 = new Date(d1);
+ d2 = new Date(d2);
+ const dates = [];
+ while (+d1 < +d2) {
+ dates.push({
+ literal: this.formateDate(d1),
+ date_object: d1
+ });
+ d1.setDate(d1.getDate() + interval)
+ }
+ return dates.slice(0);
+ }
+
+ /**
+ * get the number of days between two dates
+ * @param d1
+ * @param d2
+ */
+ dayDiff(d1: Date, d2: Date): Number {
+ return Number(((d2.getTime()) - (d1.getTime()) / 31536000000));
+ }
+
+ /**
+ * format a date object to the date format used by the inputs of type date
+ * YYYY-MM-DD
+ * @param date
+ */
+ formateDate(date) {
+ return [
+ date.getFullYear(),
+ this.getDoubleDigits(date.getMonth() + 1),
+ this.getDoubleDigits(date.getDate()),
+ ].join('-')
+ }
+
+ getDoubleDigits(str) {
+ return ("00" + str).slice(-2);
+ }
+}
diff --git a/src/app/config/PollUtilities.ts b/src/app/config/PollUtilities.ts
new file mode 100644
index 00000000..02aec5b1
--- /dev/null
+++ b/src/app/config/PollUtilities.ts
@@ -0,0 +1,61 @@
+import {HttpHeaders} from "@angular/common/http";
+import {PollConfig} from "./PollConfig";
+
+export class PollUtilities {
+ // utils functions
+ /**
+ * 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);
+ });
+ }
+
+ /**
+ * make a uniq slug for the current poll creation
+ * @param str
+ */
+ makeSlug(config: PollConfig) {
+ let str = '';
+ str = config.creationDate.getFullYear() + '_' + (config.creationDate.getMonth() + 1) + '_' + config.creationDate.getDate() + '_' + config.myName + '_' + config.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;
+ }
+
+ /**
+ * prepare headers like the charset and json type for any call to the backend
+ * @param bodyContent
+ */
+ makeHeaders(bodyContent?: any) {
+
+ const headerDict = {
+ 'Charset': 'UTF-8',
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json',
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
+ 'Access-Control-Allow-Origin': '*'
+ };
+
+ const requestOptions = {
+ headers: new HttpHeaders(headerDict),
+ body: bodyContent
+ };
+
+ return requestOptions;
+ }
+}
diff --git a/src/app/pages/dates/dates.component.ts b/src/app/pages/dates/dates.component.ts
index 25aa8676..ac115807 100644
--- a/src/app/pages/dates/dates.component.ts
+++ b/src/app/pages/dates/dates.component.ts
@@ -4,6 +4,7 @@ import {BaseComponent} from '../base-page/base.component';
import {DOCUMENT} from '@angular/common';
import {MessageService} from "primeng/api";
import {defaultTimeOfDay} from "../../config/defaultConfigs";
+import {DateUtilities} from "../../config/DateUtilities";
@Component({
selector: 'framadate-dates',
@@ -20,6 +21,7 @@ export class DatesComponent extends BaseComponent implements OnInit {
constructor(public config: ConfigService,
private cd: ChangeDetectorRef,
private messageService: MessageService,
+ private dateUtilities: DateUtilities,
@Inject(DOCUMENT) private document: any
) {
super(config);
@@ -28,7 +30,7 @@ export class DatesComponent extends BaseComponent implements OnInit {
countDays() {
// compute the number of days in the date interval
if (this.endDateInterval && this.startDateInterval) {
- this.intervalDays = (this.dayDiff(this.endDateInterval, this.startDateInterval)).toFixed(0)
+ this.intervalDays = (this.dateUtilities.dayDiff(this.endDateInterval, this.startDateInterval)).toFixed(0)
}
}
@@ -39,7 +41,7 @@ export class DatesComponent extends BaseComponent implements OnInit {
let dateCurrent = new Date();
const dateJson = dateCurrent.toISOString();
this.startDateInterval = dateJson.substring(0, 10);
- this.endDateInterval = this.addDaysToDate(this.intervalDaysDefault, dateCurrent).toISOString().substring(0, 10);
+ this.endDateInterval = this.dateUtilities.addDaysToDate(this.intervalDaysDefault, dateCurrent).toISOString().substring(0, 10);
}
addDate() {
@@ -77,16 +79,6 @@ export class DatesComponent extends BaseComponent implements OnInit {
this.config.timeList = defaultTimeOfDay;
}
- /**
- * 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;
- };
/**
* add a time period to a specific date choice,
@@ -123,7 +115,7 @@ export class DatesComponent extends BaseComponent implements OnInit {
* add all the dates between the start and end dates in the interval section
*/
addIntervalOfDates() {
- let newIntervalArray = this.getDatesInRange(this.startDateInterval, this.endDateInterval, 1);
+ let newIntervalArray = this.dateUtilities.getDatesInRange(this.startDateInterval, this.endDateInterval, 1);
const converted = [];
newIntervalArray.forEach(element => {
@@ -144,49 +136,5 @@ export class DatesComponent extends BaseComponent implements OnInit {
}
- /**
- *
- * @param d1
- * @param d2
- * @param interval
- */
- getDatesInRange(d1: Date, d2: Date, interval: number) {
- d1 = new Date(d1);
- d2 = new Date(d2);
- const dates = [];
- while (+d1 < +d2) {
- dates.push({
- literal: this.formateDate(d1),
- date_object: d1
- });
- d1.setDate(d1.getDate() + interval)
- }
- return dates.slice(0);
- }
- /**
- * get the number of days between two dates
- * @param d1
- * @param d2
- */
- dayDiff(d1: Date, d2: Date): Number {
- return Number(((d2.getTime()) - (d1.getTime()) / 31536000000));
- }
-
- /**
- * format a date object to the date format used by the inputs of type date
- * YYYY-MM-DD
- * @param date
- */
- formateDate(date) {
- return [
- date.getFullYear(),
- this.getDoubleDigits(date.getMonth() + 1),
- this.getDoubleDigits(date.getDate()),
- ].join('-')
- }
-
- getDoubleDigits(str) {
- return ("00" + str).slice(-2);
- }
}
diff --git a/src/app/pages/poll-display/poll-display.component.html b/src/app/pages/poll-display/poll-display.component.html
index 30e5c211..2cc90cf6 100644
--- a/src/app/pages/poll-display/poll-display.component.html
+++ b/src/app/pages/poll-display/poll-display.component.html
@@ -9,19 +9,18 @@
-
-
-
-
-
-
+
+
+
+
+
diff --git a/src/app/pages/visibility/visibility.component.ts b/src/app/pages/visibility/visibility.component.ts
index 78778c63..993a90fa 100644
--- a/src/app/pages/visibility/visibility.component.ts
+++ b/src/app/pages/visibility/visibility.component.ts
@@ -2,6 +2,7 @@ import {Component, OnInit} from '@angular/core';
import {BaseComponent} from '../base-page/base.component';
import {ConfigService} from '../../services/config.service';
import {environment} from "../../../environments/environment";
+import {PollUtilities} from "../../config/PollUtilities";
@Component({
selector: 'framadate-visibility',
@@ -13,12 +14,13 @@ export class VisibilityComponent extends BaseComponent implements OnInit {
baseUrl = environment.baseApiHref;
environment = environment;
- constructor(public config: ConfigService) {
+ constructor(public config: ConfigService,
+ public utils: PollUtilities) {
super(config);
}
ngOnInit() {
- this.config.customUrl = this.config.makeSlug();
+ this.config.customUrl = this.utils.makeSlug(this.config);
this.config.expirationDate = (this.config.addDaysToDate(this.config.expiracyDateDefaultInDays, new Date())).toISOString().substring(0, 10);
}
diff --git a/src/app/services/config.service.ts b/src/app/services/config.service.ts
index 3d5a0e6e..f849a5ed 100644
--- a/src/app/services/config.service.ts
+++ b/src/app/services/config.service.ts
@@ -1,6 +1,6 @@
import {Injectable} from '@angular/core';
import {PollConfig} from '../config/PollConfig';
-import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {HttpClient} from "@angular/common/http";
import {environment} from "../../environments/environment";
import {ConfirmationService, MessageService} from 'primeng/api';
import {Router} from "@angular/router";
@@ -8,6 +8,7 @@ import {mockMyPolls} from "../config/mocks/mockmypolls";
import {defaultAnswers, defaultDates, defaultTimeOfDay} from "../config/defaultConfigs";
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
@@ -24,10 +25,20 @@ export class ConfigService extends PollConfig {
constructor(private http: HttpClient,
private messageService: MessageService,
private router: Router,
+ private utils: PollUtilities,
private confirmationService: ConfirmationService,
) {
super();
- // fill in mock values if we are not in production environment
+ 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;
@@ -38,50 +49,6 @@ export class ConfigService extends PollConfig {
}
}
- set(key, val) {
- this[key] = val;
- }
-
- clear() {
- this.messageService.clear();
- }
-
- // utils functions
- /**
- * 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);
- });
- }
-
- /**
- * make a uniq slug for the current poll creation
- * @param str
- */
- 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
@@ -128,39 +95,18 @@ export class ConfigService extends PollConfig {
return jsonConfig
}
- /**
- * prepare headers like the charset and json type for any call to the backend
- * @param bodyContent
- */
- makeHeaders(bodyContent?: any) {
-
- const headerDict = {
- 'Charset': 'UTF-8',
- 'Content-Type': 'application/json',
- 'Accept': 'application/json',
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
- 'Access-Control-Allow-Origin': '*'
- };
-
- const requestOptions = {
- headers: new HttpHeaders(headerDict),
- body: bodyContent
- };
-
- return requestOptions;
- }
checkIfSlugIsUniqueInDatabase(slug: string = '') {
this.customUrlIsUnique = null;
if (!slug) {
- slug = this.makeSlug();
+ 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.makeHeaders({slug: this.customUrl}),
+ this.utils.makeHeaders({slug: this.customUrl}),
)
.subscribe((res: any) => {
@@ -177,7 +123,6 @@ export class ConfigService extends PollConfig {
*/
findPollsByEmail(email: string) {
-
this.findLocalStorageData();
// If no key is found in the localstorage, ask the backend to send an email to the user
@@ -187,7 +132,7 @@ export class ConfigService extends PollConfig {
this.todo('send email for real : TODO');
this.loading = true;
this.http.get(`${this.baseHref}/send-polls-to-user/${this.myEmail}`,
- this.makeHeaders(),
+ this.utils.makeHeaders(),
)
.subscribe(res => {
// message: 'Trouvé! Allez voir votre boite email',
@@ -232,7 +177,7 @@ export class ConfigService extends PollConfig {
getPollByURL(url: string) {
this.todo();
- return this.http.get(`${this.baseHref}/poll/slug/${url}`, this.makeHeaders())
+ return this.http.get(`${this.baseHref}/poll/slug/${url}`, this.utils.makeHeaders())
}
/**
@@ -244,7 +189,7 @@ export class ConfigService extends PollConfig {
return this.http
.get(`${this.baseHref}/poll/${id}`,
- this.makeHeaders({body: password}))
+ this.utils.makeHeaders({body: password}))
}
fetchPollFromRoute(event) {
@@ -259,7 +204,7 @@ export class ConfigService extends PollConfig {
getMyPolls(ownerEmail: string) {
this.http
.get(`${this.baseHref}/my-polls`,
- this.makeHeaders({ownerEmail: ownerEmail})
+ this.utils.makeHeaders({ownerEmail: ownerEmail})
)
.subscribe(
(res: any) => {
@@ -313,7 +258,7 @@ export class ConfigService extends PollConfig {
this.myEmail = voteStack.email;
this.voteStackId = voteStack.id;
this.myVoteStack = voteStack;
- let keys = Object.keys(voteStack.votes)
+ let keys = Object.keys(voteStack.votes);
console.log('voteStack', voteStack);
this.resetCurrentChoicesAnswers();
keys.forEach((id: any) => {
@@ -326,7 +271,7 @@ export class ConfigService extends PollConfig {
let foundChoiceToModify = this.currentPoll.choices.find(choicesItem => {
return voteItem.choice_id == choicesItem.id
});
- console.log('foundChoiceToModify', foundChoiceToModify)
+ console.log('foundChoiceToModify', foundChoiceToModify);
if (foundChoiceToModify) {
foundChoiceToModify.answer = voteItem.value;
}
@@ -344,7 +289,7 @@ export class ConfigService extends PollConfig {
console.log('config', config);
return this.http.post(`${this.baseHref}/poll`,
config,
- this.makeHeaders())
+ this.utils.makeHeaders())
.subscribe((res: any) => {
// redirect to the page to administrate the new poll
this.messageService.add({severity: 'success', summary: 'Sondage Créé',});
@@ -406,7 +351,7 @@ export class ConfigService extends PollConfig {
this.http.post(
`${this.baseHref}/poll/${this.pollId}/vote`,
voteStack,
- this.makeHeaders())
+ this.utils.makeHeaders())
.subscribe((res: any) => {
this.handleVoteAdded(res);
@@ -439,7 +384,7 @@ export class ConfigService extends PollConfig {
this.http.patch(
`${this.baseHref}/vote-stack/${voteStack.id}/token/${this.owner_modifier_token}`,
voteStack,
- this.makeHeaders())
+ this.utils.makeHeaders())
.subscribe((res: any) => {
this.messageService.add({severity: 'success', summary: 'Vote mis à jour'});
this.updateCurrentPollFromResponse(res);
@@ -468,7 +413,7 @@ export class ConfigService extends PollConfig {
this.http.post(
`${this.baseHref}/poll/${this.pollId}/comment`,
comment,
- this.makeHeaders())
+ this.utils.makeHeaders())
.subscribe((res: any) => {
this.messageService.add({
severity: 'success',
@@ -499,7 +444,7 @@ export class ConfigService extends PollConfig {
accept: () => {
this.http.delete(
`${this.baseHref}/poll/${this.pollId}/comments`,
- this.makeHeaders())
+ this.utils.makeHeaders())
.subscribe((res: any) => {
this.messageService.add({
severity: 'success',
@@ -522,7 +467,7 @@ export class ConfigService extends PollConfig {
accept: () => {
this.http.delete(
`${this.baseHref}/poll/${this.pollId}/votes`,
- this.makeHeaders())
+ this.utils.makeHeaders())
.subscribe((res: any) => {
this.messageService.add({
severity: 'success',
@@ -553,7 +498,7 @@ export class ConfigService extends PollConfig {
accept: () => {
this.http.delete(
`${this.baseHref}/poll/${this.pollId}`,
- this.makeHeaders())
+ this.utils.makeHeaders())
.subscribe((res: any) => {
this.messageService.add({
severity: 'success',
@@ -580,7 +525,7 @@ export class ConfigService extends PollConfig {
this.http.put(
`${this.baseHref}/poll/${this.pollId}`,
voteStack,
- this.makeHeaders()
+ this.utils.makeHeaders()
)
.subscribe((res: any) => {
this.messageService.add({
@@ -644,7 +589,7 @@ export class ConfigService extends PollConfig {
rows = [headers, listOfChoices, rows, headersComments, comments];
let convertedCsv = rows.map(elem => {
- console.log('elem', elem)
+ console.log('elem', elem);
return elem.map(item => {
console.log('item', item);
if (typeof item === typeof Array) {
@@ -658,11 +603,11 @@ export class ConfigService extends PollConfig {
let csvContent = "data:text/csv;charset=utf-8,"
+ convertedCsv;
- console.log('csvContent', csvContent)
+ console.log('csvContent', csvContent);
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
- let exportFileName = (this.urlPublic ? this.urlPublic : this.makeSlug()) + "_export_" + new Date() + ".csv";
+ 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".