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

feat(fulfillment): notify user about push notification support and permission #914

Merged
merged 9 commits into from
Nov 17, 2023
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export const notificationStyles = css`
box-shadow: var(--oryx-elevation-3) var(--oryx-color-elevation);
}

slot {
word-break: break-word;
}

slot:not([name]) {
display: block;
grid-row: 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class MockRouterService implements Partial<RouterService> {
}

class MockPickingListService implements Partial<PickingListService> {
get = vi.fn().mockReturnValue(of([mockPickingListData[0]]));
getList = vi.fn().mockReturnValue(of(mockPickingListData[0]));
startPicking = vi.fn().mockReturnValue(of(mockPickingListData[0]));
getUpcomingPickingListId = vi.fn().mockReturnValue(of(null));
}
Expand Down
4 changes: 2 additions & 2 deletions libs/domain/picking/list-item/list-item.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class MockRouterService implements Partial<RouterService> {
}

class MockPickingListService implements Partial<PickingListService> {
get = vi.fn().mockReturnValue(of([mockPickingListData[0]]));
getList = vi.fn().mockReturnValue(of(mockPickingListData[0]));
startPicking = vi.fn().mockReturnValue(of(mockPickingListData[0]));
getUpcomingPickingListId = vi.fn().mockReturnValue(of(null));
}
Expand Down Expand Up @@ -135,7 +135,7 @@ describe('PickingListItemComponent', () => {

describe('when cart note is not provided', () => {
beforeEach(async () => {
service.get = vi.fn().mockReturnValue(of([mockPickingListData[1]]));
service.getList = vi.fn().mockReturnValue(of(mockPickingListData[1]));
service.startPicking = vi
.fn()
.mockReturnValue(of(mockPickingListData[1]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class MockOfflineDataPlugin extends OfflineDataPlugin {
//mock
}

refreshData(): Observable<void> {
syncData(): Observable<void> {
return of(undefined);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { Provider } from '@spryker-oryx/di';
import {
NetworkStateDefaultService,
NetworkStateService,
} from '@spryker-oryx/offline';
import { PickingHeaderService } from '@spryker-oryx/picking';
import { PickingSyncActionHandlerService } from '@spryker-oryx/picking/offline';
import { PickingListService } from '@spryker-oryx/picking/services';
Expand All @@ -19,4 +23,8 @@ export const mockPickingListProviders: Provider[] = [
provide: PickingSyncActionHandlerService,
useClass: MockPickingSyncActionHandlerService,
},
{
provide: NetworkStateService,
useClass: NetworkStateDefaultService,
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
PickingListService,
SortableQualifier,
} from '@spryker-oryx/picking/services';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { BehaviorSubject, map, Observable, of } from 'rxjs';
import { mockPickingListData } from './mock-picking-list';

export class MockPickingListService implements Partial<PickingListService> {
Expand Down Expand Up @@ -42,6 +42,10 @@ export class MockPickingListService implements Partial<PickingListService> {
return of(filteredData);
}

getList(id: string): Observable<PickingList | null> {
return this.get({ ids: [id] }).pipe(map((list) => list[0] ?? null));
}

startPicking(pickingList: PickingList): Observable<PickingList> {
return of(pickingList);
}
Expand Down
20 changes: 9 additions & 11 deletions libs/domain/picking/offline/data-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,10 @@ export class OfflineDataPlugin implements AppPlugin {
this.subscription?.unsubscribe();
}

refreshData(injector: Injector): Observable<void> {
syncData(injector: Injector): Observable<void> {
this.refreshing$.next(true);
return this.clearDb(injector).pipe(
switchMap(() => this.populateDb(injector)),
tap({
next: () => {
this.refreshing$.next(false);
},
error: () => {
this.refreshing$.next(false);
},
})
return this.populateData(injector).pipe(
tap(() => this.refreshing$.next(false))
);
}

Expand Down Expand Up @@ -133,4 +125,10 @@ export class OfflineDataPlugin implements AppPlugin {
)
);
}

protected populateData(injector: Injector): Observable<void> {
return this.clearDb(injector).pipe(
switchMap(() => this.populateDb(injector))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { PickingPickerHeaderComponent } from './picker-header.component';
import { pickingPickerHeaderComponent } from './picker-header.def';

class MockPickingListService implements Partial<PickingListService> {
get = vi.fn().mockReturnValue(of([mockPickingListData[0]]));
getList = vi.fn().mockReturnValue(of(mockPickingListData[0]));
getUpcomingPickingListId = vi.fn().mockReturnValue(of(null));
}

Expand Down Expand Up @@ -155,7 +155,7 @@ describe('PickingPickerHeaderComponent', () => {

describe('when picking list does not have customer note', () => {
beforeEach(async () => {
service.get = vi.fn().mockReturnValue(of([mockPickingListData[1]]));
service.getList = vi.fn().mockReturnValue(of(mockPickingListData[1]));

element = await fixture(
html`<oryx-picking-picker-header
Expand Down
8 changes: 4 additions & 4 deletions libs/domain/picking/picker/picker.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { PickingPickerComponent } from './picker.component';
import { pickingPickerComponent } from './picker.def';

class MockPickingListService implements Partial<PickingListService> {
get = vi.fn().mockReturnValue(of([mockPickingListData[0]]));
getList = vi.fn().mockReturnValue(of(mockPickingListData[0]));
finishPicking = vi.fn().mockReturnValue(of(mockPickingListData[0]));
getUpcomingPickingListId = vi.fn().mockReturnValue(of(null));
}
Expand Down Expand Up @@ -125,7 +125,7 @@ describe('PickingPickerComponent', () => {

describe('when there is no picking lists', () => {
beforeEach(async () => {
service.get = vi.fn().mockReturnValue(of([]));
service.getList = vi.fn().mockReturnValue(of(null));

element = await fixture(
html`<oryx-picking-picker pickingListId="id"></oryx-picking-picker>`
Expand Down Expand Up @@ -155,7 +155,7 @@ describe('PickingPickerComponent', () => {

describe('when all items are already picked', () => {
beforeEach(async () => {
service.get = vi.fn().mockReturnValue(of([mockPickingListData[1]]));
service.getList = vi.fn().mockReturnValue(of(mockPickingListData[1]));
service.finishPicking = vi
.fn()
.mockReturnValue(of(mockPickingListData[1]));
Expand Down Expand Up @@ -222,7 +222,7 @@ describe('PickingPickerComponent', () => {
],
};

service.get = vi.fn().mockReturnValue(of([partiallyPickedPickingList]));
service.getList = vi.fn().mockReturnValue(of(partiallyPickedPickingList));
service.finishPicking = vi
.fn()
.mockReturnValue(of(partiallyPickedPickingList));
Expand Down
2 changes: 0 additions & 2 deletions libs/domain/picking/service-worker/push.initializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ export class PushInitializer implements AppInitializer {

const payload: PushSyncPayload = event.data.json();

console.log('Push', this.syncSchedulerService);

event.waitUntil(
firstValueFrom(
this.syncSchedulerService.schedule({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { inject } from '@spryker-oryx/di';
import {
BehaviorSubject,
catchError,
map,
Observable,
switchMap,
tap,
Expand Down Expand Up @@ -50,6 +51,10 @@ export class PickingListDefaultService implements PickingListService {
);
}

getList(id: string): Observable<PickingList | null> {
return this.get({ ids: [id] }).pipe(map((list) => list[0] ?? null));
}

startPicking(pickingList: PickingList): Observable<PickingList | null> {
this.upcomingPickingListId$.next(pickingList.id);
return this.adapter.startPicking(pickingList).pipe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {

export interface PickingListService {
get(qualifier: PickingListQualifier): Observable<PickingList[]>;
getList(id: string): Observable<PickingList | null>;
startPicking(pickingList: PickingList): Observable<PickingList | null>;
getUpcomingPickingListId(): Observable<string | null>;
updatePickingItems(pickingList: PickingList): Observable<PickingList>;
Expand Down
2 changes: 2 additions & 0 deletions libs/domain/picking/src/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
pickingWarehouseAssignmentComponent,
} from './components';
import { PickingConfig, providePickingConfig } from './config.provider';
import { PickingListContextFallback } from './picking-list.context';
import { defaultPickingRoutes } from './routes';
import { PickingHeaderDefaultService, PickingHeaderService } from './services';

Expand Down Expand Up @@ -73,6 +74,7 @@ export class PickingFeature extends PickingServicesFeature {
provide: LocaleAdapter,
useClass: DefaultLocaleAdapter,
},
PickingListContextFallback,
...super.getProviders(),
];
}
Expand Down
1 change: 1 addition & 0 deletions libs/domain/picking/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from './config.provider';
export * from './feature';
export * from './mixins';
export * from './models';
export * from './picking-list.context';
export * from './services';
50 changes: 19 additions & 31 deletions libs/domain/picking/src/mixins/picking-list.mixin.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,48 @@
import { ContextController } from '@spryker-oryx/core';
import { resolve } from '@spryker-oryx/di';
import { PickingListComponentProperties } from '@spryker-oryx/picking';
import { PickingListContext } from '@spryker-oryx/picking';
import {
PickingList,
PickingListService,
} from '@spryker-oryx/picking/services';
import {
Signal,
Type,
isDefined,
observe,
computed,
signal,
signalAware,
signalProperty,
} from '@spryker-oryx/utilities';
import { LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import {
BehaviorSubject,
Observable,
distinctUntilChanged,
filter,
map,
switchMap,
} from 'rxjs';
import { Observable, of } from 'rxjs';

export declare class PickingListMixinInterface
implements PickingListComponentProperties
{
protected pickingListService: PickingListService;
export declare class PickingListMixinInterface {
pickingListId?: string;
protected pickingList$: Observable<PickingList>;
protected context: Observable<string | undefined>;
protected pickingListService: PickingListService;
protected $pickingList: Signal<PickingList>;
protected $upcomingPickingListId: Signal<string | null>;
}

export const PickingListMixin = <
T extends Type<LitElement & PickingListComponentProperties>
>(
export const PickingListMixin = <T extends Type<LitElement>>(
superClass: T
): Type<PickingListMixinInterface> & T => {
@signalAware()
class PickingListMixinClass extends superClass {
protected pickingListService = resolve(PickingListService);
@signalProperty({ reflect: true }) pickingListId?: string;

@property() pickingListId?: string;

@observe()
protected pickingListId$ = new BehaviorSubject(this.pickingListId);
protected pickingListService = resolve(PickingListService);

protected pickingList$ = this.pickingListId$.pipe(
distinctUntilChanged(),
filter(isDefined),
switchMap((id) => this.pickingListService.get({ ids: [id] })),
map((list) => list?.[0] ?? null)
protected contextController = new ContextController(this);
protected $context = signal(
this.contextController.get<string>(PickingListContext.PickingListId)
);

protected $pickingList = signal(this.pickingList$);
protected $pickingList = computed(() => {
const id = this.pickingListId ?? this.$context();

return id ? this.pickingListService.getList(id) : of(null);
});

protected $upcomingPickingListId = signal(
this.pickingListService.getUpcomingPickingListId()
Expand Down
16 changes: 16 additions & 0 deletions libs/domain/picking/src/picking-list.context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ContextFallback } from '@spryker-oryx/core';
import { inject, Provider } from '@spryker-oryx/di';
import { RouterService } from '@spryker-oryx/router';
import { map } from 'rxjs';

export const enum PickingListContext {
PickingListId = 'pickingListId',
}

export const PickingListContextFallback: Provider = {
provide: `${ContextFallback}${PickingListContext.PickingListId}`,
useFactory: () =>
inject(RouterService)
.currentParams()
.pipe(map((params) => params?.pickingListId)),
};
31 changes: 18 additions & 13 deletions libs/domain/picking/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,35 @@ export const defaultPickingRoutes: RouteConfig[] = [
{
path: '/',
render: () =>
html`<oryx-composition uid="picking-lists"></oryx-composition>`,
html`<oryx-composition
uid="picking-lists"
mode-light
></oryx-composition>`,
},
{
path: '/warehouse-selection',
render: () =>
html`<oryx-composition uid="warehouse-selection"></oryx-composition>`,
html`<oryx-composition
uid="warehouse-selection"
mode-light
></oryx-composition>`,
},
{
path: '/picking-list/picking/:id',
render: ({ id }) =>
html`<oryx-picking-picker
.pickingListId="${id}"
path: '/picking-list/picking/:pickingListId',
render: () =>
html`<oryx-composition
uid="picking-picker"
mode-light
></oryx-picking-picker>`,
></oryx-composition>`,
leave: (): Observable<boolean> =>
resolve(PickingHeaderService).guardWithDialog(),
},
{
path: '/customer-note-info/:id',
render: ({ id }) => html`
<oryx-picking-customer-note
.pickingListId=${id}
path: '/customer-note-info/:pickingListId',
render: () =>
html`<oryx-composition
uid="customer-note"
mode-light
></oryx-picking-customer-note>
`,
></oryx-composition>`,
},
];
Loading
Loading