Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

my account navigation #960

Draft
wants to merge 45 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
be99932
artificial commit
tobi-or-not-tobi Nov 9, 2023
c0b0584
chore: Navigation layout plugin implementation (#883)
tobi-or-not-tobi Nov 10, 2023
0fa5bea
Merge branch 'development' into feature/HRZ-2519-header-navigation
tobi-or-not-tobi Nov 10, 2023
db3b986
fix SSR
tobi-or-not-tobi Nov 10, 2023
1f2b129
ssr improvements
tobi-or-not-tobi Nov 10, 2023
e17d437
category list component
tobi-or-not-tobi Nov 11, 2023
9876bf3
style lint
tobi-or-not-tobi Nov 11, 2023
03ce240
fix
tobi-or-not-tobi Nov 11, 2023
12c410d
Merge branch 'development' into feature/HRZ-2519-header-navigation
tobi-or-not-tobi Nov 13, 2023
c60cbde
refactor: category links refactor (#893)
tobi-or-not-tobi Nov 13, 2023
3ba3889
fix
tobi-or-not-tobi Nov 14, 2023
68bbeec
Merge branch 'development' into feature/HRZ-2519-header-navigation
tobi-or-not-tobi Nov 14, 2023
d8d20bc
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Nov 15, 2023
2847e1c
fix styles
tobi-or-not-tobi Nov 15, 2023
12defb6
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Nov 15, 2023
7e87363
Merge branch 'development' into feature/HRZ-2519-header-navigation
tobi-or-not-tobi Nov 15, 2023
b01cb57
chore: category navigation e2e (#892)
tobi-or-not-tobi Nov 15, 2023
60f3a61
Merge branch 'feature/HRZ-2519-header-navigation' into feature/HRZ-90…
tobi-or-not-tobi Nov 15, 2023
541d636
dropdown
tobi-or-not-tobi Nov 15, 2023
c559022
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Nov 21, 2023
ff9f9e9
tmp
tobi-or-not-tobi Nov 22, 2023
2d96118
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Nov 24, 2023
a770221
temp
tobi-or-not-tobi Nov 25, 2023
b9c1860
cleanup
tobi-or-not-tobi Nov 25, 2023
ccac324
tmp
tobi-or-not-tobi Nov 26, 2023
214a783
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Nov 27, 2023
33827ca
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Nov 30, 2023
aa6b127
tmp
tobi-or-not-tobi Nov 30, 2023
9d89b8a
My account navigation and pages
tobi-or-not-tobi Nov 30, 2023
c052bb7
missing pages, simplify path
tobi-or-not-tobi Nov 30, 2023
6c3cfda
cleanup
tobi-or-not-tobi Nov 30, 2023
2bfec6e
move trigger component to user domain
tobi-or-not-tobi Nov 30, 2023
dda08a5
nav ref
tobi-or-not-tobi Nov 30, 2023
1f36472
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Dec 3, 2023
9e7c3bb
my account control
tobi-or-not-tobi Dec 4, 2023
244ebe9
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Dec 4, 2023
2cd6d34
clean up
tobi-or-not-tobi Dec 4, 2023
a7e0992
cleanup
tobi-or-not-tobi Dec 4, 2023
9edae87
cleanup
tobi-or-not-tobi Dec 4, 2023
946256c
add tests for logout
tobi-or-not-tobi Dec 4, 2023
f0b156b
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Dec 7, 2023
41452d1
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Dec 12, 2023
8b4c813
logout link component
tobi-or-not-tobi Dec 12, 2023
df723e3
Merge branch 'development' into feature/HRZ-90382-category-list
tobi-or-not-tobi Dec 13, 2023
0e0cca4
in between
tobi-or-not-tobi Dec 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libs/base/ui/action/button/button.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,6 @@ export const enum ButtonType {
* A button which is rendered as icon.
*/
Icon = 'icon',

Tile = 'tile',
}
25 changes: 25 additions & 0 deletions libs/base/ui/action/button/button.styles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { css } from 'lit';
import { HeadingTag, headingUtil } from '../../structure/heading/src';

const baseStyles = css`
:host {
Expand Down Expand Up @@ -259,9 +260,33 @@ const loadingStyles = css`
}
`;

const tileStyles = css`
:host([type='tile']) {
color: var(--oryx-button-color, var(--_text-color));
}

:host([type='tile']) :is(a, button),
:host([type='tile']) ::slotted(:is(a, button)) {
--oryx-icon-size: 32px;

${headingUtil(HeadingTag.Subtitle)}

text-transform: uppercase;
height: 68px;
width: 62px;
/* max-width: 62px; */
display: grid;
align-content: center;
justify-items: center;
gap: 5px;
padding: 12px 8px;
}
`;

export const buttonStyles = css`
${baseStyles}
${sizeStyles}
${colorStyles}
${loadingStyles}
${tileStyles}
`;
1 change: 1 addition & 0 deletions libs/base/ui/action/link/src/styles/storefront.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const storefrontLinkStyles = css`
position: relative;
display: inline-flex;
width: var(--oryx-link-width);
cursor: pointer;
}

:host([icon]) {
Expand Down
1 change: 1 addition & 0 deletions libs/base/ui/graphical/icon/src/icon.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export enum IconTypes {
Carrier = 'carrier',
Location = 'location_on',
Login = 'login',
Logout = 'logout',
List = 'list',
ViewList = 'view_list',
BulletList = 'format_list_bulleted',
Expand Down
10 changes: 4 additions & 6 deletions libs/base/ui/overlays/dropdown/dropdown.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Position } from './dropdown.model';

export const dropdownBaseStyles = css`
:host {
--oryx-popover-top-space: 4px;
--oryx-popover-vertical-offset: 10px;
--oryx-popover-maxwidth: 206px;

Expand All @@ -32,7 +31,7 @@ export const dropdownBaseStyles = css`
),
var(--oryx-popover-maxheight, ${unsafecss(POPOVER_HEIGHT)}px)
);
width: var(--_oryx-dropdown-width);
width: var(--oryx-dropdown-width, var(--_oryx-dropdown-width));
inset-block-start: 0;
inset-inline: var(--_oryx-dropdown-start-offset, auto)
var(--_oryx-dropdown-end-offset, auto);
Expand All @@ -49,9 +48,8 @@ export const dropdownBaseStyles = css`

${featureVersion >= `1.3`
? css`
:host(:not([vertical-align])) oryx-popover {
transform: scaleX(var(--oryx-popover-visible, 0))
scaleY(var(--oryx-popover-visible, 0));
:host([vertical-align]) oryx-popover {
transform: scaleY(var(--oryx-popover-visible, 0));
}
`
: css``}
Expand Down Expand Up @@ -95,7 +93,7 @@ export const dropdownBaseStyles = css`
}

:host([vertical-align]:not([up])) oryx-popover {
inset-block-start: calc(100% + var(--oryx-popover-top-space));
inset-block-start: calc(100% + var(--oryx-popover-top-space, 4px));
}

:host([vertical-align][up]) oryx-popover {
Expand Down
8 changes: 6 additions & 2 deletions libs/base/ui/overlays/popover/src/styles/oryx.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ import { css } from 'lit';
export const popoverStyles = css`
:host {
background-color: var(--oryx-color-neutral-1);
box-shadow: var(--oryx-elevation-2) var(--oryx-color-elevation);
border-radius: var(--oryx-border-radius-small);
box-shadow: var(--oryx-shadow-hovering) var(--oryx-color-elevation);
border-radius: var(
--oryx-popover-border-radius,
var(--oryx-border-radius-small)
);
transition: transform var(--oryx-transition-time) ease-in-out;
width: var(--oryx-popover-width);
}
`;
12 changes: 6 additions & 6 deletions libs/domain/content/link/link.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class ContentLinkComponent extends ContentMixin<
protected $link = computed(() => {
const { url, type, id, params } = this.$options();
if (url) return of(url);
if (type) return this.semanticLinkService.get({ type: type, id, params });
if (type) return this.semanticLinkService.get({ type, id, params });
return of(null);
});

Expand All @@ -56,9 +56,9 @@ export class ContentLinkComponent extends ContentMixin<
const { button, icon, singleLine, color } = this.$options();

if (button) {
return html`<oryx-button part="link" }
>${this.renderLink(true)}</oryx-button
>`;
return html`<oryx-button part="link">
${this.renderLink(true)}
</oryx-button>`;
}

return html`<oryx-link
Expand All @@ -78,7 +78,7 @@ export class ContentLinkComponent extends ContentMixin<

if (type === RouteType.Category && id) {
return this.categoryService
.get(id)
.get({ id })
.pipe(map((category) => category?.name));
}

Expand All @@ -94,7 +94,7 @@ export class ContentLinkComponent extends ContentMixin<
});

protected renderLink(custom?: boolean): TemplateResult {
if (!this.$link()) return html`${this.$text()}`;
if (!this.$link()) return html`<a tabindex="0">${this.$text()}</a>`;

const { label, target } = this.$options();

Expand Down
1 change: 1 addition & 0 deletions libs/domain/content/link/link.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { css } from 'lit';

export const contentLinkStyles = css`
:host {
display: block;
padding: var(--oryx-content-link-padding);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class ProductDetailsBreadcrumbResolver implements BreadcrumbResolver {
}

return combineLatest(
categoryIds.map((id) => this.categoryService.getTrail(id))
categoryIds.map((id) => this.categoryService.getTrail({ id }))
).pipe(
switchMap((trails) =>
combineLatest([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class CategoryBreadcrumbResolver implements BreadcrumbResolver {
switchMap((category) =>
this.categoryService
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.getTrail(String((category as ValueFacet).selectedValues![0]))
.getTrail({ id: String((category as ValueFacet).selectedValues![0]) })
.pipe(
switchMap((trail) =>
combineLatest(
Expand Down
1 change: 1 addition & 0 deletions libs/domain/user/navigation-control/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './navigation-control.component';
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { AuthService } from '@spryker-oryx/auth';
import { resolve } from '@spryker-oryx/di';
import { ContentMixin } from '@spryker-oryx/experience';
import { ButtonType } from '@spryker-oryx/ui/button';
import { IconTypes } from '@spryker-oryx/ui/icon';
import { UserService } from '@spryker-oryx/user';
import { hydrate, signal } from '@spryker-oryx/utilities';
import { LitElement, TemplateResult, html } from 'lit';

@hydrate()
export class UserNavigationControlComponent extends ContentMixin(LitElement) {
protected authService = resolve(AuthService);
protected userService = resolve(UserService);

protected $isAuthenticated = signal(this.authService.isAuthenticated());
protected $user = signal(this.userService.getUser());

protected override render(): TemplateResult | void {
return html`
<oryx-button .type=${ButtonType.Tile}>
<oryx-icon .type=${IconTypes.User}></oryx-icon>
${this.$isAuthenticated()
? this.$user()?.firstName ?? ''
: this.i18n('auth.login')}
</oryx-button>
`;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { componentDef } from '@spryker-oryx/utilities';

export const userNavigationControlComponent = componentDef({
name: 'oryx-user-navigation-control',
impl: () =>
import('./navigation-control.component.js').then(
(m) => m.UserNavigationControlComponent
),
});
1 change: 1 addition & 0 deletions libs/domain/user/src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export * from '../address-list/address-list.def';
export * from '../address-remove/address-remove.def';
export * from '../address/address.def';
export * from '../contact-form/contact-form.def';
export * from '../navigation-control/navigation-control.def';
export * from '../registration/registration.def';
3 changes: 3 additions & 0 deletions libs/platform/auth/logout-link/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './logout-link.component';
export * from './logout-link.model';
export * from './logout-link.schema';
105 changes: 105 additions & 0 deletions libs/platform/auth/logout-link/logout-link.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { fixture } from '@open-wc/testing-helpers';
import { AuthService, logoutLinkComponent } from '@spryker-oryx/auth';
import { createInjector, destroyInjector } from '@spryker-oryx/di';
import { RouterService } from '@spryker-oryx/router';
import { useComponent } from '@spryker-oryx/utilities';
import { html } from 'lit';
import { of } from 'rxjs';
import { LogoutLinkComponent } from './logout-link.component';

class MockAuthService implements Partial<AuthService> {
logout = vi.fn().mockReturnValue(of(null));
isAuthenticated = vi.fn().mockReturnValue(of(false));
}

class MockRouterService implements Partial<RouterService> {
navigate = vi.fn();
}

describe('LogoutLinkComponent', () => {
let element: LogoutLinkComponent;
let authService: MockAuthService;
let routerService: MockRouterService;

const clickButton = (): void => {
element.renderRoot.querySelector<HTMLElement>('oryx-content-link')?.click();
};

beforeAll(async () => {
await useComponent(logoutLinkComponent);
});

beforeEach(async () => {
const testInjector = createInjector({
providers: [
{ provide: AuthService, useClass: MockAuthService },
{ provide: RouterService, useClass: MockRouterService },
],
});
authService = testInjector.inject<MockAuthService>(AuthService);
routerService = testInjector.inject<MockRouterService>(RouterService);
});

afterEach(() => {
destroyInjector();
});

describe('when is not authenticated', () => {
it('passes the a11y audit', async () => {
await expect(element).shadowDom.to.be.accessible();
});

it('should not render anything', () => {
expect(element).not.toContainElement('*');
});
});

describe.only('when is authenticated', () => {
beforeEach(async () => {
authService.isAuthenticated = vi.fn().mockReturnValue(of(true));
element = await fixture(
html`<oryx-auth-logout-link></oryx-auth-logout-link>`
);
});

it('passes the a11y audit', async () => {
await expect(element).shadowDom.to.be.accessible();
});

describe('and link is clicked', () => {
beforeEach(() => {
clickButton();
});

it('should emit the logout', () => {
expect(authService.logout).toHaveBeenCalled();
});

describe('and redirect route is not provided', () => {
beforeEach(async () => {
clickButton();
});

it('should redirect to the route', () => {
expect(routerService.navigate).not.toHaveBeenCalled();
});
});

describe('and redirect route is provided', () => {
const redirectUrl = '/test';

beforeEach(async () => {
element = await fixture(html`<oryx-auth-logout-link
.options=${{ redirectUrl }}
>
</oryx-auth-logout-link>`);
clickButton();
});

it('should redirect to the route', () => {
expect(routerService.navigate).toHaveBeenCalledWith(redirectUrl);
});
});
});
});
});
40 changes: 40 additions & 0 deletions libs/platform/auth/logout-link/logout-link.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { AuthService } from '@spryker-oryx/auth';
import { resolve } from '@spryker-oryx/di';
import { ContentMixin } from '@spryker-oryx/experience';
import { RouterService } from '@spryker-oryx/router';
import { hydrate, signal } from '@spryker-oryx/utilities';
import { LitElement, TemplateResult, html } from 'lit';
import { LogoutLinkOptions } from './logout-link.model';

@hydrate({ event: 'window:load' })
export class LogoutLinkComponent extends ContentMixin<LogoutLinkOptions>(
LitElement
) {
protected authService = resolve(AuthService);
protected routerService = resolve(RouterService);

protected $isAuthenticated = signal(this.authService.isAuthenticated());

protected override render(): TemplateResult | void {
if (!this.$isAuthenticated()) return;

const icon = this.$options()?.icon;
return html`
<oryx-content-link
.options=${{ icon }}
.content=${{ text: this.i18n('auth.logout') }}
@click=${this.onClick}
>
</oryx-content-link>
`;
}

protected onClick(): void {
this.authService.logout().subscribe(() => {
const { redirectUrl } = this.$options();
if (redirectUrl) {
this.routerService.navigate(redirectUrl);
}
});
}
}
16 changes: 16 additions & 0 deletions libs/platform/auth/logout-link/logout-link.def.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { componentDef } from '@spryker-oryx/utilities';
import { LogoutLinkOptions } from './logout-link.model';

declare global {
interface FeatureOptions {
'oryx-auth-logout-link'?: LogoutLinkOptions;
}
}

export const logoutLinkComponent = componentDef({
name: 'oryx-auth-logout-link',
impl: () =>
import('./logout-link.component').then((m) => m.LogoutLinkComponent),
schema: () =>
import('./logout-link.schema').then((m) => m.logoutLinkComponentSchema),
});
Loading
Loading