diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 06ff11ae21af544d9826869eaf1a5b177e2b1ad6..2c744415a07e4f794f0f01504d281c71ec595631 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -3,10 +3,10 @@ import { Routes, RouterModule, PreloadAllModules } from '@angular/router'; import { AppRoutes } from './routes'; export const routes: Routes = [ - { - path: AppRoutes.research.uri, - loadChildren: './geosource/geosource.module#GeosourceModule', - }, + // { + // path: AppRoutes.research.uri, + // loadChildren: './geosource/geosource.module#GeosourceModule', + // }, ]; @NgModule({ diff --git a/src/app/core/components/contact/contact.component.html b/src/app/core/components/contact/contact.component.html index 7f2be04253d579220d5d7981a83cc4dec8aac446..306e60a7a28bb460f97e6f98878a092c0b7cae08 100644 --- a/src/app/core/components/contact/contact.component.html +++ b/src/app/core/components/contact/contact.component.html @@ -15,7 +15,8 @@ <div class="field"> <label class="label" for="lastname" i18n="@@contact.lastname">Lastname</label> <p class="control has-icons-right"> - <input id="lastname" class="input" type="text" formControlName="lastname" [ngClass]="{'is-danger': fieldIsInvalid('lastname'), 'is-success': fieldIsValid('lastname')}"> + <input id="lastname" class="input" type="text" formControlName="lastname" (keyup)="toUppercase('lastname')" + [ngClass]="{'is-danger': fieldIsInvalid('lastname'), 'is-success': fieldIsValid('lastname')}"> <span class="icon is-small is-right has-text-success" *ngIf="fieldIsValid('lastname')"> <i class="fas fa-check-circle"></i> </span> @@ -28,13 +29,17 @@ <div *ngIf="form.controls['lastname'].errors.required" i18n="@@contact.errors.missingLastname"> You must indicate a lastname. </div> + <div *ngIf="form.controls['lastname'].errors.pattern" i18n="@@contact.errors.lastnamePattern"> + Special characters are forbidden. + </div> </div> </div> <div class="field"> <label class="label" for="firstname" i18n="@@contact.firstname">Firstname</label> <p class="control has-icons-right"> - <input id="firstname" class="input" type="text" formControlName="firstname" [ngClass]="{'is-danger': fieldIsInvalid('firstname'), 'is-success': fieldIsValid('firstname')}"> + <input id="firstname" class="input" type="text" (keyup)="toUppercase('firstname')" formControlName="firstname" + [ngClass]="{'is-danger': fieldIsInvalid('firstname'), 'is-success': fieldIsValid('firstname')}"> <span class="icon is-small is-right has-text-success" *ngIf="fieldIsValid('firstname')"> <i class="fas fa-check-circle"></i> </span> @@ -47,6 +52,9 @@ <div *ngIf="form.controls['firstname'].errors.required" i18n="@@contact.errors.missingFirstname"> You must indicate a firstname. </div> + <div *ngIf="form.controls['lastname'].errors.pattern" i18n="@@contact.errors.firstnamePattern"> + Special characters are forbidden. + </div> </div> </div> @@ -77,7 +85,8 @@ <label class="label" for="emailConfirmation" i18n="@@contact.emailConfirmation">Confirm your email address</label> <p class="control has-icons-right"> - <input blockCopyPaste 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> @@ -114,16 +123,18 @@ <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" [disabled]="formDisabled"> + <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" (keydown.enter)="setSubject(sub)" (click)="setSubject(sub)" tabindex=0> + <li class="dropdown-item" *ngFor="let sub of subjects" (keydown.enter)="setSubject(sub)" (click)="setSubject(sub)" + tabindex=0> {{ sub.value }} </li> </ul> @@ -167,7 +178,9 @@ </div> <div class="has-text-right button-wrapper"> - <button type="submit" class="button is-primary" [ngClass]="{'is-loading': formDisabled}" [disabled]="formIsInvalid() || formDisabled" i18n="@@contact.send">Send</button> + <button class="button button-gl is-outlined" type="button" [disabled]="formDisabled" (click)="cancel()" i18n="@@contact.cancel">Cancel</button> + <button type="submit" class="button button-gl" [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.scss b/src/app/core/components/contact/contact.component.scss index 1ec31ed3bb350b5002212057084441d5dde7d6e2..5b76c9a460dd64dedc83164f35c6b107013d95be 100644 --- a/src/app/core/components/contact/contact.component.scss +++ b/src/app/core/components/contact/contact.component.scss @@ -56,6 +56,14 @@ h3 { cursor: pointer; background-color: lightgrey; } + + .button-gl { + width:8rem; + + &:first-of-type { + margin-right: 1.25rem; + } + } } .title-label.is-danger { diff --git a/src/app/core/components/contact/contact.component.ts b/src/app/core/components/contact/contact.component.ts index a5c695c4b82946a0da3a57813953df80d9b5e23c..f8fc4dc557d0e6e818f6288c44a6197ed2e303df 100644 --- a/src/app/core/components/contact/contact.component.ts +++ b/src/app/core/components/contact/contact.component.ts @@ -1,8 +1,10 @@ import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms'; -import { EmailService, NotificationService } from '../../services'; +import { EmailService, NotificationService, NavigationHistoryService } from '../../services'; import { Email } from '../../models'; import { subjects as Subjects, feedbackMessages } from '../../../../i18n/contact/contact'; +import { Router, ActivatedRoute } from '@angular/router'; +import { AppRoutes } from '../../../routes'; @Component({ selector: 'app-contact', @@ -15,17 +17,24 @@ export class ContactComponent implements OnInit { subjectDropdownState = false; subjects: Subject[] = Subjects; // Keep this line in order to access the subjects in the html template selectedSubject: Subject = null; - displaySubjectInput = false; constructor( private _fb: FormBuilder, private _emailService: EmailService, private _notificationService: NotificationService, + private _navigationHistoryService: NavigationHistoryService, + private _router: Router, + private _route: ActivatedRoute, ) { this.form = this._fb.group( { - firstname: ['', [Validators.required]], - lastname: ['', Validators.required], + firstname: ['', [ + Validators.required, + Validators.pattern('([A-ZÀ-ÖØ-Ý][a-zà-öø-ýÿA-ZÀ-ÖØ-Ý]*)([ \'-][a-zA-ZÀ-ÖØ-öø-ýÿ]*)*'), + ]], + lastname: ['', [Validators.required, + Validators.pattern('([A-ZÀ-ÖØ-Ý][a-zà-öø-ýÿA-ZÀ-ÖØ-Ý]*)([ \'-][a-zA-ZÀ-ÖØ-öø-ýÿ]*)*'), + ]], email: ['', [Validators.required, Validators.email]], emailConfirmation: ['', [Validators.required, Validators.email]], subject: ['', Validators.required], @@ -33,32 +42,43 @@ export class ContactComponent implements OnInit { }); } - ngOnInit() {} + ngOnInit() { + this._route.queryParams.subscribe((params) => { + if (params.subject) { + this.selectedSubject = this.subjects.find(sub => sub.key === 'other'); + this.form.controls.subject.patchValue(params.subject); + } else { + this.selectedSubject = null; + } + }); + } 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', - message: feedbackMessages.success, - }, - ); - this.form.reset(); - }, - (err) => { - this.form.enable(); - this._notificationService.notify( - { - type: 'error', - message: feedbackMessages.error, - }, - ); - }, - ); + if (!this.formIsInvalid) { + const email = new Email(this.form.value); + this.form.disable(); + this._emailService.send(email).subscribe( + (res) => { + this.form.enable(); + this._notificationService.notify( + { + type: 'success', + message: feedbackMessages.success, + }, + ); + this.form.reset(); + }, + (err) => { + this.form.enable(); + this._notificationService.notify( + { + type: 'error', + message: feedbackMessages.error, + }, + ); + }, + ); + } } get emailConfirmationIsCorrect(): boolean { @@ -107,10 +127,17 @@ export class ContactComponent implements OnInit { if (this.selectedSubject.key === 'other') { this.form.controls.subject.patchValue(''); this.form.controls.subject.reset(); - this.displaySubjectInput = true; } else { this.form.controls.subject.patchValue(this.selectedSubject.value); - this.displaySubjectInput = false; + } + } + + cancel() { + const previous = this._navigationHistoryService.getFromLast(1); + if (previous !== null) { + this._router.navigateByUrl(previous); + } else { + this._router.navigateByUrl(AppRoutes.home.uri); } } @@ -121,6 +148,16 @@ export class ContactComponent implements OnInit { get formDisabled(): boolean { return this.form.disabled; } + + get displaySubjectInput(): boolean { + return (this.selectedSubject && this.selectedSubject.key) === 'other' ? true : false; + } + + toUppercase(controlName: string) { + const input = this.form.controls[controlName].value; + const uppercased = input.substring(0, 1).toUpperCase() + input.substring(1); + this.form.controls[controlName].patchValue(uppercased); + } } interface Subject { diff --git a/src/app/geosource/components/dataset-detail/dataset-info/dataset-info.component.html b/src/app/geosource/components/dataset-detail/dataset-info/dataset-info.component.html index 3b9525d52c7d4973b42f82ba901db2d33ce20c6c..ff6f4e9bfd2c101266b5183270318b80a12531dc 100644 --- a/src/app/geosource/components/dataset-detail/dataset-info/dataset-info.component.html +++ b/src/app/geosource/components/dataset-detail/dataset-info/dataset-info.component.html @@ -47,7 +47,8 @@ {{ generalInfo['parent'].keyTitle }} </div> <div class="column is-10 is-size-7 even"> - <a [routerLink]="['/', AppRoutes.research.uri, AppRoutes.datasets.uri, generalInfo['parent'].uuid]">{{ generalInfo['parent'].title }}</a> + <a [routerLink]="['/', AppRoutes.research.uri, AppRoutes.datasets.uri, generalInfo['parent'].uuid]">{{ + generalInfo['parent'].title }}</a> </div> </ng-container> </div> @@ -85,8 +86,14 @@ </ng-container> </div> </div> - + <div class="contact"> + <div class="columns is-marginless"> + <div class="column is-12 title is-size-7"> + Vous avez des questions sur ce jeu de données? <a class="link-red" [routerLink]="['/', AppRoutes.contact.uri]" [queryParams]="{ subject: metadata.title }">Contactez-nous.</a> + </div> + </div> + </div> </div> </div> </div> -</ng-container> +</ng-container> \ No newline at end of file diff --git a/src/app/geosource/components/dataset-detail/dataset-info/dataset-info.component.scss b/src/app/geosource/components/dataset-detail/dataset-info/dataset-info.component.scss index cec3249eef9955a73ba4713a68e442dbca4ff45d..bec1e28d4f117c5a09afd69f1b86e5a0e9c80a9c 100644 --- a/src/app/geosource/components/dataset-detail/dataset-info/dataset-info.component.scss +++ b/src/app/geosource/components/dataset-detail/dataset-info/dataset-info.component.scss @@ -36,7 +36,7 @@ div.unitary-description:not(:first-of-type) { } -.children , .general-info, .articles { +.children , .general-info, .articles, .contact { .column { padding-top: 0.3125rem; padding-bottom: 0.3125rem; diff --git a/src/app/geosource/geosource-routing.module.ts b/src/app/geosource/geosource-routing.module.ts index e1ccd324ab818c99b91e3c33ef6bb5cff72a129f..d17b00236bc3147b151903bedc4a4d67e74e0fea 100644 --- a/src/app/geosource/geosource-routing.module.ts +++ b/src/app/geosource/geosource-routing.module.ts @@ -6,7 +6,7 @@ import { AppRoutes } from '../routes'; export const routes: Routes = [ { - path: '', + path: AppRoutes.research.uri, component: ResearchComponent, data: { title: AppRoutes.research.title, diff --git a/src/i18n/messages.en.xlf b/src/i18n/messages.en.xlf index 4b173f3bce882ff4199f4594bf693cc1c03eaf3c..5b4bdfd6bf7387d21b1eb49a9d32445a27ed23ff 100644 --- a/src/i18n/messages.en.xlf +++ b/src/i18n/messages.en.xlf @@ -307,6 +307,10 @@ <source>You must indicate your lastname.</source> <target>You must indicate your lastname.</target> </trans-unit> + <trans-unit id="contact.errors.forbiddenCharacters" datatype="html"> + <source>Special characters are forbidden.</source> + <target>Special characters are forbidden.</target> + </trans-unit> <trans-unit id="contact.firstname" datatype="html"> <source>Firstname</source> <target>Firstname</target> @@ -363,6 +367,10 @@ <source>Send</source> <target>Send</target> </trans-unit> + <trans-unit id="contact.cancel" datatype="html"> + <source>Cancel</source> + <target>Cancel</target> + </trans-unit> </body> </file> </xliff> diff --git a/src/scss/variables.scss b/src/scss/variables.scss index 2521a1cbfe00bb2b96dff82a3b5bf0aa5fcbfc10..43592a0686a262a0ca66325723bbbccf2058bd87 100644 --- a/src/scss/variables.scss +++ b/src/scss/variables.scss @@ -3,7 +3,8 @@ // 2. Set your own initial variables $main: #17252b; $red: #d5232a; -$green: #04BA5B ; +$green: #04BA5B; +$dark-blue: #333745; $app-background-color: rgb(252, 252, 252); diff --git a/src/styles.scss b/src/styles.scss index 8b2428c13aa347b7750472db023c22e8b2450e01..96eed87e5d9cf812640d63328e850eedecee8700 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -154,4 +154,32 @@ a:hover { } } +.button-gl { + background: linear-gradient(to bottom, #ff6459, $red); + border-radius: 2px; + border-width: 0; + font-size: $size-6; + color: white; + text-transform: uppercase; + &:hover, &:focus { + color:white; + background: $red; + } + &.is-outlined { + border: 2px solid $dark-blue; + font-weight: bold; + color: $dark-blue; + background: transparent; + + &:hover, &:focus { + border-color: $red; + } + } +} + +.link-red { + color: $red; + text-decoration: underline; +} + @import "./scss/wordpress-style"; \ No newline at end of file