diff --git a/src/app/core/components/contact/contact.component.html b/src/app/core/components/contact/contact.component.html index 856cb61706ce6a86cb5b78cb796acffd74cf530c..7f2be04253d579220d5d7981a83cc4dec8aac446 100644 --- a/src/app/core/components/contact/contact.component.html +++ b/src/app/core/components/contact/contact.component.html @@ -77,7 +77,7 @@ <label class="label" for="emailConfirmation" i18n="@@contact.emailConfirmation">Confirm your email address</label> <p class="control has-icons-right"> - <input id="emailConfirmation" class="input" type="email" formControlName="emailConfirmation" [ngClass]="{'is-danger': emailConfirmationError || fieldIsInvalid('emailConfirmation'), 'is-success': !emailConfirmationError && fieldIsValid('emailConfirmation')}"> + <input blockCopyPaste id="emailConfirmation" class="input" type="email" formControlName="emailConfirmation" [ngClass]="{'is-danger': emailConfirmationError || fieldIsInvalid('emailConfirmation'), 'is-success': !emailConfirmationError && fieldIsValid('emailConfirmation')}"> <span class="icon is-small is-right has-text-success" *ngIf="!emailConfirmationError && fieldIsValid('emailConfirmation')"> <i class="fas fa-check-circle"></i> </span> @@ -111,19 +111,19 @@ <div class="column is-12-mobile is-10-tablet is-9-desktop"> <div class="field"> - <label class="label" [for]="subjectLabelFor" i18n="@@contact.subject">Sujet</label> + <label class="label" [for]="subjectLabelFor" i18n="@@contact.subject">Subject</label> <div class="dropdown" [ngClass]="{'is-active': subjectDropdownState}" (clickOutside)="closeSubjectDropdown()"> <div class="dropdown-trigger" (click)="toggleSubject()"> - <button id="subjectDropdown" type="button" class="button" aria-haspopup="true" aria-controls="dropdown-menu"> + <button id="subjectDropdown" type="button" class="button" aria-haspopup="true" aria-controls="dropdown-menu" [disabled]="formDisabled"> <span>{{ selectedSubject !== null && selectedSubject.value !== null ? selectedSubject.value : '---'}}</span> <span class="icon is-small"> <i class="fas fa-angle-down" aria-hidden="true"></i> </span> </button> </div> - <div class="dropdown-menu" id="dropdown-menu" role="menu"> + <div class="dropdown-menu" id="dropdown-menu" role="menu"> <ul class="dropdown-content"> - <li class="dropdown-item" *ngFor="let sub of subjects" (click)="setSubject(sub)"> + <li class="dropdown-item" *ngFor="let sub of subjects" (keydown.enter)="setSubject(sub)" (click)="setSubject(sub)" tabindex=0> {{ sub.value }} </li> </ul> @@ -167,7 +167,7 @@ </div> <div class="has-text-right button-wrapper"> - <button type="submit" class="button is-primary" [disabled]="formIsInvalid()" i18n="@@contact.send">Envoyer</button> + <button type="submit" class="button is-primary" [ngClass]="{'is-loading': formDisabled}" [disabled]="formIsInvalid() || formDisabled" i18n="@@contact.send">Send</button> </div> </div> </div> diff --git a/src/app/core/components/contact/contact.component.ts b/src/app/core/components/contact/contact.component.ts index 9861a05384d06b8aff22ae6e9fccd4d523a2cb50..a5c695c4b82946a0da3a57813953df80d9b5e23c 100644 --- a/src/app/core/components/contact/contact.component.ts +++ b/src/app/core/components/contact/contact.component.ts @@ -24,7 +24,7 @@ export class ContactComponent implements OnInit { ) { this.form = this._fb.group( { - firstname: ['', Validators.required], + firstname: ['', [Validators.required]], lastname: ['', Validators.required], email: ['', [Validators.required, Validators.email]], emailConfirmation: ['', [Validators.required, Validators.email]], @@ -33,13 +33,14 @@ export class ContactComponent implements OnInit { }); } - ngOnInit() { - } + ngOnInit() {} send() { const email = new Email(this.form.value); + this.form.disable(); this._emailService.send(email).subscribe( (res) => { + this.form.enable(); this._notificationService.notify( { type: 'success', @@ -49,6 +50,7 @@ export class ContactComponent implements OnInit { this.form.reset(); }, (err) => { + this.form.enable(); this._notificationService.notify( { type: 'error', @@ -90,7 +92,9 @@ export class ContactComponent implements OnInit { } toggleSubject() { - this.subjectDropdownState = !this.subjectDropdownState; + if (!this.formDisabled) { + this.subjectDropdownState = !this.subjectDropdownState; + } } closeSubjectDropdown() { @@ -114,6 +118,9 @@ export class ContactComponent implements OnInit { return this.displaySubjectInput ? 'subjectInput' : 'subjectDropdown'; } + get formDisabled(): boolean { + return this.form.disabled; + } } interface Subject { diff --git a/src/app/shared/directives/block-copypaste.directive.ts b/src/app/shared/directives/block-copypaste.directive.ts new file mode 100644 index 0000000000000000000000000000000000000000..7cb989da64336c3b1758850a9df2f4609dfffdcc --- /dev/null +++ b/src/app/shared/directives/block-copypaste.directive.ts @@ -0,0 +1,20 @@ +import { Directive, HostListener } from '@angular/core'; + +@Directive({ + selector: '[blockCopyPaste]', +}) +export class BlockCopyPasteDirective { + constructor() { } + + @HostListener('paste', ['$event']) blockPaste(e: KeyboardEvent) { + e.preventDefault(); + } + + @HostListener('copy', ['$event']) blockCopy(e: KeyboardEvent) { + e.preventDefault(); + } + + @HostListener('cut', ['$event']) blockCut(e: KeyboardEvent) { + e.preventDefault(); + } +} diff --git a/src/app/shared/directives/index.ts b/src/app/shared/directives/index.ts index b0c41d9454de5db89af758fe186bf1a5c7862a33..79989eb79dd7c268f6ed1e4d29230a25cd8e8b87 100644 --- a/src/app/shared/directives/index.ts +++ b/src/app/shared/directives/index.ts @@ -1,12 +1,14 @@ import { PreventDefaultDirective } from './prevent-default.directive'; import { DynamicLinks } from './dynamic-links'; import { ClickOutsideDirective } from './click-outside.directive'; +import { BlockCopyPasteDirective } from './block-copypaste.directive'; -export { PreventDefaultDirective, DynamicLinks, ClickOutsideDirective }; +export { PreventDefaultDirective, DynamicLinks, ClickOutsideDirective, BlockCopyPasteDirective }; // tslint:disable-next-line:variable-name export const SharedDirectives = [ PreventDefaultDirective, DynamicLinks, ClickOutsideDirective, + BlockCopyPasteDirective, ]; diff --git a/src/i18n/contact/contact.ts b/src/i18n/contact/contact.ts index 76cdd9ff63050c7d743d033a9c7c3f0b6aaf1906..c340e7d73203c4ca57c922d316ae6041d33dbcfc 100644 --- a/src/i18n/contact/contact.ts +++ b/src/i18n/contact/contact.ts @@ -31,5 +31,5 @@ export const subjects = [ export const feedbackMessages = { error: 'Sorry, we couldn\'t send your message, please try again later', - success: 'You message has been sent successfully.', + success: 'Your message has been sent successfully.', }; diff --git a/src/i18n/messages.fr.xlf b/src/i18n/messages.fr.xlf index f5cd22d5d735f5774ea287a3f15abecea2bc1843..87340a0760d3d97c8b6a52e8c33d5b4f78edd533 100644 --- a/src/i18n/messages.fr.xlf +++ b/src/i18n/messages.fr.xlf @@ -337,7 +337,7 @@ </trans-unit> <trans-unit id="contact.emailConfirmation" datatype="html"> <source>Confirm your email address</source> - <target>Confirmez votre adresse email</target> + <target>Confirmez votre adresse email.</target> </trans-unit> <trans-unit id="contact.errors.missingConfirmationEmail" datatype="html"> <source>You must confirm your email address.</source>