diff --git a/sharedComponents/input/input.component.ts b/sharedComponents/input/input.component.ts index 97817e8c..edf1a021 100644 --- a/sharedComponents/input/input.component.ts +++ b/sharedComponents/input/input.component.ts @@ -11,7 +11,7 @@ import { SimpleChanges, ViewChild } from "@angular/core"; -import {AbstractControl, FormArray, FormControl} from "@angular/forms"; +import {AbstractControl, FormArray, FormControl, ValidatorFn} from "@angular/forms"; import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {Observable, of, Subscription} from "rxjs"; import {MatSelect} from "@angular/material/select"; @@ -100,7 +100,7 @@ export interface Option {
-
{{placeholder}}
@@ -119,7 +119,7 @@ export interface Option {
+ [class.uk-form-danger]="formControl.invalid && searchControl.invalid && searchControl.touched" (click)="openSelect()">
- @@ -181,7 +181,7 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges { /** Textarea options */ @Input('rows') rows: number = 3; /** Select | chips available options */ - @Input('options') options: Option[]; + @Input('options') options: Option[] = []; @Input('hint') hint = null; @Input('placeholder') placeholder = ''; @Input() inputClass: string = 'input-box'; @@ -200,6 +200,7 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges { @Input() panelWidth: number = 300; @Input() panelClass: string = null; @Input() showOptionsOnEmpty: boolean = true; + @Input() validators: ValidatorFn[]; @Output() focusEmitter: EventEmitter = new EventEmitter(); /** LogoUrl information */ public secure: boolean = true; @@ -248,11 +249,9 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges { this.secure = (!this.initValue || this.initValue.includes('https://')); } if (this.type === 'chips' || this.type === 'autocomplete') { - if(!this.options) { - console.error('Please provide options to continue'); - } else { + if(this.options) { this.filteredOptions = of(this.options); - this.searchControl = new FormControl(''); + this.searchControl = new FormControl('', this.validators); this.subscriptions.push(this.searchControl.valueChanges.subscribe(value => { setTimeout(() => { this.searchInput.nativeElement.focus(); @@ -333,9 +332,9 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges { } add(event: MatChipInputEvent) { - if (this.addExtraChips && event.value) { + if (this.addExtraChips && event.value && this.searchControl.valid) { this.stopPropagation(); - this.formAsArray.push(new FormControl(event.value)); + this.formAsArray.push(new FormControl(event.value, this.validators)); this.formAsArray.markAsDirty(); this.searchControl.setValue(''); this.searchInput.nativeElement.value = ''; diff --git a/sharedComponents/subscriber-invite/subscriber-invite.component.ts b/sharedComponents/subscriber-invite/subscriber-invite.component.ts index 8ce76b9f..f3c03189 100644 --- a/sharedComponents/subscriber-invite/subscriber-invite.component.ts +++ b/sharedComponents/subscriber-invite/subscriber-invite.component.ts @@ -1,5 +1,5 @@ import {Component, Input, OnDestroy, OnInit} from "@angular/core"; -import {AbstractControl, FormBuilder, FormGroup, ValidationErrors, Validators} from "@angular/forms"; +import {AbstractControl, FormBuilder, FormGroup, ValidationErrors, ValidatorFn, Validators} from "@angular/forms"; import {Subscriber} from "rxjs"; import {StringUtils} from "../../utils/string-utils.class"; import {Email} from "../../utils/email/email"; @@ -16,17 +16,16 @@ declare var UIkit; @Component({ selector: 'subscriber-invite', template: ` -
+
From:
-
-
+
+
To *:
- Separate multiple emails with a comma
@@ -34,7 +33,7 @@ declare var UIkit;
@@ -52,17 +51,23 @@ declare var UIkit;
+
+
+
`, styleUrls: ['subscriber-invite.component.css'] }) export class SubscriberInviteComponent implements OnInit, OnDestroy { @Input() public user: User; - public community: CommunityInfo + @Input() + public longView: boolean = true; + public community: CommunityInfo; public inviteForm: FormGroup; public email: Email; public body: Body; - public loading: boolean = false; + public validators: ValidatorFn[] = [Validators.email, Validators.required]; + public loading: boolean = true; private subscriptions: any[] = []; constructor(private fb: FormBuilder, @@ -71,6 +76,7 @@ export class SubscriberInviteComponent implements OnInit, OnDestroy { } ngOnInit() { + this.loading = this.longView; this.reset(); } @@ -90,7 +96,7 @@ export class SubscriberInviteComponent implements OnInit, OnDestroy { this.unsubscribe(); this.inviteForm = this.fb.group({ name: this.fb.control('', Validators.required), - recipients: this.fb.control('', [Validators.required, this.emailsValidator]), + recipients: this.fb.array([], Validators.required), message: this.fb.control('', Validators.required) }); this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(community => { @@ -102,20 +108,16 @@ export class SubscriberInviteComponent implements OnInit, OnDestroy { this.email = Composer.initializeInvitationsEmail(community.title); this.inviteForm.get('message').setValue(this.body.paragraphs); })); - } - - emailsValidator(control: AbstractControl): ValidationErrors | null { - if (control.value === '' || !control.value || StringUtils.validateEmails(control.value)) { - return null; + if(!this.isManager) { + this.loading = false; } - return { emails: true }; } invite() { this.loading = true; - this.parseRecipients(); this.body.paragraphs = this.inviteForm.value.message; this.email.body = Composer.formatEmailBodyForInvitation(this.body); + this.email.recipients = this.inviteForm.get('recipients').value; this.subscriptions.push(this.emailService.sendEmail(properties, this.email).subscribe(res => { if(res['success']) { UIkit.notification('Invitation to subscribe has been sent', { @@ -130,6 +132,7 @@ export class SubscriberInviteComponent implements OnInit, OnDestroy { pos: 'bottom-right' }); } + this.reset(); this.loading = false; },error => { UIkit.notification('An error has occurred. Please try again later', { @@ -137,29 +140,16 @@ export class SubscriberInviteComponent implements OnInit, OnDestroy { timeout: 6000, pos: 'bottom-right' }); + this.reset(); this.loading = false; })); } - public parseRecipients() { - // remove spaces - let emails = this.inviteForm.get('recipients').value.replace(/\s/g, ''); - // remove commas - emails = emails.split(","); - - // remove empty fields - for (let i = 0; i < emails.length; i++) { - if (!(emails[i] == "")) { - this.email.recipients.push(emails[i]); - } - } - } - get isManager() { return Session.isPortalAdministrator(this.user) || Session.isCurator('community', this.user) || Session.isManager('community', this.community.communityId, this.user); } get valid() { - return this.inviteForm && this.inviteForm.valid; + return !this.loading && this.inviteForm && this.inviteForm.valid; } } diff --git a/utils/configuration/configuration.service.ts b/utils/configuration/configuration.service.ts index 74d34033..be482b53 100644 --- a/utils/configuration/configuration.service.ts +++ b/utils/configuration/configuration.service.ts @@ -118,18 +118,12 @@ export class ConfigurationService{ filtering(page_route: string) { let community: Portal = this.communityInformation.getValue(); - let pages: Page[] = community.pages; - pages = pages.filter(function (page: Page) { - return page.route == page_route; - }); - if (pages) { - let result = false; - if (pages['length'] > 0 && pages[0].route == page_route) { - result = pages[0].isEnabled; - } - return result; + let page = pages.find((page: Page) => page.route == page_route); + return page && page.isEnabled; + } else { + return false; } } diff --git a/utils/icons/icons.ts b/utils/icons/icons.ts index 3daa31c7..eac2923a 100644 --- a/utils/icons/icons.ts +++ b/utils/icons/icons.ts @@ -138,3 +138,8 @@ export const reset = { name: 'reset', data: '' } + +export const send = { + name: 'send', + data: '' +} diff --git a/utils/smooth-scroll.ts b/utils/smooth-scroll.ts index b44efade..67a1b542 100644 --- a/utils/smooth-scroll.ts +++ b/utils/smooth-scroll.ts @@ -11,46 +11,48 @@ export class SmoothScroll { private lastRoute; constructor(private router: Router) { - this.sub = router.events.subscribe(event => { - if (event instanceof NavigationEnd) { - if (this.interval) { - clearInterval(this.interval); - } - const fragment = router.parseUrl(router.url).fragment; - if (this.lastRoute !== this.getUrl(event.url)) { - window.scrollTo({top: 0}); - } - if (fragment) { - let i = 0; - this.interval = setInterval(() => { - i++; - const element = document.getElementById(fragment); - if (element) { - if (this.interval) { + if(typeof window !== "undefined") { + this.sub = router.events.subscribe(event => { + if (event instanceof NavigationEnd) { + if (this.interval) { + clearInterval(this.interval); + } + const fragment = router.parseUrl(router.url).fragment; + if (this.lastRoute !== this.getUrl(event.url)) { + window.scrollTo({top: 0}); + } + if (fragment) { + let i = 0; + this.interval = setInterval(() => { + i++; + const element = document.getElementById(fragment); + if (element) { + if (this.interval) { + clearInterval(this.interval); + } + const yOffset = -100; + let position = 0; + let interval = setInterval(() => { + if (position !== element.getBoundingClientRect().top) { + position = element.getBoundingClientRect().top; + } else { + clearInterval(interval); + const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset; + window.scrollTo({top: y, behavior: 'smooth'}); + } + }, 50); + } + if (i > 4 && this.interval) { clearInterval(this.interval); } - const yOffset = -100; - let position = 0; - let interval = setInterval(() => { - if (position !== element.getBoundingClientRect().top) { - position = element.getBoundingClientRect().top; - } else { - clearInterval(interval); - const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset; - window.scrollTo({top: y, behavior: 'smooth'}); - } - }, 50); - } - if (i > 4 && this.interval) { - clearInterval(this.interval); - } - }, 100); - } else { - window.scrollTo({top: 0, behavior: 'smooth'}); + }, 100); + } else { + window.scrollTo({top: 0, behavior: 'smooth'}); + } + this.lastRoute = this.getUrl(event.url); } - this.lastRoute = this.getUrl(event.url); - } - }); + }); + } } private getUrl(url: string) {