projects/storefrontlib/cms-components/myaccount/consent-management/components/consent-management.component.ts
| selector | cx-consent-management |
| templateUrl | ./consent-management.component.html |
Properties |
|
Methods |
|
constructor(userConsentService: UserConsentService, globalMessageService: GlobalMessageService, anonymousConsentsConfig: AnonymousConsentsConfig, anonymousConsentsService: AnonymousConsentsService, authService: AuthService)
|
||||||||||||||||||
|
Parameters :
|
| allowAll | ||||||||
allowAll(templates: ConsentTemplate[])
|
||||||||
|
Parameters :
Returns :
void
|
| Private consentListInit |
consentListInit()
|
|
Returns :
void
|
| Private consentsExists | ||||||
consentsExists(templateList: ConsentTemplate[])
|
||||||
|
Parameters :
Returns :
boolean
|
| Private giveConsentInit |
giveConsentInit()
|
|
Returns :
void
|
| Private isRequiredConsent | ||||||
isRequiredConsent(template: ConsentTemplate)
|
||||||
|
Parameters :
Returns :
boolean
|
| ngOnDestroy |
ngOnDestroy()
|
|
Returns :
void
|
| ngOnInit |
ngOnInit()
|
|
Returns :
void
|
| onConsentChange | |||||
onConsentChange(undefined: literal type)
|
|||||
|
Parameters :
Returns :
void
|
| Private onConsentGivenSuccess | ||||||
onConsentGivenSuccess(success: boolean)
|
||||||
|
Parameters :
Returns :
void
|
| Private onConsentWithdrawnSuccess | ||||||
onConsentWithdrawnSuccess(success: boolean)
|
||||||
|
Parameters :
Returns :
void
|
| rejectAll | ||||||||
rejectAll(templates: ConsentTemplate[])
|
||||||||
|
Parameters :
Returns :
void
|
| Private setupGiveStream | ||||||||
setupGiveStream(consentsToGive: ConsentTemplate[])
|
||||||||
|
Parameters :
Returns :
Observable<number>
|
| Private setupWithdrawalStream | ||||||||
setupWithdrawalStream(consentsToWithdraw: ConsentTemplate[])
|
||||||||
|
Parameters :
Returns :
Observable<number>
|
| Private withdrawConsentInit |
withdrawConsentInit()
|
|
Returns :
void
|
| Private allConsentsLoading |
Default value : new BehaviorSubject<boolean>(false)
|
| loading$ |
Type : Observable<boolean>
|
| requiredConsents |
Type : string[]
|
Default value : []
|
| Private subscriptions |
Default value : new Subscription()
|
| templateList$ |
Type : Observable<ConsentTemplate[]>
|
import { Component, OnDestroy, OnInit } from '@angular/core';
import {
AnonymousConsentsConfig,
AnonymousConsentsService,
AuthService,
ConsentTemplate,
GlobalMessageService,
GlobalMessageType,
UserConsentService,
} from '@spartacus/core';
import {
BehaviorSubject,
combineLatest,
concat,
Observable,
Subscription,
} from 'rxjs';
import {
distinctUntilChanged,
filter,
map,
scan,
skipWhile,
tap,
withLatestFrom,
} from 'rxjs/operators';
@Component({
selector: 'cx-consent-management',
templateUrl: './consent-management.component.html',
})
export class ConsentManagementComponent implements OnInit, OnDestroy {
private subscriptions = new Subscription();
private allConsentsLoading = new BehaviorSubject<boolean>(false);
templateList$: Observable<ConsentTemplate[]>;
loading$: Observable<boolean>;
requiredConsents: string[] = [];
constructor(
protected userConsentService: UserConsentService,
protected globalMessageService: GlobalMessageService,
protected anonymousConsentsConfig: AnonymousConsentsConfig,
protected anonymousConsentsService: AnonymousConsentsService,
protected authService: AuthService
) {}
ngOnInit(): void {
this.loading$ = combineLatest([
this.userConsentService.getConsentsResultLoading(),
this.userConsentService.getGiveConsentResultLoading(),
this.userConsentService.getWithdrawConsentResultLoading(),
this.authService.isUserLoggedIn(),
this.allConsentsLoading,
]).pipe(
map(
([
consentLoading,
giveConsentLoading,
withdrawConsentLoading,
isUserLoggedIn,
allConsentsLoading,
]) =>
consentLoading ||
giveConsentLoading ||
withdrawConsentLoading ||
!isUserLoggedIn ||
allConsentsLoading
)
);
this.consentListInit();
this.giveConsentInit();
this.withdrawConsentInit();
}
private consentListInit(): void {
this.templateList$ = this.userConsentService.getConsents().pipe(
withLatestFrom(
this.anonymousConsentsService.getTemplates(),
this.authService.isUserLoggedIn()
),
filter(
([_templateList, _anonymousTemplates, isUserLoggedIn]) => isUserLoggedIn
),
tap(([templateList, _anonymousTemplates]) => {
if (!this.consentsExists(templateList)) {
this.userConsentService.loadConsents();
}
}),
map(([templateList, anonymousTemplates]) => {
if (Boolean(this.anonymousConsentsConfig.anonymousConsents)) {
if (
Boolean(
this.anonymousConsentsConfig.anonymousConsents.requiredConsents
)
) {
this.requiredConsents =
this.anonymousConsentsConfig.anonymousConsents.requiredConsents;
}
if (
Boolean(
this.anonymousConsentsConfig.anonymousConsents
.consentManagementPage
)
) {
return this.hideAnonymousConsents(templateList, anonymousTemplates);
}
}
return templateList;
})
);
}
private hideAnonymousConsents(
templateList: ConsentTemplate[],
anonymousTemplates: ConsentTemplate[] = []
): ConsentTemplate[] {
let hideTemplateIds: string[] = [];
if (
!this.anonymousConsentsConfig.anonymousConsents.consentManagementPage
.showAnonymousConsents
) {
hideTemplateIds = anonymousTemplates.map((template) => template.id);
return this.userConsentService.filterConsentTemplates(
templateList,
hideTemplateIds
);
}
if (
Boolean(
this.anonymousConsentsConfig.anonymousConsents.consentManagementPage
.hideConsents
) &&
this.anonymousConsentsConfig.anonymousConsents.consentManagementPage
.hideConsents.length > 0
) {
hideTemplateIds =
this.anonymousConsentsConfig.anonymousConsents.consentManagementPage
.hideConsents;
}
return this.userConsentService.filterConsentTemplates(
templateList,
hideTemplateIds
);
}
private giveConsentInit(): void {
this.userConsentService.resetGiveConsentProcessState();
this.subscriptions.add(
this.userConsentService
.getGiveConsentResultSuccess()
.subscribe((success) => this.onConsentGivenSuccess(success))
);
}
private withdrawConsentInit(): void {
this.userConsentService.resetWithdrawConsentProcessState();
this.subscriptions.add(
this.userConsentService
.getWithdrawConsentResultLoading()
.pipe(
skipWhile(Boolean),
withLatestFrom(
this.userConsentService.getWithdrawConsentResultSuccess()
),
map(([, withdrawalSuccess]) => withdrawalSuccess),
tap((withdrawalSuccess) => {
if (withdrawalSuccess) {
this.userConsentService.loadConsents();
}
})
)
.subscribe((withdrawalSuccess) =>
this.onConsentWithdrawnSuccess(withdrawalSuccess)
)
);
}
private consentsExists(templateList: ConsentTemplate[]): boolean {
return Boolean(templateList) && templateList.length > 0;
}
onConsentChange({
given,
template,
}: {
given: boolean;
template: ConsentTemplate;
}): void {
if (given) {
this.userConsentService.giveConsent(template.id, template.version);
} else {
this.userConsentService.withdrawConsent(template.currentConsent.code);
}
}
private onConsentGivenSuccess(success: boolean): void {
if (success) {
this.userConsentService.resetGiveConsentProcessState();
this.globalMessageService.add(
{ key: 'consentManagementForm.message.success.given' },
GlobalMessageType.MSG_TYPE_CONFIRMATION
);
}
}
private onConsentWithdrawnSuccess(success: boolean): void {
if (success) {
this.userConsentService.resetWithdrawConsentProcessState();
this.globalMessageService.add(
{ key: 'consentManagementForm.message.success.withdrawn' },
GlobalMessageType.MSG_TYPE_CONFIRMATION
);
}
}
rejectAll(templates: ConsentTemplate[] = []): void {
const consentsToWithdraw: ConsentTemplate[] = [];
templates.forEach((template) => {
if (this.userConsentService.isConsentGiven(template.currentConsent)) {
if (this.isRequiredConsent(template)) {
return;
}
consentsToWithdraw.push(template);
}
});
this.allConsentsLoading.next(true);
this.subscriptions.add(
this.setupWithdrawalStream(consentsToWithdraw)
.pipe(tap((_timesLoaded) => this.allConsentsLoading.next(false)))
.subscribe()
);
}
private setupWithdrawalStream(
consentsToWithdraw: ConsentTemplate[] = []
): Observable<number> {
const loading$ = concat(
this.userConsentService.getWithdrawConsentResultLoading()
).pipe(
distinctUntilChanged(),
filter((loading) => !loading)
);
const count$ = loading$.pipe(scan((acc, _value) => acc + 1, -1));
const withdraw$ = count$.pipe(
tap((i) => {
if (i < consentsToWithdraw.length) {
this.userConsentService.withdrawConsent(
consentsToWithdraw[i].currentConsent.code
);
}
})
);
const checkTimesLoaded$ = withdraw$.pipe(
filter((timesLoaded) => timesLoaded === consentsToWithdraw.length)
);
return checkTimesLoaded$;
}
allowAll(templates: ConsentTemplate[] = []): void {
const consentsToGive: ConsentTemplate[] = [];
templates.forEach((template) => {
if (this.userConsentService.isConsentWithdrawn(template.currentConsent)) {
if (this.isRequiredConsent(template)) {
return;
}
}
consentsToGive.push(template);
});
this.allConsentsLoading.next(true);
this.subscriptions.add(
this.setupGiveStream(consentsToGive)
.pipe(tap((_timesLoaded) => this.allConsentsLoading.next(false)))
.subscribe()
);
}
private setupGiveStream(
consentsToGive: ConsentTemplate[] = []
): Observable<number> {
const loading$ = concat(
this.userConsentService.getGiveConsentResultLoading()
).pipe(
distinctUntilChanged(),
filter((loading) => !loading)
);
const count$ = loading$.pipe(scan((acc, _value) => acc + 1, -1));
const giveConsent$ = count$.pipe(
tap((i) => {
if (i < consentsToGive.length) {
this.userConsentService.giveConsent(
consentsToGive[i].id,
consentsToGive[i].version
);
}
})
);
const checkTimesLoaded$ = giveConsent$.pipe(
filter((timesLoaded) => timesLoaded === consentsToGive.length)
);
return checkTimesLoaded$;
}
private isRequiredConsent(template: ConsentTemplate): boolean {
return (
Boolean(this.anonymousConsentsConfig.anonymousConsents) &&
Boolean(
this.anonymousConsentsConfig.anonymousConsents.requiredConsents
) &&
this.anonymousConsentsConfig.anonymousConsents.requiredConsents.includes(
template.id
)
);
}
ngOnDestroy(): void {
this.subscriptions.unsubscribe();
this.allConsentsLoading.unsubscribe();
this.userConsentService.resetGiveConsentProcessState();
this.userConsentService.resetWithdrawConsentProcessState();
}
}
<div *ngIf="loading$ | async; else consentManagementForm">
<div class="cx-spinner">
<cx-spinner></cx-spinner>
</div>
</div>
<ng-template #consentManagementForm>
<ng-container *ngIf="templateList$ | async as templateList">
<div class="cx-consent-action-links">
<div class="col-sm-12 col-md-8 col-lg-6">
<button
tabindex="0"
class="btn btn-link cx-action-link"
(click)="rejectAll(templateList)"
>
{{ 'consentManagementForm.clearAll' | cxTranslate }}
</button>
<button
tabindex="0"
class="btn btn-link cx-action-link"
(click)="allowAll(templateList)"
>
{{ 'consentManagementForm.selectAll' | cxTranslate }}
</button>
</div>
</div>
<div class="cx-consent-toggles">
<div class="col-sm-12 col-md-8 col-lg-6">
<cx-consent-management-form
*ngFor="let consentTemplate of templateList"
[consentTemplate]="consentTemplate"
[requiredConsents]="requiredConsents"
(consentChanged)="onConsentChange($event)"
></cx-consent-management-form>
</div>
</div>
</ng-container>
</ng-template>