Skip to content

Commit

Permalink
feat: introduce account navigation grouping - used in b2b theme (#1331)
Browse files Browse the repository at this point in the history
* account navigation was reworked to support navigation grouping (used in `b2b` theme)
* externalized navigation items in overwritable .ts file
* simplified NavigationItems structure
* migration documentation
* fix: styling fix for list items

BREAKING CHANGES:
Changed NavigationItem data structure and handling (see [Migrations / 3.3 to 4.0](https://github.com/intershop/intershop-pwa/blob/develop/docs/guides/migrations.md#33-to-40) for more details).
---------

Co-authored-by: Stefan Hauke <s.hauke@intershop.de>
Co-authored-by: Silke <s.grueber@intershop.de>
  • Loading branch information
3 people authored Feb 23, 2023
1 parent 1f87684 commit 3334e77
Show file tree
Hide file tree
Showing 17 changed files with 376 additions and 206 deletions.
6 changes: 6 additions & 0 deletions docs/guides/migrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ kb_sync_latest_only

## 3.3 to 4.0

The account navigation was reworked to support navigation grouping (used in `b2b` theme, see [`account-navigation.items.ts`](https://github.com/intershop/intershop-pwa/blob/4.0.0/src/app/pages/account/account-navigation/account-navigation.items.ts)).
For better maintainability and brand specific overriding the account navigation items were externalized in an extra file `account-navigation.items.ts` used by the `account-navigation.component.ts`.
Also with this rework the navigation items data structure was changed from a key value object to a simpler `NavigationItem` Array.
With this data structure accessing the data was changed for the key access from `item.key` to `item.routerLink` or for the value example from `item.value.localizationKey` to `item.localizationKey`.
To migrate to this new account navigation item handling any account navigation customization needs to be adapted accordingly.

The deprecated SSR environment variable `ICM_IDENTITY_PROVIDER` was completely removed.
Use the variable `IDENTITY_PROVIDER` instead to select the identity provider to be used if it is not the default `ICM`.
Removed default `identityProvider` configuration from `environment.model.ts` so only hardcoded fallback from `configuration.effects.ts` works as fallback.
Expand Down
10 changes: 5 additions & 5 deletions e2e/cypress/e2e/pages/account/my-account.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class MyAccountPage {
}

navigateToQuoting() {
cy.get('a[data-testing-id="quote-list-link"]').click();
cy.get('a[data-testing-id="quotes-nav-link"]').click();
}

get respondedQuotesCount() {
Expand All @@ -22,18 +22,18 @@ export class MyAccountPage {
}

navigateToAddresses() {
cy.get('a[data-testing-id="addresses-link"]').click();
cy.get('a[data-testing-id="addresses-nav-link"]').click();
}

navigateToWishlists() {
cy.get('a[data-testing-id="wishlists-link"]').click();
cy.get('a[data-testing-id="wishlists-nav-link"]').click();
}

navigateToOrderTemplates() {
cy.get('a[data-testing-id="order-templates-link"]').click();
cy.get('a[data-testing-id="order-templates-nav-link"]').click();
}

navigateToPayments() {
cy.get('a[data-testing-id="payments-link"]').click();
cy.get('a[data-testing-id="payment-nav-link"]').click();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class OrderTemplatesDetailsPage {
readonly breadcrumb = new BreadcrumbModule();

static navigateToOverviewPage() {
cy.get('a[data-testing-id="order-templates-link"]').click();
cy.get('a[data-testing-id="order-templates-nav-link"]').click();
}

get listItem() {
Expand Down
24 changes: 15 additions & 9 deletions src/app/core/icon.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
faBalanceScale,
faBan,
faBars,
faBriefcase,
faCalendarDay,
faCheck,
faCheckCircle,
Expand All @@ -20,6 +21,7 @@ import {
faEnvelope,
faFastForward,
faFax,
faGear,
faGlobeAmericas,
faHeart,
faHome,
Expand All @@ -36,6 +38,7 @@ import {
faPlus,
faPrint,
faQuestionCircle,
faRightFromBracket,
faSearch,
faShoppingCart,
faSpinner,
Expand Down Expand Up @@ -63,22 +66,29 @@ export class IconModule {
faAngleLeft,
faAngleRight,
faAngleUp,
faArrowsAlt,
faArrowAltCircleRight,
faArrowsAlt,
faBalanceScale,
faBan,
faBars,
faBriefcase,
faCalendarDay,
faCheck,
faCheckCircle,
faCog,
faCogs,
faEnvelope,
faFastForward,
faFax,
faGear,
faGlobeAmericas,
faHeart,
faHome,
faInbox,
faInfoCircle,
faList,
faListAlt,
faMapMarkerAlt,
faMinus,
faPaperPlane,
faPencilAlt,
Expand All @@ -87,23 +97,19 @@ export class IconModule {
faPlus,
faPrint,
faQuestionCircle,
faRightFromBracket,
faSearch,
faShoppingCart,
faSpinner,
faStar,
faStarHalf,
faTh,
faTimes,
faTimesCircle,
faTrashAlt,
faUndo,
faUser,
faUserCheck,
faStar,
faStarHalf,
faHeart,
faFastForward,
faMapMarkerAlt,
faEnvelope,
faFax
faUserCheck
);
}
}
Original file line number Diff line number Diff line change
@@ -1,56 +1,108 @@
<ng-container *ngIf="!isMobileView; else mobileNavigation">
<ul class="account-navigation list-unstyled" data-testing-id="myaccount-navigation">
<!-- account navigation with hierarchy -->
<ng-container *ngIf="!(deviceType === 'mobile' || deviceType === 'tablet'); else mobileNavigation">
<ul class="account-navigation list-unstyled">
<ish-account-user-info></ish-account-user-info>
<ng-container *ngFor="let item of navigationItems | keyvalue: unsorted; let first = first">
<ng-container *ishIsAuthorizedTo="item.value.permission || 'always'">
<ng-container *ishHasNotRole="item.value.notRole">
<li
*ngIf="
(item.value.feature || 'always' | ishFeature) && (item.value.serverSetting || 'always' | ishServerSetting)
"
routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: first }"
<ng-container *ngFor="let item of navItems">
<ng-container *ishIsAuthorizedTo="item.permission || 'always'">
<ng-container *ishHasNotRole="item.notRole">
<ng-container
*ngIf="(item.feature || 'always' | ishFeature) && (item.serverSetting || 'always' | ishServerSetting)"
>
<a [routerLink]="item.key" [attr.data-testing-id]="item.value.dataTestingId">{{
item.value.localizationKey | translate
}}</a>
</li>
</ng-container>
</ng-container>
<ul *ngIf="item.value.children" class="account-navigation list-unstyled">
<ng-container *ngFor="let subItem of item.value.children | keyvalue: unsorted">
<ng-container *ishIsAuthorizedTo="item.value.permission || 'always'">
<li
*ngIf="
(subItem.value.feature || 'always' | ishFeature) &&
(subItem.value.serverSetting || 'always' | ishServerSetting)
"
>
<a [routerLink]="item.key + subItem.key" [attr.data-testing-id]="subItem.value.dataTestingId">{{
subItem.value.localizationKey | translate
}}</a>
</li>
<ng-container *ngIf="item.children; else noChildren">
<li
(click)="toggleCollapse(item)"
(keydown.enter)="toggleCollapse(item)"
tabindex="0"
class="account-nav-header"
[attr.aria-expanded]="!item.isCollapsed"
[attr.data-testing-id]="item.id + '-nav-link'"
>
<span>
<fa-icon *ngIf="item.faIcon" [icon]="item.faIcon"></fa-icon>
{{ item.localizationKey | translate }}
</span>
</li>
<li [ngbCollapse]="item.isCollapsed">
<ul class="account-navigation list-unstyled">
<ng-container *ngFor="let subItem of item.children">
<ng-container *ishIsAuthorizedTo="subItem.permission || 'always'">
<ng-container *ishHasNotRole="subItem.notRole">
<ng-container
*ngIf="
(subItem.feature || 'always' | ishFeature) &&
(subItem.serverSetting || 'always' | ishServerSetting)
"
>
<li
[routerLinkActive]="activeClass"
[routerLinkActiveOptions]="{ exact: false }"
(isActiveChange)="activeChanged($event, subItem)"
>
<a [routerLink]="subItem.routerLink" [attr.data-testing-id]="subItem.id + '-nav-link'">
{{ subItem.localizationKey | translate }}
</a>
</li>
</ng-container>
</ng-container>
</ng-container>
</ng-container>
</ul>
</li>
</ng-container>

<ng-template #noChildren>
<li
[routerLinkActive]="activeClass"
[routerLinkActiveOptions]="{ exact: item.routerLink === '/account' ? true : false }"
>
<a [routerLink]="item.routerLink" [attr.data-testing-id]="item.id + '-nav-link'">
<fa-icon *ngIf="item.faIcon" [icon]="item.faIcon"></fa-icon>
{{ item.localizationKey | translate }}
</a>
</li>
</ng-template>
</ng-container>
</ng-container>
</ul>
</ng-container>
</ng-container>
</ul>
</ng-container>

<!-- mobile account navigation select box -->
<ng-template #mobileNavigation>
<select (change)="navigateTo($event.target)" class="form-control">
<ng-container *ngFor="let item of navigationItems | keyvalue: unsorted">
<ng-container *ishIsAuthorizedTo="item.value.permission || 'always'">
<ng-container *ishHasNotRole="item.value.notRole">
<option
*ngIf="
(item.value.feature || 'always' | ishFeature) && (item.value.serverSetting || 'always' | ishServerSetting)
"
[value]="item.key"
[attr.selected]="isSelected(item.key)"
<ng-container *ngFor="let item of navItems">
<ng-container *ishIsAuthorizedTo="item.permission || 'always'">
<ng-container *ishHasNotRole="item.notRole">
<ng-container
*ngIf="(item.feature || 'always' | ishFeature) && (item.serverSetting || 'always' | ishServerSetting)"
>
{{ item.value.localizationKey | translate }}
</option>
<ng-container *ngIf="item.children; else noOptgroup">
<optgroup [label]="item.localizationKey | translate"></optgroup>
<ng-container *ngFor="let subItem of item.children">
<ng-container *ishIsAuthorizedTo="subItem.permission || 'always'">
<ng-container *ishHasNotRole="subItem.notRole">
<ng-container
*ngIf="
(subItem.feature || 'always' | ishFeature) &&
(subItem.serverSetting || 'always' | ishServerSetting)
"
>
<option [value]="subItem.routerLink" [attr.selected]="isSelected(subItem)">
{{ subItem.localizationKey | translate }}
</option>
</ng-container>
</ng-container>
</ng-container>
</ng-container>
</ng-container>

<ng-template #noOptgroup>
<option [value]="item.routerLink" [attr.selected]="isSelected(item)">
{{ item.localizationKey | translate }}
</option>
</ng-template>
</ng-container>
</ng-container>
</ng-container>
</ng-container>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { NgbCollapse } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
import { MockComponent, MockPipe } from 'ng-mocks';
import { MockComponent, MockDirective, MockPipe } from 'ng-mocks';

import { AuthorizationToggleModule } from 'ish-core/authorization-toggle.module';
import { FeatureTogglePipe } from 'ish-core/pipes/feature-toggle.pipe';
Expand All @@ -22,6 +24,8 @@ describe('Account Navigation Component', () => {
declarations: [
AccountNavigationComponent,
MockComponent(AccountUserInfoComponent),
MockComponent(FaIconComponent),
MockDirective(NgbCollapse),
MockPipe(FeatureTogglePipe, () => true),
MockPipe(ServerSettingPipe, () => true),
],
Expand Down
Loading

0 comments on commit 3334e77

Please sign in to comment.