diff --git a/projects/admin/src/app/class/library.ts b/projects/admin/src/app/class/library.ts index 13580fcec..9ba2be8a5 100644 --- a/projects/admin/src/app/class/library.ts +++ b/projects/admin/src/app/class/library.ts @@ -52,6 +52,14 @@ export interface ExceptionDates { repeat?: Repeat; } +export interface NotificationSettings { + type: string; + email: string; + template: string; + delay_availability?: number; + language?: string; +} + export class Library { // CLASS ATTRIBUTES ================================================ @@ -63,6 +71,7 @@ export class Library { code: string = null; opening_hours: Array = []; exception_dates?: Array; + notification_settings?: Array; organisation: Organisation; // GETTER & SETTER ================================================ diff --git a/projects/admin/src/app/record/custom-editor/libraries/library-form.service.ts b/projects/admin/src/app/record/custom-editor/libraries/library-form.service.ts index fbf5f4565..99de30633 100644 --- a/projects/admin/src/app/record/custom-editor/libraries/library-form.service.ts +++ b/projects/admin/src/app/record/custom-editor/libraries/library-form.service.ts @@ -17,10 +17,11 @@ import { Injectable } from '@angular/core'; import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { TimeValidator } from '@rero/ng-core'; +import { RecordService, TimeValidator } from '@rero/ng-core'; import { WeekDays } from '../../../class/week-days'; -import { Library } from '../../../class/library'; +import { Library, NotificationSettings } from '../../../class/library'; +import { Subject } from 'rxjs'; @Injectable({ providedIn: 'root' @@ -29,14 +30,22 @@ export class LibraryFormService { public form; + + private notificationTypes = []; + + /** Observable for build event */ + private buildEvent = new Subject(); + constructor( - private fb: FormBuilder - ) { - this.build(); - } + private _fb: FormBuilder, + private _recordService: RecordService + ) { } + /** + * Build form + */ build() { - this.form = this.fb.group({ + this.form = this._fb.group({ name: ['', [ Validators.required, Validators.minLength(4) @@ -48,11 +57,34 @@ export class LibraryFormService { Validators.required ] }], - opening_hours: this.fb.array([]) + opening_hours: this._fb.array([]), + notification_settings: this._fb.array([]) }); this.initializeOpeningHours(); + this.initializeNotificationSettings(); + } + + /** + * Get build event + */ + getBuildEvent() { + return this.buildEvent.asObservable(); } + create() { + this._recordService + .getSchemaForm('notifications') + .subscribe((jsonSchema: any) => { + this.notificationTypes = jsonSchema.schema.properties.notification_type.enum; + this.build(); + this.buildEvent.next(true); + }); + } + + /** + * Build and set default values for opening hours at form initialization + * @param openingHours - opening hours + */ initializeOpeningHours(openingHours = []) { const days = Object.keys(WeekDays); const hours = this.form.get('opening_hours'); @@ -60,12 +92,16 @@ export class LibraryFormService { hours.push(this.buildOpeningHours( false, days[step], - this.fb.array([]) + this._fb.array([]) )); } this.setOpeningHours(openingHours); } + /** + * Set opening hours from record data + * @param openingHours - opening hours + */ setOpeningHours(openingHours = []) { for (let step = 0; step < 7; step++) { const atimes = this.getTimesByDayIndex(step); @@ -85,8 +121,14 @@ export class LibraryFormService { } } + /** + * Create opening hour form control + * @param isOpen - is open + * @param day - day + * @param times - times array + */ buildOpeningHours(isOpen, day, times): FormGroup { - return this.fb.group({ + return this._fb.group({ is_open: [isOpen], day: [day], times @@ -95,9 +137,14 @@ export class LibraryFormService { }); } + /** + * Create times form control + * @param startTime - start time + * @param endTime - end time + */ buildTimes(startTime = '00:01', endTime = '23:59'): FormGroup { const regex = '^(?!(0:00)|(00:00)$)([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$'; - return this.fb.group({ + return this._fb.group({ start_time: [startTime, { validators: [ Validators.required, @@ -115,10 +162,10 @@ export class LibraryFormService { }); } - reset() { - this.build(); - } - + /** + * Populate the form + * @param library - library + */ populate(library: Library) { this.form.patchValue({ name: library.name, @@ -127,6 +174,66 @@ export class LibraryFormService { code: library.code, }); this.setOpeningHours(library.opening_hours); + this.setNotificationSettings(library.notification_settings); + } + + /** + * Build an set default values for notification settings + * @param notificationSettings - notification settings + */ + initializeNotificationSettings(notificationSettings = []) { + const settings = this.form.get('notification_settings'); + this.notificationTypes.forEach(type => { + settings.push(this.getSettingsByType(type)); + }); + this.setNotificationSettings(notificationSettings); + } + + /** + * Get setting by type + * @param settingType - setting type + */ + getSettingsByType(settingType: string) { + const model: NotificationSettings = { + type: settingType, + email: '', + template: '' + }; + switch (settingType) { + case('availability'): + model.delay_availability = 0; + break; + case('booking'): + case('transit_notice'): + case('request'): + model.language = ''; + break; + } + return this._fb.group(model); + } + + /** + * Set values from record + * @param notificationSettings - notification settings + */ + setNotificationSettings(notificationSettings = []) { + if (notificationSettings.length > 0) { + const formSettings = this.form.get('notification_settings'); + for (let step = 0; step < formSettings.value.length; step++) { + const formSetting = formSettings.get(String(step)); + const currentSetting = notificationSettings.find(element => element.type === formSetting.get('type').value); + if (currentSetting !== undefined) { + formSetting.get('email').setValue(currentSetting.email); + formSetting.get('template').setValue(currentSetting.template); + if (currentSetting.language !== undefined) { + formSetting.get('language').setValue(currentSetting.language); + } + if (currentSetting.delay_availability !== undefined) { + formSetting.get('delay_availability').setValue(currentSetting.delay_availability); + } + } + } + } } setId(id) { this.form.value.id = id; } @@ -140,6 +247,9 @@ export class LibraryFormService { get opening_hours() { return this.form.get('opening_hours') as FormArray; } + get notification_settings() { + return this.form.get('notification_settings') as FormArray; + } getValues() { return this.form.value; } diff --git a/projects/admin/src/app/record/custom-editor/libraries/library.component.html b/projects/admin/src/app/record/custom-editor/libraries/library.component.html index af9c15163..2632d48ba 100644 --- a/projects/admin/src/app/record/custom-editor/libraries/library.component.html +++ b/projects/admin/src/app/record/custom-editor/libraries/library.component.html @@ -14,183 +14,244 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - - -

Library

-
-
- -
- -
-
- Name is required. -
-
- Name must be at least 4 characters long. +
+ +

Library

+ +
+ +
+ +
+
+ Name is required. +
+
+ Name must be at least 4 characters long. +
+
-
-
-
- -
- -
-
- Address must be at least 4 characters long. +
+ +
+ +
+
+ Address must be at least 4 characters long. +
+
-
-
-
- -
- -
-
- Email format is not correct. +
+ +
+ +
+
+ Email format is not correct. +
+
-
-
-
- -
- -
-
- Code is already taken. +
+ +
+ +
+
+ Code is already taken. +
+
Validating…
+
-
Validating…
-
-
- - - - {{ 'Opening Hours' | translate }} - -
-
-
-
-
- - -
-
-
-
    -
  • -
    -
    -
    - -
    -
    - -
    -
    - - -
    -
    -
    -
    - Start time is required. -
    -
    - Start time format is not correct. -
    -
    -
    -
    - End time is required. -
    -
    - End time format is not correct. -
    -
    -
    -
    - End time is less than start time. + + + + {{ 'Opening Hours' | translate }} + +
    +
    +
    +
    +
    + + +
    +
    +
    +
      +
    • +
      +
      +
      + +
      +
      + +
      +
      + + +
      +
      +
      +
      + Start time is required. +
      +
      + Start time format is not correct. +
      +
      +
      +
      + End time is required. +
      +
      + End time format is not correct. +
      +
      +
      +
      + End time is less than start time. +
      +
      +
    • +
    +
    +
    + The two periods are overlapping.
    -
  • -
-
-
- The two periods are overlapping.
+ + + + {{ 'Exceptions (holidays, etc.)' | translate }} + + + + + + {{ 'Notification settings' | translate }} + +
+
+
+ {{ setting.controls.type.value}} +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+
+ + +
+ +
+ +
Sending how many minutes after the item is available
+
+
+
+
+
+
+
+ +
+
+ +
- - - - {{ 'Exceptions (holidays, etc.)' | translate }} - - - - -
-
- - -
-
- - + + +
diff --git a/projects/admin/src/app/record/custom-editor/libraries/library.component.ts b/projects/admin/src/app/record/custom-editor/libraries/library.component.ts index 9072ef129..799abf203 100644 --- a/projects/admin/src/app/record/custom-editor/libraries/library.component.ts +++ b/projects/admin/src/app/record/custom-editor/libraries/library.component.ts @@ -16,7 +16,7 @@ */ import { Location } from '@angular/common'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormArray, FormGroup } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; @@ -25,17 +25,23 @@ import { ToastrService } from 'ngx-toastr'; import { UserService } from '@rero/shared'; import { Library } from '../../../class/library'; import { LibraryFormService } from './library-form.service'; +import { Subscription } from 'rxjs'; @Component({ selector: 'admin-libraries-library', templateUrl: './library.component.html', styleUrls: ['./library.component.scss'] }) -export class LibraryComponent implements OnInit { +export class LibraryComponent implements OnInit, OnDestroy { public library: Library; public libForm: FormGroup; - public organisationPid; + public organisationPid: string; + + /** List of internal notification types */ + internalTypes = ['booking', 'request', 'transit_notice']; + + private eventForm: Subscription; constructor( private recordService: RecordService, @@ -55,22 +61,28 @@ export class LibraryComponent implements OnInit { if (loggedUser) { this.organisationPid = loggedUser.currentOrganisation; } - if (params && params.pid) { - this.recordService.getRecord('libraries', params.pid, 1).subscribe(record => { - this.library = new Library(record.metadata); - this.libraryForm.populate(record.metadata); + this.libraryForm.create(); + this.eventForm = this.libraryForm.getBuildEvent().subscribe((buildEvent: any) => { + if (params && params.pid) { + this.recordService.getRecord('libraries', params.pid, 1).subscribe(record => { + this.library = new Library(record.metadata); + this.libraryForm.populate(record.metadata); + this.libForm = this.libraryForm.form; + this.setAsyncValidator(); + }); + } else { + this.library = new Library({}); this.libForm = this.libraryForm.form; this.setAsyncValidator(); - }); - } else { - this.libraryForm.reset(); - this.library = new Library({}); - this.libForm = this.libraryForm.form; - this.setAsyncValidator(); - } + } + }); }); } + ngOnDestroy() { + this.eventForm.unsubscribe(); + } + setAsyncValidator() { this.libForm.controls.code.setAsyncValidators([ UniqueValidator.createValidator( @@ -87,6 +99,8 @@ export class LibraryComponent implements OnInit { get email() { return this.libraryForm.email; } get code() { return this.libraryForm.code; } get openingHours() { return this.libraryForm.opening_hours as FormArray; } + get notificationSettings() { + return this.libraryForm.notification_settings as FormArray; } onSubmit() { this._cleanFormValues(this.libraryForm.getValues()); @@ -112,7 +126,7 @@ export class LibraryComponent implements OnInit { this.router.navigate(['../detail', record.metadata.pid], {relativeTo: this.route, replaceUrl: true}); }); } - this.libraryForm.reset(); + this.libraryForm.build(); } /** @@ -126,12 +140,13 @@ export class LibraryComponent implements OnInit { day.times = []; } }); + formValues.notification_settings = formValues.notification_settings.filter(element => element.email !== ''); } onCancel(event) { event.preventDefault(); this.location.back(); - this.libraryForm.reset(); + this.libraryForm.build(); } addTime(dayIndex): void { this.libraryForm.addTime(dayIndex); diff --git a/projects/admin/src/app/record/detail-view/library-detail-view/library-detail-view.component.html b/projects/admin/src/app/record/detail-view/library-detail-view/library-detail-view.component.html index 4e5729dab..df3af03b9 100644 --- a/projects/admin/src/app/record/detail-view/library-detail-view/library-detail-view.component.html +++ b/projects/admin/src/app/record/detail-view/library-detail-view/library-detail-view.component.html @@ -89,6 +89,47 @@

{{ record.metadata.name }}

no location

- + + +
+
+ Notification settings +
+
diff --git a/proxy.conf.json b/proxy.conf.json index e2eaefe87..5a22c8816 100644 --- a/proxy.conf.json +++ b/proxy.conf.json @@ -25,6 +25,15 @@ "pathRewrite": { "^/api": "https://localhost:5000/api" } + }, + "/notifications/*": { + "target": "https://localhost:5000", + "secure": false, + "logLevel": "debug", + "changeOrigin": true, + "pathRewrite": { + "^/notifications": "https://localhost:5000/notifications" + } }, "/lang/*": { "target": "https://localhost:5000",