File

projects/storefrontlib/shared/components/anonymous-consents-dialog/anonymous-consent-dialog.component.ts

Implements

OnInit OnDestroy

Metadata

selector cx-anonymous-consent-dialog
templateUrl ./anonymous-consent-dialog.component.html

Index

Properties
Methods
HostBindings
HostListeners

Constructor

constructor(config: AnonymousConsentsConfig, anonymousConsentsService: AnonymousConsentsService, el: ElementRef, launchDialogService: LaunchDialogService)
Parameters :
Name Type Optional
config AnonymousConsentsConfig No
anonymousConsentsService AnonymousConsentsService No
el ElementRef No
launchDialogService LaunchDialogService No

HostBindings

attr.aria-modal
Type : boolean
Default value : true
attr.role
Type : string
Default value : 'dialog'

HostListeners

click
Arguments : '$event'
click(event: UIEvent)

Methods

allowAll
allowAll()
Returns : void
close
close(reason?: any)
Parameters :
Name Type Optional
reason any Yes
Returns : void
getCorrespondingConsent
getCorrespondingConsent(template: ConsentTemplate, consents: AnonymousConsent[])
Parameters :
Name Type Optional Default value
template ConsentTemplate No
consents AnonymousConsent[] No []
Returns : AnonymousConsent
handleClick
handleClick(event: UIEvent)
Decorators :
@HostListener('click', ['$event'])
Parameters :
Name Type Optional
event UIEvent No
Returns : void
Private isRequiredConsent
isRequiredConsent(template: ConsentTemplate)
Parameters :
Name Type Optional
template ConsentTemplate No
Returns : boolean
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onConsentChange
onConsentChange(undefined: literal type)
Parameters :
Name Type Optional
literal type No
Returns : void
rejectAll
rejectAll()
Returns : void

Properties

consents$
Type : Observable<AnonymousConsent[]>
focusConfig
Type : FocusConfig
Default value : { trap: true, block: true, autofocus: 'input[type="checkbox"]', focusOnEscape: true, }
iconTypes
Default value : ICON_TYPE
loading$
Type : Observable<boolean>
modal
Default value : true
Decorators :
@HostBinding('attr.aria-modal')
requiredConsents
Type : string[]
Default value : []
role
Type : string
Default value : 'dialog'
Decorators :
@HostBinding('attr.role')
showLegalDescription
Default value : true
Private subscriptions
Default value : new Subscription()
templates$
Type : Observable<ConsentTemplate[]>
import {
  Component,
  ElementRef,
  HostBinding,
  HostListener,
  OnDestroy,
  OnInit,
} from '@angular/core';
import {
  AnonymousConsent,
  AnonymousConsentsConfig,
  AnonymousConsentsService,
  ConsentTemplate,
} from '@spartacus/core';
import { combineLatest, Observable, Subscription } from 'rxjs';
import { distinctUntilChanged, take, tap } from 'rxjs/operators';
import { ICON_TYPE } from '../../../cms-components/misc/icon/index';
import { FocusConfig } from '../../../layout/a11y/keyboard-focus/index';
import { LaunchDialogService } from '../../../layout/launch-dialog/services/launch-dialog.service';

@Component({
  selector: 'cx-anonymous-consent-dialog',
  templateUrl: './anonymous-consent-dialog.component.html',
})
export class AnonymousConsentDialogComponent implements OnInit, OnDestroy {
  @HostBinding('attr.role') role = 'dialog';
  @HostBinding('attr.aria-modal') modal = true;

  private subscriptions = new Subscription();

  showLegalDescription = true;
  iconTypes = ICON_TYPE;
  requiredConsents: string[] = [];

  loading$: Observable<boolean>;
  templates$: Observable<ConsentTemplate[]>;
  consents$: Observable<AnonymousConsent[]>;

  focusConfig: FocusConfig = {
    trap: true,
    block: true,
    autofocus: 'input[type="checkbox"]',
    focusOnEscape: true,
  };

  @HostListener('click', ['$event'])
  handleClick(event: UIEvent): void {
    // Close on click outside the dialog window
    if ((event.target as any).tagName === this.el.nativeElement.tagName) {
      this.close('Cross click');
    }
  }

  constructor(
    protected config: AnonymousConsentsConfig,
    protected anonymousConsentsService: AnonymousConsentsService,
    protected el: ElementRef,
    protected launchDialogService: LaunchDialogService
  ) {
    if (Boolean(this.config.anonymousConsents)) {
      this.showLegalDescription =
        this.config.anonymousConsents.showLegalDescriptionInDialog;
      if (Boolean(this.config.anonymousConsents.requiredConsents)) {
        this.requiredConsents = this.config.anonymousConsents.requiredConsents;
      }
    }
  }

  ngOnInit(): void {
    this.templates$ = this.anonymousConsentsService.getTemplates();
    this.consents$ = this.anonymousConsentsService.getConsents();
    this.loading$ = this.anonymousConsentsService.getLoadTemplatesLoading();
  }

  close(reason?: any): void {
    this.launchDialogService.closeDialog(reason);
  }

  rejectAll(): void {
    this.subscriptions.add(
      combineLatest([this.templates$, this.consents$])
        .pipe(
          take(1),
          distinctUntilChanged(),
          tap(([templates, consents]) =>
            templates.forEach((template) => {
              const consent = this.getCorrespondingConsent(template, consents);
              if (this.anonymousConsentsService.isConsentGiven(consent)) {
                if (this.isRequiredConsent(template)) {
                  return;
                }

                this.anonymousConsentsService.withdrawConsent(template.id);
              }
            })
          )
        )
        .subscribe()
    );
    this.close('rejectAll');
  }

  allowAll(): void {
    this.subscriptions.add(
      combineLatest([this.templates$, this.consents$])
        .pipe(
          take(1),
          distinctUntilChanged(),
          tap(([templates, consents]) =>
            templates.forEach((template) => {
              const consent = this.getCorrespondingConsent(template, consents);
              if (
                (consent && consent.consentState == null) ||
                this.anonymousConsentsService.isConsentWithdrawn(consent)
              ) {
                if (this.isRequiredConsent(template)) {
                  return;
                }

                this.anonymousConsentsService.giveConsent(template.id);
              }
            })
          )
        )
        .subscribe()
    );
    this.close('allowAll');
  }

  private isRequiredConsent(template: ConsentTemplate): boolean {
    return (
      Boolean(this.config.anonymousConsents) &&
      Boolean(this.config.anonymousConsents.requiredConsents) &&
      this.config.anonymousConsents.requiredConsents.includes(template.id)
    );
  }

  onConsentChange({
    given,
    template,
  }: {
    given: boolean;
    template: ConsentTemplate;
  }): void {
    if (given) {
      this.anonymousConsentsService.giveConsent(template.id);
    } else {
      this.anonymousConsentsService.withdrawConsent(template.id);
    }
  }

  getCorrespondingConsent(
    template: ConsentTemplate,
    consents: AnonymousConsent[] = []
  ): AnonymousConsent {
    for (const consent of consents) {
      if (template.id === consent.templateCode) {
        return consent;
      }
    }
    return null;
  }

  ngOnDestroy(): void {
    this.subscriptions.unsubscribe();
  }
}
<div
  class="cx-anonymous-consent-dialog"
  [cxFocus]="focusConfig"
  (esc)="close('Escape clicked')"
>
  <div class="cx-dialog-content">
    <div *ngIf="loading$ | async; else dialogBody">
      <cx-spinner></cx-spinner>
    </div>
    <ng-template #dialogBody>
      <div class="cx-dialog-header">
        <h3>
          {{ 'anonymousConsents.dialog.title' | cxTranslate }}
        </h3>
        <button
          type="button"
          class="close"
          [attr.aria-label]="'common.close' | cxTranslate"
          (click)="close('Cross click')"
        >
          <span aria-hidden="true">
            <cx-icon [type]="iconTypes.CLOSE"></cx-icon>
          </span>
        </button>
      </div>
      <!-- Separator -->
      <div class="cx-dialog-description" *ngIf="showLegalDescription">
        {{ 'anonymousConsents.dialog.legalDescription' | cxTranslate }}
        <div
          class="cx-dialog-separator col-sm-12 d-xs-block d-sm-block d-md-none"
        ></div>
      </div>
      <!-- Actions -->
      <div class="cx-dialog-buttons">
        <a tabindex="0" class="btn-link cx-action-link" (click)="rejectAll()">{{
          'anonymousConsents.dialog.clearAll' | cxTranslate
        }}</a>
        <a tabindex="0" class="btn-link cx-action-link" (click)="allowAll()">{{
          'anonymousConsents.dialog.selectAll' | cxTranslate
        }}</a>
      </div>
      <!-- Modal Body -->
      <div class="cx-dialog-body" *ngIf="templates$ | async as templates">
        <ng-container *ngIf="consents$ | async as consents">
          <div
            class="cx-dialog-row col-sm-12 col-md-6"
            *ngFor="let template of templates"
          >
            <cx-consent-management-form
              [consentTemplate]="template"
              [requiredConsents]="requiredConsents"
              [consent]="getCorrespondingConsent(template, consents)"
              (consentChanged)="onConsentChange($event)"
            ></cx-consent-management-form>
          </div>
        </ng-container>
      </div>
    </ng-template>
  </div>
</div>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""