check for uniqueness of the slug, slug the title by default

This commit is contained in:
Baptiste Lemoine 2020-01-16 11:33:13 +01:00
parent 5eba5d684b
commit 2720b65962
5 changed files with 71 additions and 28 deletions

View File

@ -59,12 +59,14 @@ export class PollConfig {
// access // access
visibility = 'link_only'; // visible to anyone with the link: visibility = 'link_only'; // visible to anyone with the link:
voteChoices = 'only_yes'; // possible answers to a vote choice: only "yes", "yes, maybe, no" voteChoices = 'only_yes'; // possible answers to a vote choice: only "yes", "yes, maybe, no"
creationDate = new Date();
expirationDate = ''; // expiracy date expirationDate = ''; // expiracy date
pollId = null; // id of the current poll when created. data given by the backend api pollId = null; // id of the current poll when created. data given by the backend api
selectedPoll = null; // current poll selected with createPoll or getPoll of ConfigService selectedPoll = null; // current poll selected with createPoll or getPoll of ConfigService
passwordAccess = 0; passwordAccess = 0;
password = ''; password = '';
customUrl = ''; customUrl = ''; // custom slug in the url, must be unique
customUrlIsUnique = null; // given by the backend
urlPublic = environment.baseApiHref + '/default-url'; urlPublic = environment.baseApiHref + '/default-url';
urlAdmin = environment.baseApiHref + '/default-url/admin/d65es45fd45sdf45sd345f312sdf31sgfd345'; urlAdmin = environment.baseApiHref + '/default-url/admin/d65es45fd45sdf45sd345f312sdf31sgfd345';
canModifyAnswers = 1;// everybody, self, nobody (= just admin) canModifyAnswers = 1;// everybody, self, nobody (= just admin)

View File

@ -107,11 +107,14 @@
class="input-lg" class="input-lg"
name="url" name="url"
id="url" id="url"
[value]="baseUrl+'/'+config.customUrl"> [(ngModel)]="config.customUrl">
<sub class="instructions"> <sub class="instructions">
{{"visibility.access_instructions"|translate}} {{"visibility.access_instructions"|translate}}
</sub> </sub>
<div class="preview-url">
{{baseUrl + '/' + config.customUrl}}
</div>
<br> <br>
<label for="passwordAccess"> <label for="passwordAccess">
{{"visibility.access_want"|translate}} {{"visibility.access_want"|translate}}

View File

@ -17,29 +17,9 @@ export class VisibilityComponent extends BaseComponent implements OnInit {
} }
ngOnInit() { ngOnInit() {
this.config.customUrl = this.makeUuid(); this.config.customUrl = this.config.makeSlug();
this.config.expirationDate = (this.addDaysToDate(this.config.expiracyDateDefaultInDays, new Date())).toISOString().substring(0, 10); this.config.expirationDate = (this.config.addDaysToDate(this.config.expiracyDateDefaultInDays, new Date())).toISOString().substring(0, 10);
} }
/**
* 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);
});
}
/**
* 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;
};
} }

View File

@ -30,6 +30,48 @@ export class ConfigService extends PollConfig {
this.messageService.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 * poll public calls to get non authenticated info
@ -86,6 +128,22 @@ export class ConfigService extends PollConfig {
return requestOptions; 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 * search in localstorage, fallback asking the backend to send an email to the owner if it exists
* @param email * @param email
@ -106,7 +164,7 @@ export class ConfigService extends PollConfig {
.subscribe(res => { .subscribe(res => {
// message: 'Trouvé! Allez voir votre boite email', // message: 'Trouvé! Allez voir votre boite email',
this.myPolls = res; this.myPolls = res;
console.log('res', res) console.log('res', res);
this.loading = false; this.loading = false;
this.messageService.add({ this.messageService.add({
severity: 'success', severity: 'success',

View File

@ -51,7 +51,7 @@ option {
background-color: transparent; background-color: transparent;
background-image: url("./assets/img/fleche_bas.svg"); background-image: url("./assets/img/fleche_bas.svg");
padding-right: 1.5rem; padding-right: 2.5rem;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 9px 8px; background-size: 9px 8px;