Skip to content

Commit

Permalink
fix: move anonymous consent notification inside dialog (#19735)
Browse files Browse the repository at this point in the history
  • Loading branch information
sdrozdsap authored Dec 16, 2024
1 parent ac00986 commit f94d257
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ export interface FeatureTogglesInterface {
*/
a11yCartImportConfirmationMessage?: boolean;

/**
* In `AnonymousConsentDialogComponent` display notifications inside the modal without closing it
*/
a11yAnonymousConsentMessageInDialog?: boolean;

/**
* Changes 'order days' check list into a fieldset inside of 'CheckoutScheduleReplenishmentOrderComponent'.
*/
Expand Down Expand Up @@ -746,6 +751,15 @@ export interface FeatureTogglesInterface {
*/
a11ySearchboxAssistiveMessage?: boolean;

/**
* Updates the derivative `consentGiven` state when `consent` is updated.
*
* Components affected:
* - `ConsentManagementFormComponent`
* - `MyAccountV2ConsentManagementFormComponent`
*/
updateConsentGivenInOnChanges?: boolean;

/**
* Adds additional styling to help differentiate between focused and selected items in the list.
* Affects: ConfiguratorAttributeSingleSelectionImageComponent, ProductImagesComponent
Expand Down Expand Up @@ -944,6 +958,7 @@ export const defaultFeatureToggles: Required<FeatureTogglesInterface> = {
a11yOrganizationsBanner: true,
a11yOrganizationListHeadingOrder: true,
a11yCartImportConfirmationMessage: false,
a11yAnonymousConsentMessageInDialog: false,
a11yReplenishmentOrderFieldset: true,
a11yListOversizedFocus: true,
a11yStoreFinderOverflow: true,
Expand Down Expand Up @@ -1024,6 +1039,7 @@ export const defaultFeatureToggles: Required<FeatureTogglesInterface> = {
a11yTextSpacingAdjustments: false,
a11yTableHeaderReadout: false,
a11ySearchboxAssistiveMessage: false,
updateConsentGivenInOnChanges: false,
a11yDifferentiateFocusedAndSelected: false,
a11yKeyboardFocusInSearchBox: false,
a11yAddPaddingToCarouselPanel: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ if (environment.cpq) {
a11yOrganizationsBanner: true,
a11yOrganizationListHeadingOrder: true,
a11yCartImportConfirmationMessage: true,
a11yAnonymousConsentMessageInDialog: true,
a11yReplenishmentOrderFieldset: true,
a11yListOversizedFocus: true,
a11yStoreFinderOverflow: true,
Expand Down Expand Up @@ -408,6 +409,7 @@ if (environment.cpq) {
a11yTextSpacingAdjustments: true,
a11yTableHeaderReadout: true,
a11ySearchboxAssistiveMessage: true,
updateConsentGivenInOnChanges: true,
a11yDifferentiateFocusedAndSelected: true,
a11yKeyboardFocusInSearchBox: true,
a11yAddPaddingToCarouselPanel: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ import { By } from '@angular/platform-browser';
import {
ANONYMOUS_CONSENT_STATUS,
ConsentTemplate,
FeatureConfigService,
I18nTestingModule,
} from '@spartacus/core';
import { ConsentManagementFormComponent } from './consent-management-form.component';
import { MockFeatureDirective } from 'projects/storefrontlib/shared/test/mock-feature-directive';

class MockFeatureConfigService {
isEnabled(): boolean {
return true;
}
}

describe('ConsentManagementFormComponent', () => {
let component: ConsentManagementFormComponent;
let fixture: ComponentFixture<ConsentManagementFormComponent>;
Expand All @@ -18,6 +25,9 @@ describe('ConsentManagementFormComponent', () => {
TestBed.configureTestingModule({
imports: [I18nTestingModule],
declarations: [ConsentManagementFormComponent, MockFeatureDirective],
providers: [
{ provide: FeatureConfigService, useClass: MockFeatureConfigService },
],
}).compileComponents();
}));

Expand Down Expand Up @@ -120,7 +130,6 @@ describe('ConsentManagementFormComponent', () => {

component.consentTemplate = mockConsentTemplate;
component.consentGiven = true;
component.ngOnInit();
fixture.detectChanges();

const checkbox = el.query(By.css('input')).nativeElement as HTMLElement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,28 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import {
Component,
EventEmitter,
inject,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
} from '@angular/core';
import {
AnonymousConsent,
ANONYMOUS_CONSENT_STATUS,
ConsentTemplate,
FeatureConfigService,
} from '@spartacus/core';

@Component({
selector: 'cx-consent-management-form',
templateUrl: './consent-management-form.component.html',
})
export class ConsentManagementFormComponent implements OnInit {
export class ConsentManagementFormComponent implements OnInit, OnChanges {
consentGiven = false;

@Input()
Expand All @@ -35,23 +45,24 @@ export class ConsentManagementFormComponent implements OnInit {
template: ConsentTemplate;
}>();

private featureConfigService = inject(FeatureConfigService, {
optional: true,
});

constructor() {
// Intentional empty constructor
}

ngOnInit(): void {
if (this.consent) {
this.consentGiven = Boolean(
this.consent.consentState === ANONYMOUS_CONSENT_STATUS.GIVEN
);
} else {
if (this.consentTemplate && this.consentTemplate.currentConsent) {
if (this.consentTemplate.currentConsent.consentWithdrawnDate) {
this.consentGiven = false;
} else if (this.consentTemplate.currentConsent.consentGivenDate) {
this.consentGiven = true;
}
}
this.updateConsentGiven();
}

ngOnChanges(changes: SimpleChanges): void {
if (
this.featureConfigService?.isEnabled('updateConsentGivenInOnChanges') &&
(changes.consent || changes.consentTemplate)
) {
this.updateConsentGiven();
}
}

Expand All @@ -67,4 +78,20 @@ export class ConsentManagementFormComponent implements OnInit {
isRequired(templateId: string | undefined): boolean {
return templateId ? this.requiredConsents.includes(templateId) : false;
}

protected updateConsentGiven(): void {
if (this.consent) {
this.consentGiven = Boolean(
this.consent.consentState === ANONYMOUS_CONSENT_STATUS.GIVEN
);
} else {
if (this.consentTemplate && this.consentTemplate.currentConsent) {
if (this.consentTemplate.currentConsent.consentWithdrawnDate) {
this.consentGiven = false;
} else if (this.consentTemplate.currentConsent.consentGivenDate) {
this.consentGiven = true;
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ import { By } from '@angular/platform-browser';
import {
ANONYMOUS_CONSENT_STATUS,
ConsentTemplate,
FeatureConfigService,
I18nTestingModule,
} from '@spartacus/core';
import { MyAccountV2ConsentManagementFormComponent } from './my-account-v2-consent-management-form.component';

class MockFeatureConfigService {
isEnabled(): boolean {
return true;
}
}

describe('MyAccountV2ConsentManagementFormComponent', () => {
let component: MyAccountV2ConsentManagementFormComponent;
let fixture: ComponentFixture<MyAccountV2ConsentManagementFormComponent>;
Expand All @@ -17,6 +24,12 @@ describe('MyAccountV2ConsentManagementFormComponent', () => {
TestBed.configureTestingModule({
imports: [I18nTestingModule],
declarations: [MyAccountV2ConsentManagementFormComponent],
providers: [
{
provide: FeatureConfigService,
useClass: MockFeatureConfigService,
},
],
}).compileComponents();
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ <h3 id="dialogTitle">
class="cx-dialog-separator col-sm-12 d-xs-block d-sm-block d-md-none"
></div>
</div>

<ng-container *cxFeature="'a11yAnonymousConsentMessageInDialog'">
<div class="cx-dialog-message" aria-live="assertive" aria-atomic="true">
<cx-message
*ngIf="message$ | async as message"
[text]="message.key | cxTranslate"
[type]="message.type"
[isVisibleCloseButton]="true"
(closeMessage)="closeMessage()"
[cxFocus]="{ autofocus: '.cx-message' }"
></cx-message>
</div>
</ng-container>
<!-- Actions -->
<div class="cx-dialog-buttons">
<ng-container *cxFeature="'a11yUseButtonsForBtnLinks'">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,14 @@ describe('AnonymousConsentsDialogComponent', () => {
});
});

describe('closeMessage', () => {
it('should reset message$ subject', () => {
spyOn(component.message$, 'next').and.stub();
component.closeMessage();
expect(component.message$.next).toHaveBeenCalledWith(null);
});
});

describe('ngOnDestroy', () => {
it('should call unsubscribe', () => {
spyOn<any>(component['subscriptions'], 'unsubscribe').and.stub();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
GlobalMessageType,
useFeatureStyles,
} from '@spartacus/core';
import { combineLatest, Observable, Subscription } from 'rxjs';
import { combineLatest, Observable, Subject, 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';
Expand Down Expand Up @@ -59,6 +59,8 @@ export class AnonymousConsentDialogComponent implements OnInit, OnDestroy {
@Optional() globalMessageService = inject(GlobalMessageService, {
optional: true,
});
globalMessageType = GlobalMessageType;
message$ = new Subject<{ type: GlobalMessageType; key: string } | null>();

@HostListener('click', ['$event'])
handleClick(event: UIEvent): void {
Expand All @@ -83,6 +85,7 @@ export class AnonymousConsentDialogComponent implements OnInit, OnDestroy {
}
useFeatureStyles('a11yUseButtonsForBtnLinks');
useFeatureStyles('a11yExpandedFocusIndicator');
useFeatureStyles('a11yAnonymousConsentMessageInDialog');
}

ngOnInit(): void {
Expand Down Expand Up @@ -121,7 +124,13 @@ export class AnonymousConsentDialogComponent implements OnInit, OnDestroy {
)
.subscribe(() => this.onConsentWithdrawnSuccess())
);
this.close('rejectAll');
if (
!this.featureConfigService.isEnabled(
'a11yAnonymousConsentMessageInDialog'
)
) {
this.close('rejectAll');
}
}

allowAll(): void {
Expand Down Expand Up @@ -151,7 +160,13 @@ export class AnonymousConsentDialogComponent implements OnInit, OnDestroy {
)
.subscribe(() => this.onConsentGivenSuccess())
);
this.close('allowAll');
if (
!this.featureConfigService.isEnabled(
'a11yAnonymousConsentMessageInDialog'
)
) {
this.close('allowAll');
}
}

private isRequiredConsent(template: ConsentTemplate): boolean {
Expand Down Expand Up @@ -194,6 +209,13 @@ export class AnonymousConsentDialogComponent implements OnInit, OnDestroy {

protected onConsentGivenSuccess(): void {
if (
this.featureConfigService.isEnabled('a11yAnonymousConsentMessageInDialog')
) {
this.message$.next({
type: GlobalMessageType.MSG_TYPE_CONFIRMATION,
key: 'consentManagementForm.message.success.given',
});
} else if (
this.featureConfigService.isEnabled('a11yNotificationsOnConsentChange')
) {
this.globalMessageService?.add(
Expand All @@ -205,6 +227,13 @@ export class AnonymousConsentDialogComponent implements OnInit, OnDestroy {

protected onConsentWithdrawnSuccess(): void {
if (
this.featureConfigService.isEnabled('a11yAnonymousConsentMessageInDialog')
) {
this.message$.next({
type: GlobalMessageType.MSG_TYPE_CONFIRMATION,
key: 'consentManagementForm.message.success.withdrawn',
});
} else if (
this.featureConfigService.isEnabled('a11yNotificationsOnConsentChange')
) {
this.globalMessageService?.add(
Expand All @@ -214,6 +243,10 @@ export class AnonymousConsentDialogComponent implements OnInit, OnDestroy {
}
}

closeMessage(): void {
this.message$.next(null);
}

ngOnDestroy(): void {
this.subscriptions.unsubscribe();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { NgModule } from '@angular/core';
import { FeaturesConfigModule, I18nModule } from '@spartacus/core';
import { IconModule } from '../../../cms-components/misc/icon/icon.module';
import { ConsentManagementModule } from '../../../cms-components/myaccount/consent-management/consent-management.module';
import { MessageComponentModule } from '../../../cms-components/misc/message';
import { KeyboardFocusModule } from '../../../layout/a11y/keyboard-focus/index';
import { SpinnerModule } from '../spinner/spinner.module';
import { AnonymousConsentDialogComponent } from './anonymous-consent-dialog.component';
Expand All @@ -22,6 +23,7 @@ import { AnonymousConsentDialogComponent } from './anonymous-consent-dialog.comp
ConsentManagementModule,
KeyboardFocusModule,
FeaturesConfigModule,
MessageComponentModule,
],
declarations: [AnonymousConsentDialogComponent],
exports: [AnonymousConsentDialogComponent],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@
}
}

@include forFeature('a11yAnonymousConsentMessageInDialog') {
.cx-dialog-message {
padding: 1.5rem 1.75rem 0;

.cx-message {
margin: 0;
}
}
}

.cx-action-link {
margin: 0 0.35rem;

Expand Down

0 comments on commit f94d257

Please sign in to comment.