mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
Merge branch 'develop' into feature/responsive-customer-orders
This commit is contained in:
1
.vscode/extensions.json
vendored
1
.vscode/extensions.json
vendored
@@ -3,6 +3,5 @@
|
||||
"johnpapa.angular2",
|
||||
"esbenp.prettier-vscode",
|
||||
"angular.ng-template",
|
||||
"eg2.vscode-npm-script"
|
||||
]
|
||||
}
|
||||
197
angular.json
197
angular.json
@@ -375,37 +375,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@shell/breadcrumb": {
|
||||
"projectType": "library",
|
||||
"root": "apps/shell/breadcrumb",
|
||||
"sourceRoot": "apps/shell/breadcrumb/src",
|
||||
"prefix": "shell",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"options": {
|
||||
"tsConfig": "apps/shell/breadcrumb/tsconfig.lib.json",
|
||||
"project": "apps/shell/breadcrumb/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "apps/shell/breadcrumb/tsconfig.lib.prod.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"tsConfig": "apps/shell/breadcrumb/tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"polyfills": [
|
||||
"zone.js",
|
||||
"zone.js/testing"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@domain/defs": {
|
||||
"projectType": "library",
|
||||
"root": "apps/domain/defs",
|
||||
@@ -840,37 +809,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@shell/header": {
|
||||
"projectType": "library",
|
||||
"root": "apps/shell/header",
|
||||
"sourceRoot": "apps/shell/header/src",
|
||||
"prefix": "shell",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"options": {
|
||||
"tsConfig": "apps/shell/header/tsconfig.lib.json",
|
||||
"project": "apps/shell/header/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "apps/shell/header/tsconfig.lib.prod.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"tsConfig": "apps/shell/header/tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"polyfills": [
|
||||
"zone.js",
|
||||
"zone.js/testing"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@modal/reorder": {
|
||||
"projectType": "library",
|
||||
"root": "apps/modal/reorder",
|
||||
@@ -1058,74 +996,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@shell/footer": {
|
||||
"projectType": "library",
|
||||
"root": "apps/shell/footer",
|
||||
"sourceRoot": "apps/shell/footer/src",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"options": {
|
||||
"project": "apps/shell/footer/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "apps/shell/footer/tsconfig.lib.prod.json"
|
||||
},
|
||||
"development": {
|
||||
"tsConfig": "apps/shell/footer/tsconfig.lib.json"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"tsConfig": "apps/shell/footer/tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"polyfills": [
|
||||
"zone.js",
|
||||
"zone.js/testing"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@shell/process": {
|
||||
"projectType": "library",
|
||||
"root": "apps/shell/process",
|
||||
"sourceRoot": "apps/shell/process/src",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"options": {
|
||||
"project": "apps/shell/process/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "apps/shell/process/tsconfig.lib.prod.json"
|
||||
},
|
||||
"development": {
|
||||
"tsConfig": "apps/shell/process/tsconfig.lib.json"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"tsConfig": "apps/shell/process/tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"polyfills": [
|
||||
"zone.js",
|
||||
"zone.js/testing"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@domain/isa": {
|
||||
"projectType": "library",
|
||||
"root": "apps/domain/isa",
|
||||
@@ -1160,40 +1030,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@shell/filter-overlay": {
|
||||
"projectType": "library",
|
||||
"root": "apps/shell/filter-overlay",
|
||||
"sourceRoot": "apps/shell/filter-overlay/src",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"options": {
|
||||
"project": "apps/shell/filter-overlay/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "apps/shell/filter-overlay/tsconfig.lib.prod.json"
|
||||
},
|
||||
"development": {
|
||||
"tsConfig": "apps/shell/filter-overlay/tsconfig.lib.json"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"tsConfig": "apps/shell/filter-overlay/tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"polyfills": [
|
||||
"zone.js",
|
||||
"zone.js/testing"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@store/search-component-store": {
|
||||
"projectType": "library",
|
||||
"root": "apps/store/search-component-store",
|
||||
@@ -1634,6 +1470,39 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shell": {
|
||||
"projectType": "library",
|
||||
"root": "apps/shell",
|
||||
"sourceRoot": "apps/shell/src",
|
||||
"prefix": "shell",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"options": {
|
||||
"project": "apps/shell/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "apps/shell/tsconfig.lib.prod.json"
|
||||
},
|
||||
"development": {
|
||||
"tsConfig": "apps/shell/tsconfig.lib.json"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"tsConfig": "apps/shell/tsconfig.spec.json",
|
||||
"polyfills": [
|
||||
"zone.js",
|
||||
"zone.js/testing"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { DomainAvailabilityService } from '@domain/availability';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { BranchDTO } from '@swagger/checkout';
|
||||
import { isBoolean, isNumber } from '@utils/common';
|
||||
@@ -16,25 +15,30 @@ import {
|
||||
selectActivatedProcess,
|
||||
patchProcess,
|
||||
patchProcessData,
|
||||
selectTitle,
|
||||
setTitle,
|
||||
} from './store';
|
||||
|
||||
@Injectable()
|
||||
export class ApplicationService {
|
||||
/** @deprecated */
|
||||
private activatedProcessIdSubject = new BehaviorSubject<number>(undefined);
|
||||
|
||||
/** @deprecated */
|
||||
get activatedProcessId() {
|
||||
return this.activatedProcessIdSubject.value;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
get activatedProcessId$() {
|
||||
return this.activatedProcessIdSubject.asObservable();
|
||||
}
|
||||
|
||||
title$ = this.store.select(selectTitle);
|
||||
|
||||
constructor(private store: Store) {}
|
||||
|
||||
setTitle(title: string) {
|
||||
this.store.dispatch(setTitle({ title }));
|
||||
}
|
||||
|
||||
getProcesses$(section?: 'customer' | 'branch') {
|
||||
const processes$ = this.store.select(selectProcesses);
|
||||
return processes$.pipe(map((processes) => processes.filter((process) => (section ? process.section === section : true))));
|
||||
|
||||
@@ -3,6 +3,8 @@ import { ApplicationProcess } from '..';
|
||||
|
||||
const prefix = '[CORE-APPLICATION]';
|
||||
|
||||
export const setTitle = createAction(`${prefix} Set Title`, props<{ title: string }>());
|
||||
|
||||
export const setSection = createAction(`${prefix} Set Section`, props<{ section: 'customer' | 'branch' }>());
|
||||
|
||||
export const addProcess = createAction(`${prefix} Add Process`, props<{ process: ApplicationProcess }>());
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import { Action, createReducer, on } from '@ngrx/store';
|
||||
import { setSection, addProcess, removeProcess, setActivatedProcess, patchProcess, patchProcessData } from './application.actions';
|
||||
import {
|
||||
setSection,
|
||||
addProcess,
|
||||
removeProcess,
|
||||
setActivatedProcess,
|
||||
patchProcess,
|
||||
patchProcessData,
|
||||
setTitle,
|
||||
} from './application.actions';
|
||||
import { ApplicationState, INITIAL_APPLICATION_STATE } from './application.state';
|
||||
|
||||
const _applicationReducer = createReducer(
|
||||
INITIAL_APPLICATION_STATE,
|
||||
on(setTitle, (state, { title }) => ({ ...state, title })),
|
||||
on(setSection, (state, { section }) => ({ ...state, section })),
|
||||
on(addProcess, (state, { process }) => ({ ...state, processes: [...state.processes, { data: {}, ...process }] })),
|
||||
on(removeProcess, (state, { processId }) => {
|
||||
|
||||
@@ -2,6 +2,8 @@ import { createFeatureSelector, createSelector } from '@ngrx/store';
|
||||
import { ApplicationState } from './application.state';
|
||||
export const selectApplicationState = createFeatureSelector<ApplicationState>('core-application');
|
||||
|
||||
export const selectTitle = createSelector(selectApplicationState, (s) => s.title);
|
||||
|
||||
export const selectSection = createSelector(selectApplicationState, (s) => s.section);
|
||||
|
||||
export const selectProcesses = createSelector(selectApplicationState, (s) => s.processes);
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { ApplicationProcess } from '../defs';
|
||||
|
||||
export interface ApplicationState {
|
||||
title: string;
|
||||
processes: ApplicationProcess[];
|
||||
section: 'customer' | 'branch';
|
||||
}
|
||||
|
||||
export const INITIAL_APPLICATION_STATE: ApplicationState = {
|
||||
title: '',
|
||||
processes: [],
|
||||
section: 'customer',
|
||||
};
|
||||
|
||||
@@ -135,9 +135,9 @@ export class BreadcrumbService {
|
||||
crumbs.forEach((crumb) => this.removeBreadcrumb(crumb.id));
|
||||
}
|
||||
|
||||
getLatestBreadcrumbForSection(section: 'customer' | 'branch') {
|
||||
getLatestBreadcrumbForSection(section: 'customer' | 'branch', predicate: (crumb: Breadcrumb) => boolean = (_) => true) {
|
||||
return this.store
|
||||
.select(selectors.selectBreadcrumbsBySection, { section })
|
||||
.pipe(map((crumbs) => crumbs.sort((a, b) => b.changed - a.changed).find((f) => true)));
|
||||
.pipe(map((crumbs) => crumbs.sort((a, b) => b.changed - a.changed).find((f) => predicate(f))));
|
||||
}
|
||||
}
|
||||
|
||||
7
apps/core/navigation/ng-package.json
Normal file
7
apps/core/navigation/ng-package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../../dist/core/navigation",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
||||
8
apps/core/navigation/src/lib/navigation.module.ts
Normal file
8
apps/core/navigation/src/lib/navigation.module.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [],
|
||||
exports: [],
|
||||
})
|
||||
export class NavigationModule {}
|
||||
16
apps/core/navigation/src/lib/navigation.service.spec.ts
Normal file
16
apps/core/navigation/src/lib/navigation.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NavigationService } from './navigation.service';
|
||||
|
||||
describe('EnvironmentService', () => {
|
||||
let service: NavigationService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(NavigationService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -21,7 +21,7 @@ export interface OutletLocations {
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AppNavigationService {
|
||||
export class NavigationService {
|
||||
get isTablet() {
|
||||
return this._environment.isTablet();
|
||||
}
|
||||
6
apps/core/navigation/src/public-api.ts
Normal file
6
apps/core/navigation/src/public-api.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
* Public API Surface of navigation
|
||||
*/
|
||||
|
||||
export * from './lib/navigation.service';
|
||||
export * from './lib/navigation.module';
|
||||
@@ -45,6 +45,8 @@ export class DomainInStockService {
|
||||
const key = this.getKey({ itemId, branchId });
|
||||
this._addToInStockQueue({ itemId, branchId });
|
||||
|
||||
let _previousValue: InStock;
|
||||
|
||||
const sub = combineLatest([this._inStockMap, this._inStockFetchingMap])
|
||||
.pipe(distinctUntilChanged(isEqual))
|
||||
.subscribe(([inStockMap, inStockFetchingMap]) => {
|
||||
@@ -54,7 +56,12 @@ export class DomainInStockService {
|
||||
inStock: inStockMap[key],
|
||||
fetching: inStockFetchingMap[key] ?? false,
|
||||
};
|
||||
obs.next(inStock);
|
||||
|
||||
if (!isEqual(inStock, _previousValue)) {
|
||||
obs.next(inStock);
|
||||
}
|
||||
|
||||
_previousValue = inStock;
|
||||
});
|
||||
return () => {
|
||||
sub.unsubscribe();
|
||||
|
||||
@@ -447,7 +447,7 @@ export class DomainRemissionService {
|
||||
* Create a new receipt for the given return/remission
|
||||
* @param returnId Return ID
|
||||
* @param receiptNumber Receipt number
|
||||
* @returns ReturnDTO - ShippingDocument
|
||||
* @returns ReceiptDTO
|
||||
*/
|
||||
async createReceipt(returnDTO: ReturnDTO, receiptNumber?: string): Promise<ReceiptDTO> {
|
||||
const stock = await this._getStock();
|
||||
@@ -471,14 +471,41 @@ export class DomainRemissionService {
|
||||
return receipt;
|
||||
}
|
||||
|
||||
async completeReceipt(returnId: number, receiptId: number, packageCode: string): Promise<ReceiptDTO> {
|
||||
/**
|
||||
* Create a new Package and assign it to a receipt
|
||||
* @param returnId Return ID
|
||||
* @param receiptId Receipt ID
|
||||
* @param packageNumber Packagenumber
|
||||
* @returns ReceiptDTO
|
||||
*/
|
||||
async createReceiptAndAssignPackage({
|
||||
returnId,
|
||||
receiptId,
|
||||
packageNumber,
|
||||
}: {
|
||||
returnId: number;
|
||||
receiptId: number;
|
||||
packageNumber: string;
|
||||
}): Promise<ReceiptDTO> {
|
||||
const response = await this._returnService
|
||||
.ReturnCreateAndAssignPackage({
|
||||
returnId,
|
||||
receiptId,
|
||||
data: {
|
||||
packageNumber,
|
||||
},
|
||||
})
|
||||
.toPromise();
|
||||
const receipt: ReceiptDTO = response.result;
|
||||
return receipt;
|
||||
}
|
||||
|
||||
async completeReceipt(returnId: number, receiptId: number): Promise<ReceiptDTO> {
|
||||
const res = await this._returnService
|
||||
.ReturnFinalizeReceipt({
|
||||
returnId,
|
||||
receiptId,
|
||||
data: {
|
||||
packageCode,
|
||||
},
|
||||
data: {},
|
||||
})
|
||||
.toPromise();
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { isDevMode, NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { DebugComponent } from './debug/debug.component';
|
||||
import {
|
||||
CanActivateCartGuard,
|
||||
CanActivateCartWithProcessIdGuard,
|
||||
@@ -17,9 +16,9 @@ import {
|
||||
} from './guards';
|
||||
import { CanActivateAssortmentGuard } from './guards/can-activate-assortment.guard';
|
||||
import { CanActivatePackageInspectionGuard } from './guards/can-activate-package-inspection.guard';
|
||||
import { MainComponent } from './main.component';
|
||||
import { PreviewComponent } from './preview';
|
||||
import { BranchSectionResolver, CustomerSectionResolver, ProcessIdResolver } from './resolvers';
|
||||
import { ShellComponent, ShellModule } from './shell';
|
||||
import { TokenLoginComponent, TokenLoginModule } from './token-login';
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -40,7 +39,7 @@ const routes: Routes = [
|
||||
children: [
|
||||
{
|
||||
path: 'kunde',
|
||||
component: ShellComponent,
|
||||
component: MainComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'dashboard',
|
||||
@@ -106,7 +105,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'filiale',
|
||||
component: ShellComponent,
|
||||
component: MainComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'task-calendar',
|
||||
@@ -152,7 +151,7 @@ if (isDevMode()) {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes), ShellModule, TokenLoginModule],
|
||||
imports: [RouterModule.forRoot(routes), TokenLoginModule],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class AppRoutingModule {}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
:host {
|
||||
@apply block box-border;
|
||||
}
|
||||
|
||||
button {
|
||||
@apply fixed bottom-4 right-2 bg-blue-500 text-white font-bold py-2 px-4 rounded z-tooltip;
|
||||
@apply block;
|
||||
}
|
||||
|
||||
@@ -32,9 +32,11 @@ import { IsaErrorHandler } from './providers/isa.error-handler';
|
||||
import { ScanAdapterModule, ScanAdapterService, ScanditScanAdapterModule } from '@adapter/scan';
|
||||
import { RootStateService } from './store/root-state.service';
|
||||
import * as Commands from './commands';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { UiIconModule, UI_ICON_CFG } from '@ui/icon';
|
||||
import { PreviewComponent } from './preview';
|
||||
import { NativeContainerService } from 'native-container';
|
||||
import { ShellModule } from '@shared/shell';
|
||||
import { MainComponent } from './main.component';
|
||||
|
||||
registerLocaleData(localeDe, localeDeExtra);
|
||||
registerLocaleData(localeDe, 'de', localeDeExtra);
|
||||
@@ -74,11 +76,12 @@ export function _notificationsHubOptionsFactory(config: Config, auth: AuthServic
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
declarations: [AppComponent, MainComponent],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
HttpClientModule,
|
||||
ShellModule.forRoot(),
|
||||
AppRoutingModule,
|
||||
AppSwaggerModule,
|
||||
AppDomainModule,
|
||||
@@ -103,31 +106,7 @@ export function _notificationsHubOptionsFactory(config: Config, auth: AuthServic
|
||||
ScanAdapterModule.forRoot(),
|
||||
ScanditScanAdapterModule.forRoot(),
|
||||
PlatformModule,
|
||||
UiIconModule.forRoot({
|
||||
aliases: [
|
||||
{ alias: 'd-account', name: 'account' },
|
||||
{ alias: 'd-no-account', name: 'package-variant-closed' },
|
||||
{ name: 'isa-audio', alias: 'AU' },
|
||||
{ name: 'isa-audio', alias: 'CAS' },
|
||||
{ name: 'isa-audio', alias: 'DL' },
|
||||
{ name: 'isa-audio', alias: 'KAS' },
|
||||
{ name: 'isa-hard-cover', alias: 'BUCH' },
|
||||
{ name: 'isa-hard-cover', alias: 'GEB' },
|
||||
{ name: 'isa-hard-cover', alias: 'HC' },
|
||||
{ name: 'isa-hard-cover', alias: 'KT' },
|
||||
{ name: 'isa-ebook', alias: 'EB' },
|
||||
{ name: 'isa-non-book', alias: 'GLO' },
|
||||
{ name: 'isa-non-book', alias: 'HDL' },
|
||||
{ name: 'isa-non-book', alias: 'NB' },
|
||||
{ name: 'isa-non-book', alias: 'SPL' },
|
||||
{ name: 'isa-calendar', alias: 'KA' },
|
||||
{ name: 'isa-scroll', alias: 'MA' },
|
||||
{ name: 'isa-software', alias: 'SW' },
|
||||
{ name: 'isa-soft-cover', alias: 'TB' },
|
||||
{ name: 'isa-video', alias: 'VI' },
|
||||
{ name: 'isa-news-paper', alias: 'ZS' },
|
||||
],
|
||||
}),
|
||||
UiIconModule.forRoot(),
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
@@ -156,6 +135,11 @@ export function _notificationsHubOptionsFactory(config: Config, auth: AuthServic
|
||||
useClass: IsaErrorHandler,
|
||||
},
|
||||
{ provide: LOCALE_ID, useValue: 'de-DE' },
|
||||
{
|
||||
provide: UI_ICON_CFG,
|
||||
useFactory: (config: Config) => config.get('@ui/icon'),
|
||||
deps: [Config],
|
||||
},
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
|
||||
@@ -2,9 +2,9 @@ import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { ApplicationProcess, ApplicationService } from '@core/application';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
import { NavigationService } from '@core/navigation';
|
||||
import { DomainCheckoutService } from '@domain/checkout';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { AppNavigationService } from '../app-navigation.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CanActivateProductGuard implements CanActivate {
|
||||
@@ -16,7 +16,7 @@ export class CanActivateProductGuard implements CanActivate {
|
||||
private readonly _applicationService: ApplicationService,
|
||||
private readonly _checkoutService: DomainCheckoutService,
|
||||
private readonly _environment: EnvironmentService,
|
||||
private readonly _navigationService: AppNavigationService,
|
||||
private readonly _navigationService: NavigationService,
|
||||
private readonly _router: Router
|
||||
) {}
|
||||
|
||||
|
||||
3
apps/isa-app/src/app/main.component.html
Normal file
3
apps/isa-app/src/app/main.component.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<shell-root>
|
||||
<router-outlet></router-outlet>
|
||||
</shell-root>
|
||||
10
apps/isa-app/src/app/main.component.ts
Normal file
10
apps/isa-app/src/app/main.component.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-main',
|
||||
templateUrl: 'main.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class MainComponent {
|
||||
constructor() {}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
// start:ng42.barrel
|
||||
export * from './shell.component';
|
||||
export * from './shell.module';
|
||||
// end:ng42.barrel
|
||||
@@ -1,88 +0,0 @@
|
||||
<div class="shell-header-wrapper">
|
||||
<shell-header [section]="section$ | async" (sectionChange)="setSection($event)">
|
||||
<a [routerLink]="['/kunde/dashboard']" routerLinkActive="active" class="dashboard-btn">
|
||||
<ui-icon icon="dashboard" size="26px"></ui-icon>
|
||||
</a>
|
||||
<button class="notifications-btn" [disabled]="(notificationCount$ | async) === 0" (click)="openNotifications()">
|
||||
<ui-icon icon="notification" size="26px"></ui-icon>
|
||||
<span class="notification-counter" *ngIf="notificationCount$ | async; let count">{{ count }}</span>
|
||||
</button>
|
||||
<button (click)="logout()" class="logout-btn">
|
||||
<span *ngIf="currentBranch$ | async; let currentBranch">{{ currentBranch.key | uppercase }}</span>
|
||||
<ui-icon icon="logout" size="26px"></ui-icon>
|
||||
</button>
|
||||
</shell-header>
|
||||
</div>
|
||||
<div class="shell-process-wrapper">
|
||||
<shell-process
|
||||
[label]="addProcessLabel$ | async"
|
||||
[canAddProcess]="canAddProcess$ | async"
|
||||
(addProcess)="addProcess(); processTabs?.last?.triggerAnimation()"
|
||||
>
|
||||
<shell-process-tab
|
||||
#processTabs
|
||||
(activateProcess)="activateProcess($event)"
|
||||
(closeProcess)="closeProcess($event)"
|
||||
(processAction)="processAction($event)"
|
||||
*ngFor="let process of processes$ | async; trackBy: trackByIdFn"
|
||||
[isActive]="(activatedProcessId$ | async) === process.id"
|
||||
[process]="process"
|
||||
></shell-process-tab>
|
||||
</shell-process>
|
||||
</div>
|
||||
<div class="main-wrapper">
|
||||
<main>
|
||||
<router-outlet></router-outlet>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<div class="shell-footer-wrapper">
|
||||
<shell-footer *ngIf="section$ | async; let section">
|
||||
<ng-container *ngIf="section === 'customer'">
|
||||
<a [routerLink]="productRoutePath$ | async" routerLinkActive="active">
|
||||
<ui-icon icon="catalog" size="30px"></ui-icon>
|
||||
Artikelsuche
|
||||
</a>
|
||||
<a [routerLink]="[customerBasePath$ | async, 'customer']" routerLinkActive="active">
|
||||
<ui-icon icon="customer" size="24px"></ui-icon>
|
||||
Kundensuche
|
||||
</a>
|
||||
<a *ifRole="'Store'" [routerLink]="[customerBasePath$ | async, 'goods', 'out']" routerLinkActive="active">
|
||||
<ui-icon icon="box_out" size="24px"></ui-icon>
|
||||
Warenausgabe
|
||||
</a>
|
||||
<a *ifRole="'CallCenter'" [routerLink]="customerOrdersPath$ | async" routerLinkActive="active">
|
||||
<ui-svg-icon icon="package-variant-closed" [size]="28"></ui-svg-icon>
|
||||
Kundenbestellungen
|
||||
</a>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="section === 'branch'">
|
||||
<a [routerLink]="['/filiale/assortment']" routerLinkActive="active">
|
||||
<ui-svg-icon icon="shape-outline" [size]="24"></ui-svg-icon>
|
||||
Sortiment
|
||||
</a>
|
||||
<a [routerLink]="['/filiale/task-calendar']" routerLinkActive="active">
|
||||
<ui-icon icon="calendar_check" size="24px"></ui-icon>
|
||||
Tätigkeitskalender
|
||||
</a>
|
||||
<a [routerLink]="['/filiale/goods/in']" routerLinkActive="active">
|
||||
<ui-icon icon="box_return" size="24px"></ui-icon>
|
||||
Abholfach
|
||||
</a>
|
||||
<a [routerLink]="[remissionUrl$ | async]" [queryParams]="remissionQueryParams$ | async" routerLinkActive="active">
|
||||
<ui-icon icon="documents_refresh" size="24px"></ui-icon>
|
||||
Remission
|
||||
</a>
|
||||
<a [routerLink]="['/filiale/package-inspection']" routerLinkActive="active" (click)="fetchAndOpenPackages()">
|
||||
<ui-svg-icon icon="clipboard-check-outline" [size]="24"></ui-svg-icon>
|
||||
Wareneingang
|
||||
</a>
|
||||
</ng-container>
|
||||
</shell-footer>
|
||||
</div>
|
||||
|
||||
<button *ngIf="isDevelopment" class="block absolute bottom-0 right-0 z-tooltip p-4 opacity-5" (click)="debugOpen = !debugOpen">
|
||||
<ui-svg-icon icon="bug-outline"></ui-svg-icon>
|
||||
</button>
|
||||
|
||||
<app-debug *ngIf="debugOpen" class="absolute inset-x-0 top-0 max-h-[calc(100vh-80px)]"></app-debug>
|
||||
@@ -1,59 +0,0 @@
|
||||
:host {
|
||||
@apply block relative min-h-screen;
|
||||
}
|
||||
|
||||
.main-wrapper {
|
||||
@apply fixed right-0 left-0 overflow-auto;
|
||||
top: 8.375rem;
|
||||
bottom: 5rem;
|
||||
}
|
||||
main {
|
||||
@apply w-full mx-auto max-w-desktop px-px-15 desktop:px-6 self-stretch;
|
||||
}
|
||||
|
||||
.shell-header-wrapper {
|
||||
@apply fixed top-0 left-0 right-0 bg-white;
|
||||
|
||||
shell-header {
|
||||
@apply w-full max-w-desktop px-px-15 desktop:px-6 mx-auto;
|
||||
}
|
||||
|
||||
button.notifications-btn {
|
||||
@apply relative;
|
||||
|
||||
.notification-counter {
|
||||
@apply absolute flex items-center justify-center top-2 right-px-3 text-sm rounded-full w-6 h-6 font-semibold;
|
||||
background-color: var(--shell-notification-counter-background);
|
||||
color: var(--shell-notification-counter-text);
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shell-process-wrapper {
|
||||
@apply fixed left-0 right-0 bg-white;
|
||||
top: 5.125rem;
|
||||
|
||||
shell-process {
|
||||
@apply w-full max-w-desktop px-px-15 desktop:px-6 mx-auto;
|
||||
height: 52px;
|
||||
}
|
||||
}
|
||||
|
||||
shell-process {
|
||||
height: 52px;
|
||||
grid-area: process;
|
||||
}
|
||||
|
||||
.shell-footer-wrapper {
|
||||
@apply fixed bottom-0 left-0 right-0 bg-white z-fixed shadow-card;
|
||||
|
||||
shell-footer {
|
||||
@apply w-full max-w-desktop px-px-15 desktop:px-6 mx-auto;
|
||||
|
||||
.active {
|
||||
@apply font-bold;
|
||||
color: var(--shell-footer-link-active);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,445 +0,0 @@
|
||||
// unit test ShellComponent with Spectator
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { ApplicationProcess, ApplicationService } from '@core/application';
|
||||
import { AuthModule, AuthService } from '@core/auth';
|
||||
import { Config } from '@core/config';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { DomainAvailabilityService } from '@domain/availability';
|
||||
import { DomainDashboardService } from '@domain/isa';
|
||||
import { NotificationsHub } from '@hub/notifications';
|
||||
import { ModalNotificationsComponent } from '@modal/notifications';
|
||||
import { Spectator, createComponentFactory, SpyObject, createSpyObject } from '@ngneat/spectator';
|
||||
import { DashboardComponent } from '@page/dashboard';
|
||||
import { ShellFooterComponent } from '@shell/footer';
|
||||
import { ShellHeaderComponent } from '@shell/header';
|
||||
import { ShellProcessComponent, ShellProcessTabComponent } from '@shell/process';
|
||||
import { IconRegistry, UiIconComponent, UiIconModule } from '@ui/icon';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { EnvelopeDTO, MessageBoardItemDTO } from 'apps/hub/notifications/src/lib/defs';
|
||||
import { MockComponent } from 'ng-mocks';
|
||||
import { of } from 'rxjs';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { ShellComponent } from './shell.component';
|
||||
import { WrongDestinationModalService } from 'apps/page/package-inspection/src/lib/components/wrong-destination-modal/wrong-destination-modal.service';
|
||||
|
||||
// DummyComponent Class
|
||||
@Component({
|
||||
selector: 'dummy-component',
|
||||
template: '<div></div>',
|
||||
})
|
||||
class DummyComponent {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
describe('ShellComponent', () => {
|
||||
let spectator: Spectator<ShellComponent>;
|
||||
let applicationServiceMock: SpyObject<ApplicationService>;
|
||||
let modalServiceMock: SpyObject<UiModalService>;
|
||||
let notificationsHubMock: SpyObject<NotificationsHub>;
|
||||
let router: Router;
|
||||
let breadcrumbServiceMock: SpyObject<BreadcrumbService>;
|
||||
let authServiceMock: SpyObject<AuthService>;
|
||||
|
||||
const createComponent = createComponentFactory({
|
||||
component: ShellComponent,
|
||||
imports: [
|
||||
UiIconModule,
|
||||
RouterTestingModule.withRoutes([
|
||||
{ path: 'kunde', component: DummyComponent },
|
||||
{ path: 'kunde/dashboard', component: DashboardComponent },
|
||||
]),
|
||||
AuthModule,
|
||||
],
|
||||
declarations: [
|
||||
MockComponent(ShellHeaderComponent),
|
||||
MockComponent(ShellFooterComponent),
|
||||
MockComponent(ShellProcessComponent),
|
||||
MockComponent(ShellProcessTabComponent),
|
||||
],
|
||||
mocks: [
|
||||
BreadcrumbService,
|
||||
DomainAvailabilityService,
|
||||
AuthService,
|
||||
DomainDashboardService,
|
||||
Config,
|
||||
WrongDestinationModalService,
|
||||
IconRegistry,
|
||||
],
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
applicationServiceMock = createSpyObject(ApplicationService);
|
||||
applicationServiceMock.getSection$.and.returnValue(of('customer'));
|
||||
applicationServiceMock.getProcesses$.and.returnValue(of([]));
|
||||
applicationServiceMock.getProcessById$.and.returnValue(of({ id: 4000 }));
|
||||
applicationServiceMock.getActivatedProcessId$.and.returnValue(of(undefined));
|
||||
applicationServiceMock.getLastActivatedProcessWithSectionAndType$.and.returnValue(of({}));
|
||||
applicationServiceMock.getLastActivatedProcessWithSection$.and.returnValue(of({}));
|
||||
|
||||
notificationsHubMock = createSpyObject(NotificationsHub);
|
||||
notificationsHubMock.notifications$ = of({});
|
||||
|
||||
modalServiceMock = createSpyObject(UiModalService);
|
||||
|
||||
authServiceMock = createSpyObject(AuthService);
|
||||
|
||||
spectator = createComponent({
|
||||
providers: [
|
||||
{ provide: ApplicationService, useValue: applicationServiceMock },
|
||||
{ provide: NotificationsHub, useValue: notificationsHubMock },
|
||||
{ provide: UiModalService, useValue: modalServiceMock },
|
||||
{ provide: AuthService, useValue: authServiceMock },
|
||||
],
|
||||
});
|
||||
|
||||
breadcrumbServiceMock = spectator.inject(BreadcrumbService);
|
||||
router = spectator.inject(Router);
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(spectator.component).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('shell-header', () => {
|
||||
it('should call setSection() on sectionChange event with the section argument', () => {
|
||||
spyOn(spectator.component, 'setSection');
|
||||
spectator.triggerEventHandler('shell-header', 'sectionChange', 'branch');
|
||||
expect(spectator.component.setSection).toHaveBeenCalledWith('branch');
|
||||
});
|
||||
|
||||
it('should render the header buttons', () => {
|
||||
// Test verhält sich anders, wenn die größe des Browserfensters kleiner ist als 640px, da
|
||||
// die Buttons dann unsichtbar werden und ins Drei-Punkt Menü verschoben werden.
|
||||
if (document.body.clientWidth > 639) {
|
||||
expect(spectator.query('shell-header .notifications-btn')).toBeVisible();
|
||||
expect(spectator.query('shell-header .dashboard-btn')).toBeVisible();
|
||||
expect(spectator.query('shell-header .logout-btn')).toBeVisible();
|
||||
} else {
|
||||
expect(spectator.query('shell-header .notifications-btn')).not.toBeVisible();
|
||||
expect(spectator.query('shell-header .dashboard-btn')).not.toBeVisible();
|
||||
expect(spectator.query('shell-header .logout-btn')).not.toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
it('should have a anchor tag which navigates to /kunde/dashboard', () => {
|
||||
const anchor = spectator.query('shell-header a');
|
||||
expect(anchor).toHaveAttribute('href', '/kunde/dashboard');
|
||||
});
|
||||
});
|
||||
|
||||
describe('shell-process', () => {
|
||||
it('should call addProcess() on addProcess event', () => {
|
||||
spyOn(spectator.component, 'addProcess');
|
||||
spectator.triggerEventHandler('shell-process', 'addProcess', undefined);
|
||||
expect(spectator.component.addProcess).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('shell-process-tab', () => {
|
||||
it('should render for each process', () => {
|
||||
const processes = [{}, {}, {}];
|
||||
applicationServiceMock.getSection$.and.returnValue(of('customer'));
|
||||
applicationServiceMock.getProcesses$.and.returnValue(of(processes));
|
||||
spectator.detectComponentChanges();
|
||||
expect(spectator.queryAll('shell-process-tab')).toHaveLength(processes.length);
|
||||
});
|
||||
|
||||
it('should call activateProcess() on activateProcess event', () => {
|
||||
const processes = [{ id: 1 }];
|
||||
|
||||
applicationServiceMock.getProcesses$.and.returnValue(of(processes));
|
||||
spectator.detectComponentChanges();
|
||||
|
||||
spyOn(spectator.component, 'activateProcess');
|
||||
spectator.triggerEventHandler('shell-process-tab', 'activateProcess', processes[0].id);
|
||||
expect(spectator.component.activateProcess).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it('should call closeProcess() on closeProcess event', () => {
|
||||
const processes = [{ id: 1 }];
|
||||
|
||||
applicationServiceMock.getProcesses$.and.returnValue(of(processes));
|
||||
spectator.detectComponentChanges();
|
||||
|
||||
spyOn(spectator.component, 'closeProcess');
|
||||
spectator.triggerEventHandler('shell-process-tab', 'closeProcess', processes[0].id);
|
||||
expect(spectator.component.closeProcess).toHaveBeenCalledWith(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('shell-footer', () => {
|
||||
it('should render when section is set', () => {
|
||||
applicationServiceMock.getSection$.and.returnValue(of('customer'));
|
||||
spectator.detectComponentChanges();
|
||||
expect(spectator.query('shell-footer')).toBeVisible();
|
||||
});
|
||||
|
||||
it('should not render when section is undefined', () => {
|
||||
applicationServiceMock.getSection$.and.returnValue(of(undefined));
|
||||
spectator.detectComponentChanges();
|
||||
expect(spectator.query('shell-footer')).not.toBeVisible();
|
||||
});
|
||||
|
||||
xit('should display the menu items for section customer', () => {
|
||||
applicationServiceMock.getSection$.and.returnValue(of('customer'));
|
||||
spectator.component.customerBasePath$ = of('/kunde/1');
|
||||
spectator.detectComponentChanges();
|
||||
|
||||
authServiceMock.hasRole.and.returnValue(true);
|
||||
|
||||
const anchors = spectator.queryAll('shell-footer a');
|
||||
expect(anchors[0]).toHaveText('Artikelsuche');
|
||||
expect(anchors[0]).toHaveAttribute('href', '/kunde/1/product');
|
||||
expect(anchors[1]).toHaveText('Kundensuche');
|
||||
expect(anchors[1]).toHaveAttribute('href', '/kunde/1/customer');
|
||||
expect(anchors[2]).toHaveText('Warenausgabe');
|
||||
expect(anchors[2]).toHaveAttribute('href', '/kunde/1/goods/out');
|
||||
});
|
||||
|
||||
it('should display the menu items for section branch', () => {
|
||||
applicationServiceMock.getSection$.and.returnValue(of('branch'));
|
||||
spectator.detectComponentChanges();
|
||||
|
||||
const anchors = spectator.queryAll('shell-footer a');
|
||||
expect(anchors[0]).toHaveText('Sortiment');
|
||||
expect(anchors[0]).toHaveAttribute('href', '/filiale/assortment');
|
||||
expect(anchors[1]).toHaveText('Tätigkeitskalender');
|
||||
expect(anchors[1]).toHaveAttribute('href', '/filiale/task-calendar');
|
||||
expect(anchors[2]).toHaveText('Abholfach');
|
||||
expect(anchors[2]).toHaveAttribute('href', '/filiale/goods/in');
|
||||
expect(anchors[3]).toHaveText('Remission');
|
||||
expect(anchors[3]).toHaveAttribute('href', '/filiale/remission');
|
||||
expect(anchors[4]).toHaveText('Wareneingang');
|
||||
expect(anchors[4]).toHaveAttribute('href', '/filiale/package-inspection');
|
||||
});
|
||||
});
|
||||
|
||||
describe('activatedProcessId$', () => {
|
||||
it('should call _appService.getActivatedProcessId$() and return its value', async () => {
|
||||
applicationServiceMock.getActivatedProcessId$.and.returnValue(of(1));
|
||||
const processId = await spectator.component.activatedProcessId$.pipe(first()).toPromise();
|
||||
expect(processId).toBe(1);
|
||||
expect(applicationServiceMock.getActivatedProcessId$).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('section$', () => {
|
||||
it('should call _appService.getSection$() and return its value', async () => {
|
||||
applicationServiceMock.getSection$.and.returnValue(of('branch'));
|
||||
const section = await spectator.component.section$.pipe(first()).toPromise();
|
||||
expect(section).toBe('branch');
|
||||
expect(applicationServiceMock.getSection$).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('processes$', () => {
|
||||
it('should call _appService.processes$() and return its value', async () => {
|
||||
applicationServiceMock.getProcesses$.and.returnValue(of([{}, {}]));
|
||||
const processes = await spectator.component.processes$.pipe(first()).toPromise();
|
||||
expect(processes).toHaveLength(2);
|
||||
expect(applicationServiceMock.getProcesses$).toHaveBeenCalledWith('customer');
|
||||
});
|
||||
});
|
||||
|
||||
describe('remissionProcess$', () => {
|
||||
it('should call _appService.getProcessById$() with Remission Id and return its value', async () => {
|
||||
applicationServiceMock.getProcessById$.and.returnValue(of({ id: 4000 }));
|
||||
await spectator.component.remissionProcess$.pipe(first()).toPromise();
|
||||
expect(applicationServiceMock.getProcessById$).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('remissionUrl$', () => {
|
||||
it('should return the correct url if process.data.active is available', async () => {
|
||||
const process = {
|
||||
id: 4000,
|
||||
data: {
|
||||
active: 9999,
|
||||
},
|
||||
};
|
||||
applicationServiceMock.getProcessById$.and.returnValue(of(process));
|
||||
const url = await spectator.component.remissionUrl$.pipe(first()).toPromise();
|
||||
expect(url).toBe('/filiale/remission/9999/list');
|
||||
});
|
||||
|
||||
it('should return the correct url if process.data.active is not available', async () => {
|
||||
const process = {
|
||||
id: 4000,
|
||||
data: {},
|
||||
};
|
||||
applicationServiceMock.getProcessById$.and.returnValue(of(process));
|
||||
const url = await spectator.component.remissionUrl$.pipe(first()).toPromise();
|
||||
expect(url).toBe('/filiale/remission');
|
||||
});
|
||||
});
|
||||
|
||||
describe('remissionQueryParams$', () => {
|
||||
it('should return the correct queryParams if process.data.active and process.data.queryParams are available', async () => {
|
||||
const process = {
|
||||
id: 4000,
|
||||
data: {
|
||||
active: 9999,
|
||||
queryParams: { filter: 'test' },
|
||||
},
|
||||
};
|
||||
applicationServiceMock.getProcessById$.and.returnValue(of(process));
|
||||
const queryParams = await spectator.component.remissionQueryParams$.pipe(first()).toPromise();
|
||||
expect(queryParams).toEqual(process.data.queryParams);
|
||||
});
|
||||
|
||||
it('should return the correct queryParams if process.data.active and process.data.queryParams are not available', async () => {
|
||||
const process = {
|
||||
id: 4000,
|
||||
data: {},
|
||||
};
|
||||
applicationServiceMock.getProcessById$.and.returnValue(of(process));
|
||||
const queryParams = await spectator.component.remissionQueryParams$.pipe(first()).toPromise();
|
||||
expect(queryParams).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setSection()', () => {
|
||||
it('should call _appService.setSection() with the argument section', async () => {
|
||||
await spectator.component.setSection('customer');
|
||||
expect(applicationServiceMock.setSection).toHaveBeenCalledWith('customer');
|
||||
});
|
||||
|
||||
it('should call activateProcess if getLastActivatedProcessWithSection returns a value', async () => {
|
||||
applicationServiceMock.getLastActivatedProcessWithSection$.and.returnValue(of({ id: 1 }));
|
||||
spyOn(spectator.component, 'activateProcess');
|
||||
await spectator.component.setSection('customer');
|
||||
expect(spectator.component.activateProcess).toHaveBeenCalledWith(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('logout()', () => {
|
||||
it('should call _authService.logout()', () => {
|
||||
spectator.component.logout();
|
||||
expect(authServiceMock.logout).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('addProcess()', () => {
|
||||
it('should call navigate to /kunde/{timestamp}/product', () => {
|
||||
spyOn(router, 'navigate');
|
||||
spyOn(Date, 'now').and.returnValue(123);
|
||||
spectator.component.addProcess();
|
||||
expect(router.navigate).toHaveBeenCalledWith(['/kunde', 123, 'product']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('closeProcess()', () => {
|
||||
it('should call _appService.removeProcess() with the processId argument', () => {
|
||||
const processes = [{}, {}, {}];
|
||||
applicationServiceMock.getSection$.and.returnValue(of('customer'));
|
||||
applicationServiceMock.getProcesses$.and.returnValue(of(processes));
|
||||
spectator.component.closeProcess(1);
|
||||
expect(applicationServiceMock.removeProcess).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it('should navigate to kunde/dashboard if no process is available', async () => {
|
||||
spyOn(router, 'navigate');
|
||||
applicationServiceMock.getSection$.and.returnValue(of('customer'));
|
||||
applicationServiceMock.getProcesses$.and.returnValue(of([]));
|
||||
spectator.detectComponentChanges();
|
||||
await spectator.component.closeProcess(1);
|
||||
expect(router.navigate).toHaveBeenCalledWith(['/kunde', 'dashboard']);
|
||||
});
|
||||
|
||||
it('should not navigate to kunde/dashboard if processes are available', async () => {
|
||||
spyOn(router, 'navigate');
|
||||
const processes = [
|
||||
{ id: 1, name: 'test', section: 'customer' },
|
||||
{ id: 2, name: 'test', section: 'customer' },
|
||||
];
|
||||
|
||||
applicationServiceMock.getLastActivatedProcessWithSection$.and.returnValue(of({}));
|
||||
applicationServiceMock.getSection$.and.returnValue(of('customer'));
|
||||
applicationServiceMock.getProcesses$.and.returnValue(of(processes));
|
||||
await spectator.component.closeProcess(1);
|
||||
expect(router.navigate).not.toHaveBeenCalledWith(['/kunde', 'dashboard']);
|
||||
});
|
||||
|
||||
it('should activate the next process when it was not the last process', async () => {
|
||||
spyOn(spectator.component, 'activateProcess');
|
||||
|
||||
applicationServiceMock.getLastActivatedProcessWithSection$.and.returnValue(
|
||||
of({
|
||||
id: 2,
|
||||
name: 'test',
|
||||
section: 'customer',
|
||||
activated: 2,
|
||||
})
|
||||
);
|
||||
|
||||
const processes = [
|
||||
{ id: 1, name: 'test', section: 'customer', activated: 1 },
|
||||
{ id: 2, name: 'test', section: 'customer', activated: 2 },
|
||||
];
|
||||
applicationServiceMock.getSection$.and.returnValue(of('customer'));
|
||||
applicationServiceMock.getProcesses$.and.returnValue(of(processes));
|
||||
await spectator.component.closeProcess(1);
|
||||
|
||||
expect(spectator.component.activateProcess).toHaveBeenCalledWith(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('activateProcess()', () => {
|
||||
it('should get the last activated breadcrumb by key and if it is defined it navigates to its path with queryParams', async () => {
|
||||
const crumb = { path: '/kunde/product', params: { id: 1 } };
|
||||
spyOn(router, 'navigate');
|
||||
breadcrumbServiceMock.getLastActivatedBreadcrumbByKey$.and.returnValue(of(crumb));
|
||||
|
||||
await spectator.component.activateProcess(1);
|
||||
expect(router.navigate).toHaveBeenCalledWith([crumb.path], { queryParams: crumb.params });
|
||||
});
|
||||
|
||||
it('should navigate to /kunde if no breadcrumb for this process exists', async () => {
|
||||
breadcrumbServiceMock.getLastActivatedBreadcrumbByKey$.and.returnValue(of(undefined));
|
||||
spyOn(router, 'navigate');
|
||||
|
||||
await spectator.component.activateProcess(1);
|
||||
expect(router.navigate).toHaveBeenCalledWith(['/kunde', 1, 'product']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('processAction()', () => {
|
||||
it('should navigate to cart when process type is cart', () => {
|
||||
spyOn(router, 'navigate');
|
||||
|
||||
const process: ApplicationProcess = { id: 1, name: 'Vorgang', section: 'customer', type: 'cart' };
|
||||
spectator.component.processAction(process);
|
||||
expect(router.navigate).toHaveBeenCalledWith(['/kunde', process.id, 'cart']);
|
||||
});
|
||||
|
||||
it('should not navigate to when process type is not cart', () => {
|
||||
spyOn(router, 'navigate');
|
||||
|
||||
const process: ApplicationProcess = { id: 1, name: 'Vorgang', section: 'customer', type: 'goods-out' };
|
||||
spectator.component.processAction(process);
|
||||
expect(router.navigate).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('openNotifications()', () => {
|
||||
it('should call modalService.open() with the ModalNotificationComponent', async () => {
|
||||
const notifications: EnvelopeDTO<MessageBoardItemDTO[]> = {
|
||||
data: [{}, {}, {}],
|
||||
};
|
||||
|
||||
spectator.component.notifications$ = of(notifications);
|
||||
|
||||
await spectator.component.openNotifications();
|
||||
expect(modalServiceMock.open).toHaveBeenCalledWith({
|
||||
content: ModalNotificationsComponent,
|
||||
data: notifications,
|
||||
config: {
|
||||
showScrollbarY: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,209 +0,0 @@
|
||||
import { Component, ChangeDetectionStrategy, ViewChildren, QueryList, TrackByFunction, NgZone } from '@angular/core';
|
||||
import { ApplicationProcess, ApplicationService } from '@core/application';
|
||||
import { first, map, shareReplay, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { NotificationsHub } from '@hub/notifications';
|
||||
import { ModalNotificationsComponent } from '@modal/notifications';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { Router } from '@angular/router';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { combineLatest } from 'rxjs';
|
||||
import { AuthService } from '@core/auth';
|
||||
import { DomainAvailabilityService } from '@domain/availability';
|
||||
import { ShellProcessTabComponent } from '@shell/process';
|
||||
import { Config } from '@core/config';
|
||||
import { WrongDestinationModalService } from 'apps/page/package-inspection/src/lib/components/wrong-destination-modal/wrong-destination-modal.service';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
import { AppNavigationService } from '../app-navigation.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-shell',
|
||||
templateUrl: 'shell.component.html',
|
||||
styleUrls: ['shell.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ShellComponent {
|
||||
isDevelopment = Boolean(this._config.get('debug'));
|
||||
|
||||
debugOpen = false;
|
||||
|
||||
@ViewChildren('processTabs')
|
||||
readonly processTabs: QueryList<ShellProcessTabComponent>;
|
||||
|
||||
notifications$ = this._notificationsHub.notifications$;
|
||||
|
||||
notificationCount$ = this.notifications$.pipe(map((message) => message?.data?.length));
|
||||
|
||||
get activatedProcessId$() {
|
||||
return this._appService.getActivatedProcessId$().pipe(
|
||||
tap((activatedProcessId) => {
|
||||
this.processTabs?.find((process) => process?.process?.id === activatedProcessId && !process?.isActive)?.slideIntoView();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
customerBasePath$ = this.activatedProcessId$.pipe(
|
||||
switchMap((processId) => this._appService.getProcessById$(processId)),
|
||||
map((process) => {
|
||||
if (!!process && process.section === 'customer' && process.type !== 'cart-checkout') {
|
||||
// Übernehme aktiven Prozess
|
||||
return `/kunde/${process.id}`;
|
||||
} else {
|
||||
// Über Guards wird ein neuer Prozess erstellt
|
||||
return '/kunde';
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
productRoutePath$ = this.activatedProcessId$.pipe(
|
||||
switchMap((processId) => this._appService.getProcessById$(processId)),
|
||||
map((process) => {
|
||||
if (!!process && process.section === 'customer' && process.type !== 'cart-checkout') {
|
||||
// Übernehme aktiven Prozess
|
||||
return this._navigationService.getArticleSearchBasePath(process.id);
|
||||
} else {
|
||||
// Über Guards wird ein neuer Prozess erstellt
|
||||
return this._navigationService.getArticleSearchBasePath();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
customerOrdersPath$ = this.customerBasePath$.pipe(
|
||||
map((basePath) => {
|
||||
if (this.isTablet) {
|
||||
return [basePath, 'order'];
|
||||
} else {
|
||||
return [basePath, 'order', { outlets: { main: null, left: 'search', right: 'filter' } }];
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
get section$() {
|
||||
return this._appService.getSection$().pipe(shareReplay());
|
||||
}
|
||||
|
||||
get processes$() {
|
||||
return this.section$.pipe(switchMap((section) => this._appService.getProcesses$(section)));
|
||||
}
|
||||
|
||||
get remissionProcess$() {
|
||||
return this._appService.getProcessById$(this._config.get('process.ids.remission'));
|
||||
}
|
||||
|
||||
get remissionUrl$() {
|
||||
return this.remissionProcess$.pipe(
|
||||
map((process) => (process?.data?.active ? `/filiale/remission/${process.data.active}/list` : '/filiale/remission'))
|
||||
);
|
||||
}
|
||||
|
||||
get remissionQueryParams$() {
|
||||
return this.remissionProcess$.pipe(
|
||||
map((process) => (process?.data?.active && process?.data?.queryParams ? process.data.queryParams : {}))
|
||||
);
|
||||
}
|
||||
|
||||
get addProcessLabel$() {
|
||||
return combineLatest([this.section$, this.processes$]).pipe(
|
||||
map(([section, processes]) => (section === 'customer' && processes.length === 0 ? 'VORGANG STARTEN' : ''))
|
||||
);
|
||||
}
|
||||
|
||||
get canAddProcess$() {
|
||||
return this.section$.pipe(map((section) => section === 'customer'));
|
||||
}
|
||||
|
||||
get currentBranch$() {
|
||||
return this._availabilityService.getDefaultBranch();
|
||||
}
|
||||
|
||||
get isTablet() {
|
||||
return this._environment.isTablet();
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly _appService: ApplicationService,
|
||||
private readonly _config: Config,
|
||||
private readonly _notificationsHub: NotificationsHub,
|
||||
private readonly _modal: UiModalService,
|
||||
private readonly _router: Router,
|
||||
private readonly _breadcrumbService: BreadcrumbService,
|
||||
private readonly _authService: AuthService,
|
||||
private readonly _availabilityService: DomainAvailabilityService,
|
||||
private readonly _zone: NgZone,
|
||||
private readonly _wrongDestinationModalService: WrongDestinationModalService,
|
||||
private readonly _environment: EnvironmentService,
|
||||
private readonly _navigationService: AppNavigationService
|
||||
) {}
|
||||
|
||||
async setSection(section: 'customer' | 'branch') {
|
||||
this._appService.setSection(section);
|
||||
|
||||
const lastProcessId = (await this._appService.getLastActivatedProcessWithSection$(section).pipe(first()).toPromise())?.id;
|
||||
if (lastProcessId) {
|
||||
this.activateProcess(lastProcessId);
|
||||
} else {
|
||||
this._router.navigate([section === 'customer' ? '/kunde' : '/filiale']);
|
||||
}
|
||||
}
|
||||
|
||||
// Process werden über Guards erstellt und aktiviert. An dieser Stelle wird nur navigiert
|
||||
async addProcess() {
|
||||
const processId = Date.now();
|
||||
await this._navigationService.navigateToProductSearch({ processId });
|
||||
}
|
||||
|
||||
async activateProcess(activatedProcessId: number) {
|
||||
try {
|
||||
const latestCrumb = await this._breadcrumbService?.getLastActivatedBreadcrumbByKey$(activatedProcessId)?.pipe(take(1)).toPromise();
|
||||
await this._zone.run(async () => {
|
||||
if (latestCrumb) {
|
||||
if (latestCrumb.path instanceof Array) {
|
||||
await this._router.navigate(latestCrumb.path, { queryParams: latestCrumb.params });
|
||||
} else {
|
||||
await this._router.navigate([latestCrumb.path], { queryParams: latestCrumb.params });
|
||||
}
|
||||
} else {
|
||||
await this._navigationService.navigateToProductSearch({ processId: activatedProcessId });
|
||||
}
|
||||
});
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
async closeProcess(processId: number) {
|
||||
this._appService.removeProcess(processId);
|
||||
|
||||
const processes = await this.processes$.pipe(first()).toPromise();
|
||||
if (processes.length === 0) {
|
||||
await this._router.navigate(['/kunde', 'dashboard']);
|
||||
return;
|
||||
}
|
||||
|
||||
const section = await this.section$.pipe(first()).toPromise();
|
||||
const lastActivatedProcess = await this._appService.getLastActivatedProcessWithSection$(section).pipe(first()).toPromise();
|
||||
this.activateProcess(lastActivatedProcess?.id);
|
||||
}
|
||||
|
||||
processAction(process: ApplicationProcess) {
|
||||
if (process?.type === 'cart') {
|
||||
this._router.navigate(['/kunde', process.id, 'cart']);
|
||||
}
|
||||
}
|
||||
|
||||
async logout() {
|
||||
await this._authService.logout();
|
||||
}
|
||||
|
||||
async openNotifications() {
|
||||
const notifications = await this.notifications$.pipe(first()).toPromise();
|
||||
this._modal.open({
|
||||
content: ModalNotificationsComponent,
|
||||
data: notifications,
|
||||
config: {
|
||||
showScrollbarY: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
trackByIdFn: TrackByFunction<ApplicationProcess> = (_, process) => process.id;
|
||||
|
||||
fetchAndOpenPackages = () => this._wrongDestinationModalService.fetchAndOpen();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
|
||||
import { ShellHeaderModule } from '@shell/header';
|
||||
import { ShellProcessModule } from '@shell/process';
|
||||
import { ShellFooterModule } from '@shell/footer';
|
||||
|
||||
import { ShellComponent } from './shell.component';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AuthModule } from '@core/auth';
|
||||
import { DebugComponent } from '../debug/debug.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule,
|
||||
CommonModule,
|
||||
ShellHeaderModule,
|
||||
ShellProcessModule,
|
||||
ShellFooterModule,
|
||||
UiIconModule,
|
||||
OverlayModule,
|
||||
AuthModule,
|
||||
DebugComponent,
|
||||
],
|
||||
exports: [ShellComponent],
|
||||
declarations: [ShellComponent],
|
||||
providers: [],
|
||||
})
|
||||
export class ShellModule {}
|
||||
@@ -1,20 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Material Symbols Outlined';
|
||||
font-style: normal;
|
||||
font-weight: 100 700;
|
||||
src: url(./materials-icons-outlined.woff2) format('woff2');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Material Symbols Rounded';
|
||||
font-style: normal;
|
||||
font-weight: 100 700;
|
||||
src: url(./materials-icons-rounded.woff2) format('woff2');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Material Symbols Sharp';
|
||||
font-style: normal;
|
||||
font-weight: 100 700;
|
||||
src: url(./materials-icons-sharp.woff2) format('woff2');
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -8,9 +8,8 @@
|
||||
},
|
||||
"@core/auth": {
|
||||
"issuer": "https://sso-test.paragon-data.de",
|
||||
"clientId": "hug-isa",
|
||||
"responseType": "id_token token",
|
||||
"oidc": true,
|
||||
"clientId": "isa-client",
|
||||
"responseType": "code",
|
||||
"scope": "openid profile cmf_user isa-isa-webapi isa-checkout-webapi isa-cat-webapi isa-ava-webapi isa-crm-webapi isa-review-webapi isa-kpi-webapi isa-oms-webapi isa-nbo-webapi isa-print-webapi eis-service isa-inv-webapi isa-wws-webapi"
|
||||
},
|
||||
"@core/logger": {
|
||||
@@ -41,7 +40,7 @@
|
||||
"rootUrl": "https://filialinformationsystem-integration.paragon-systems.de/eiswebapi/v1"
|
||||
},
|
||||
"@swagger/remi": {
|
||||
"rootUrl": "https://isa-integration.paragon-data.net/inv/v1"
|
||||
"rootUrl": "https://isa-integration.paragon-data.net/inv/v6"
|
||||
},
|
||||
"@swagger/wws": {
|
||||
"rootUrl": "https://isa-integration.paragon-data.net/wws/v1"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -41,10 +41,10 @@
|
||||
"rootUrl": "https://filialinformationsystem.paragon-systems.de/eiswebapi/v1"
|
||||
},
|
||||
"@swagger/remi": {
|
||||
"rootUrl": "https://isa.paragon-systems.de/inv/v1"
|
||||
"rootUrl": "https://isa.paragon-systems.de/inv/v6"
|
||||
},
|
||||
"@swagger/wws": {
|
||||
"rootUrl": "https://isa.paragon-data.net/wws/v1"
|
||||
"rootUrl": "https://isa.paragon-systems.de/wws/v1"
|
||||
},
|
||||
"hubs": {
|
||||
"notifications": {
|
||||
@@ -69,6 +69,6 @@
|
||||
},
|
||||
"checkForUpdates": 3600000,
|
||||
"licence": {
|
||||
"scandit": ""
|
||||
"scandit": "AfHi/mY+RbwJD5nC7SuWn3I14pFUOfSbQ2QG//4aV3zWQjwix30kHqsqraA8ZiipDBql8YlwIyV6VPBMUiAX4s9YHDxHHsWwq2BUB3ImzDEcU1jmMH/5yakGUYpCQ68D0iZ8SG9sS0QBb3iFdCHc1r9DFr1cMTxM7zOvb/AUoIVmieHZXnx9ioUgCvczsLiuX3hwvTW3lhbvJ4uUyqTWK4sWFVwoY4AIWSFrPwwrkV2DksMKT5fMJT3GWgPypvTIGwWvpRfLWwKlc1Z3ckyb84khsnaWD2wr+hdgu/K8YIMmgGszm5KIZ/G05YfDNZtQ4jby+5RZvQwWR8rxM35rJgf73OkMSpuL9jw3T0TTAlvpkGRLzVVuCw9VjlBLqfPNEZ6VsEwFuAla9IYUvFHCsjypg2J6UpxHXrTYmbsSu5Jm8frVfS5znPPTO9D/4rF6ZVv2PxY9PgUgJUvwMa/VMc/nse3RRRf8RGT4rUItfJDFO8pujD76vVEWq/KixQRoMdLgDLyxhsFVftkxqhZhyEfFZzsEy49LSojJ28vpHpBWLeCQBmnZ7JZ4C5yOQiqSQV/assBq2zJN2q+vCDp8qy5j1rED1SX5Ec7JpgpgnU4chLIf5Zn7bP/hNGT3pEYBuXeDXXN8ke1pcc3fc3m0FysDG0o56XVCUqImZ8Ezi8eujZciKDrWbtljhKTj7cnfuJx0sVHF6Bh5i4YfgA/Z+NL+MtH2EVIF67e6hEz6PWYTcoh3ybBaJfxb2FNvGJutNKg04GwMhYq6K2IddBt0fDiBt0SGM0oSBlUP3DKCUmXcf2a6ASbrcqv6Wz1jHt0pY4U8bEpg7qSbW3VDyvdPgyQ="
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
"rootUrl": "https://filialinformationsystem-staging.paragon-systems.de/eiswebapi/v1"
|
||||
},
|
||||
"@swagger/remi": {
|
||||
"rootUrl": "https://isa-staging.paragon-systems.de/inv/v1"
|
||||
"rootUrl": "https://isa-staging.paragon-systems.de/inv/v6"
|
||||
},
|
||||
"@swagger/wws": {
|
||||
"rootUrl": "https://isa-staging.paragon-systems.de/wws/v1"
|
||||
@@ -69,6 +69,6 @@
|
||||
},
|
||||
"checkForUpdates": 3600000,
|
||||
"licence": {
|
||||
"scandit": ""
|
||||
"scandit": "AfHi/mY+RbwJD5nC7SuWn3I14pFUOfSbQ2QG//4aV3zWQjwix30kHqsqraA8ZiipDBql8YlwIyV6VPBMUiAX4s9YHDxHHsWwq2BUB3ImzDEcU1jmMH/5yakGUYpCQ68D0iZ8SG9sS0QBb3iFdCHc1r9DFr1cMTxM7zOvb/AUoIVmieHZXnx9ioUgCvczsLiuX3hwvTW3lhbvJ4uUyqTWK4sWFVwoY4AIWSFrPwwrkV2DksMKT5fMJT3GWgPypvTIGwWvpRfLWwKlc1Z3ckyb84khsnaWD2wr+hdgu/K8YIMmgGszm5KIZ/G05YfDNZtQ4jby+5RZvQwWR8rxM35rJgf73OkMSpuL9jw3T0TTAlvpkGRLzVVuCw9VjlBLqfPNEZ6VsEwFuAla9IYUvFHCsjypg2J6UpxHXrTYmbsSu5Jm8frVfS5znPPTO9D/4rF6ZVv2PxY9PgUgJUvwMa/VMc/nse3RRRf8RGT4rUItfJDFO8pujD76vVEWq/KixQRoMdLgDLyxhsFVftkxqhZhyEfFZzsEy49LSojJ28vpHpBWLeCQBmnZ7JZ4C5yOQiqSQV/assBq2zJN2q+vCDp8qy5j1rED1SX5Ec7JpgpgnU4chLIf5Zn7bP/hNGT3pEYBuXeDXXN8ke1pcc3fc3m0FysDG0o56XVCUqImZ8Ezi8eujZciKDrWbtljhKTj7cnfuJx0sVHF6Bh5i4YfgA/Z+NL+MtH2EVIF67e6hEz6PWYTcoh3ybBaJfxb2FNvGJutNKg04GwMhYq6K2IddBt0fDiBt0SGM0oSBlUP3DKCUmXcf2a6ASbrcqv6Wz1jHt0pY4U8bEpg7qSbW3VDyvdPgyQ="
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -7,7 +7,6 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||||
<link href="/assets/fonts/fonts.css" rel="stylesheet" />
|
||||
<link href="/assets/icons/icons.css" rel="stylesheet" />
|
||||
<link rel="manifest" href="manifest.webmanifest" />
|
||||
<meta name="theme-color" content="#1976d2" />
|
||||
</head>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { Breadcrumb, BreadcrumbService } from '@core/breadcrumb';
|
||||
import { Config } from '@core/config';
|
||||
|
||||
@@ -13,10 +14,11 @@ export class AssortmentComponent implements OnInit {
|
||||
return this._config.get('process.ids.assortment');
|
||||
}
|
||||
|
||||
constructor(private _config: Config, private _breadcrumb: BreadcrumbService) {}
|
||||
constructor(private _config: Config, private _breadcrumb: BreadcrumbService, private _app: ApplicationService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.createBreadcrumbIfNotExists();
|
||||
this._app.setTitle('Sortiment');
|
||||
}
|
||||
|
||||
async createBreadcrumbIfNotExists(): Promise<void> {
|
||||
|
||||
@@ -5,8 +5,9 @@ import { EnvironmentService } from '@core/environment';
|
||||
import { DomainAvailabilityService, DomainInStockService } from '@domain/availability';
|
||||
import { ProductListItemDTO } from '@swagger/wws';
|
||||
import { DateAdapter } from '@ui/common';
|
||||
import { debounceTime, map, shareReplay, switchMap } from 'rxjs/operators';
|
||||
import { debounceTime, filter, map, shareReplay, switchMap } from 'rxjs/operators';
|
||||
import { PriceUpdateComponentStore } from '../price-update.component.store';
|
||||
import { ReplaySubject, combineLatest } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'page-price-update-item',
|
||||
@@ -16,8 +17,18 @@ import { PriceUpdateComponentStore } from '../price-update.component.store';
|
||||
providers: [DatePipe],
|
||||
})
|
||||
export class PriceUpdateItemComponent {
|
||||
private _item$ = new ReplaySubject<ProductListItemDTO>(1);
|
||||
|
||||
private _item: ProductListItemDTO;
|
||||
|
||||
@Input()
|
||||
item: ProductListItemDTO;
|
||||
get item() {
|
||||
return this._item;
|
||||
}
|
||||
set item(value) {
|
||||
this._item = value;
|
||||
this._item$.next(value);
|
||||
}
|
||||
|
||||
get publicationDate() {
|
||||
if (!!this.item?.product?.publicationDate) {
|
||||
@@ -40,21 +51,14 @@ export class PriceUpdateItemComponent {
|
||||
|
||||
defaultBranch$ = this._availability.getDefaultBranch();
|
||||
|
||||
inStock$ = this.defaultBranch$.pipe(
|
||||
inStock$ = combineLatest([this.defaultBranch$, this._item$]).pipe(
|
||||
debounceTime(100),
|
||||
switchMap(
|
||||
(defaultBranch) =>
|
||||
this._stockService.getInStock$({
|
||||
itemId: Number(this.item?.product?.catalogProductNumber),
|
||||
branchId: defaultBranch?.id,
|
||||
})
|
||||
// TODO: Bugfixing INSTOCK
|
||||
// .pipe(
|
||||
// map((instock) => {
|
||||
// this.item.product.ean === '9783551775559' ? console.log({ item: this.item, instock }) : '';
|
||||
// return instock;
|
||||
// })
|
||||
// )
|
||||
filter(([defaultBranch, item]) => !!defaultBranch && !!item),
|
||||
switchMap(([defaultBranch, item]) =>
|
||||
this._stockService.getInStock$({
|
||||
itemId: Number(item?.product?.catalogProductNumber),
|
||||
branchId: defaultBranch?.id,
|
||||
})
|
||||
),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { Config } from '@core/config';
|
||||
import { provideComponentStore } from '@ngrx/component-store';
|
||||
import { ShellFilterOverlayComponent } from '@shell/filter-overlay';
|
||||
import { SharedFilterOverlayComponent } from '@shared/components/filter-overlay';
|
||||
import { UiFilter, UiFilterComponent } from '@ui/filter';
|
||||
import { PriceUpdateComponentStore } from './price-update.component.store';
|
||||
import { combineLatest, Subject, Subscription } from 'rxjs';
|
||||
@@ -26,8 +26,8 @@ export class PriceUpdateComponent implements OnInit {
|
||||
|
||||
hint$ = new Subject<string>();
|
||||
|
||||
@ViewChild(ShellFilterOverlayComponent)
|
||||
filterOverlay: ShellFilterOverlayComponent;
|
||||
@ViewChild(SharedFilterOverlayComponent)
|
||||
filterOverlay: SharedFilterOverlayComponent;
|
||||
|
||||
/**
|
||||
* Zeigt die liste an, wenn entweder keine items geladen werden oder wenn items geladen wurden
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ShellFilterOverlayModule } from '@shell/filter-overlay';
|
||||
import { SharedFilterOverlayModule } from '@shared/components/filter-overlay';
|
||||
import { UiFilterNextModule } from '@ui/filter';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
@@ -8,7 +8,7 @@ import { PriceUpdateListModule } from './price-update-list';
|
||||
import { PriceUpdateComponent } from './price-update.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, PriceUpdateListModule, UiIconModule, UiFilterNextModule, ShellFilterOverlayModule, UiSpinnerModule],
|
||||
imports: [CommonModule, PriceUpdateListModule, UiIconModule, UiFilterNextModule, SharedFilterOverlayModule, UiSpinnerModule],
|
||||
exports: [PriceUpdateComponent],
|
||||
declarations: [PriceUpdateComponent],
|
||||
providers: [],
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
|
||||
<div class="product-actions">
|
||||
<button *ngIf="!(store.isDownload$ | async)" class="cta-availabilities" (click)="showAvailabilities()">
|
||||
Vorrätig in anderer Filiale
|
||||
Vorrätig in anderer Filiale?
|
||||
</button>
|
||||
<button
|
||||
class="cta-continue"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, ElementRef } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { DomainPrinterService } from '@domain/printer';
|
||||
import { ItemDTO as PrinterItemDTO } from '@swagger/print';
|
||||
@@ -137,7 +137,8 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
|
||||
private _purchaseOptionsModalService: PurchaseOptionsModalService,
|
||||
private _availability: DomainAvailabilityService,
|
||||
private _navigationService: ProductCatalogNavigationService,
|
||||
private _environment: EnvironmentService
|
||||
private _environment: EnvironmentService,
|
||||
private _router: Router
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -312,11 +313,41 @@ export class ArticleDetailsComponent implements OnInit, OnDestroy {
|
||||
async showPurchasingModal(selectedBranch?: BranchDTO) {
|
||||
const item = await this.store.item$.pipe(first()).toPromise();
|
||||
|
||||
this._purchaseOptionsModalService.open({
|
||||
type: 'add',
|
||||
processId: this.applicationService.activatedProcessId,
|
||||
items: [item],
|
||||
});
|
||||
this._purchaseOptionsModalService
|
||||
.open({
|
||||
type: 'add',
|
||||
processId: this.applicationService.activatedProcessId,
|
||||
items: [item],
|
||||
})
|
||||
.afterClosed$.subscribe((result) => {
|
||||
if (result?.data === 'continue') {
|
||||
this.navigateToShoppingCart();
|
||||
console.log('continue');
|
||||
} else if (result?.data === 'continue-shopping') {
|
||||
this.navigateToResultList();
|
||||
console.log('continue-shopping');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
navigateToShoppingCart() {
|
||||
this._router.navigate([`/kunde/${this.applicationService.activatedProcessId}/cart/review`]);
|
||||
}
|
||||
|
||||
async navigateToResultList() {
|
||||
let crumbs = await this.breadcrumb
|
||||
.getBreadcrumbsByKeyAndTags$(this.applicationService.activatedProcessId, ['catalog'])
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
crumbs = crumbs.filter((crumb) => !crumb.tags?.includes('details'));
|
||||
|
||||
const crumb = crumbs[crumbs.length - 1];
|
||||
if (crumb) {
|
||||
this._router.navigate([crumb.path], { queryParams: crumb.params });
|
||||
} else {
|
||||
this._router.navigate([`/kunde/${this.applicationService.activatedProcessId}/product`]);
|
||||
}
|
||||
}
|
||||
|
||||
scrollTop() {
|
||||
|
||||
@@ -6,11 +6,11 @@ import { ArticleSearchComponent } from './article-search.component';
|
||||
import { SearchResultsModule } from './search-results/search-results.module';
|
||||
import { SearchMainModule } from './search-main/search-main.module';
|
||||
import { SearchFilterModule } from './search-filter/search-filter.module';
|
||||
import { ShellFilterOverlayModule } from '@shell/filter-overlay';
|
||||
import { ArticleSearchService } from './article-search.store';
|
||||
import { SharedFilterOverlayModule } from '@shared/components/filter-overlay';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, RouterModule, UiIconModule, SearchResultsModule, SearchMainModule, SearchFilterModule, ShellFilterOverlayModule],
|
||||
imports: [CommonModule, RouterModule, UiIconModule, SearchResultsModule, SearchMainModule, SearchFilterModule, SharedFilterOverlayModule],
|
||||
exports: [ArticleSearchComponent],
|
||||
declarations: [ArticleSearchComponent],
|
||||
providers: [ArticleSearchService],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<a
|
||||
class="page-search-result-item__item-card p-5 desktop:p-px-10 h-[212px] desktop:h-[181px] bg-white border border-solid rounded-card"
|
||||
class="page-search-result-item__item-card p-5 desktop:p-px-10 h-[212px] desktop:h-[181px] bg-white border border-solid border-transparent rounded-card"
|
||||
[routerLink]="detailsPath"
|
||||
[routerLinkActive]="!isTablet ? 'active' : ''"
|
||||
[queryParamsHandling]="!isTablet ? 'preserve' : ''"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { Component, ChangeDetectionStrategy, Input, EventEmitter, Output } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
import { DomainAvailabilityService, DomainInStockService } from '@domain/availability';
|
||||
@@ -9,7 +8,7 @@ import { ItemDTO } from '@swagger/cat';
|
||||
import { DateAdapter } from '@ui/common';
|
||||
import { isEqual } from 'lodash';
|
||||
import { combineLatest } from 'rxjs';
|
||||
import { debounceTime, switchMap, map, shareReplay } from 'rxjs/operators';
|
||||
import { debounceTime, switchMap, map, shareReplay, filter } from 'rxjs/operators';
|
||||
import { ArticleSearchService } from '../article-search.store';
|
||||
import { ProductCatalogNavigationService } from '../../product-catalog-navigation.service';
|
||||
|
||||
@@ -116,9 +115,11 @@ export class SearchResultItemComponent extends ComponentStore<SearchResultItemCo
|
||||
|
||||
inStock$ = combineLatest([this.item$, this.selectedBranchId$, this.defaultBranch$]).pipe(
|
||||
debounceTime(100),
|
||||
filter(([item, branch, defaultBranch]) => !!item && !!defaultBranch),
|
||||
switchMap(([item, branch, defaultBranch]) =>
|
||||
this._stockService.getInStock$({ itemId: item.id, branchId: branch?.id ?? defaultBranch?.id })
|
||||
)
|
||||
),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
:host {
|
||||
@apply box-border grid h-[100vh] max-h-[calc(100vh-364px)] desktop:max-h-[calc(100vh-300px)];
|
||||
@apply box-border grid h-[100vh] max-h-[calc(100vh-364px)] desktop:max-h-[calc(100vh-245px)];
|
||||
grid-template-rows: auto auto 1fr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<shared-breadcrumb class="my-4" [key]="activatedProcessId$ | async" [tags]="['catalog']">
|
||||
<shared-branch-selector [branchType]="1" [value]="selectedBranch$ | async" (valueChange)="patchProcessData($event)">
|
||||
<shared-branch-selector
|
||||
[filterCurrentBranch]="!!auth.hasRole('Store')"
|
||||
[orderBy]="auth.hasRole('Store') ? 'distance' : 'name'"
|
||||
[branchType]="1"
|
||||
[value]="selectedBranch$ | async"
|
||||
(valueChange)="patchProcessData($event)"
|
||||
>
|
||||
</shared-branch-selector>
|
||||
</shared-breadcrumb>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { AuthService } from '@core/auth';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
import { BranchSelectorComponent } from '@shared/components/branch-selector';
|
||||
import { BreadcrumbComponent } from '@shared/components/breadcrumb';
|
||||
@@ -34,14 +35,18 @@ export class PageCatalogComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
constructor(
|
||||
public application: ApplicationService,
|
||||
private _uiModal: UiModalService,
|
||||
public auth: AuthService,
|
||||
private _environmentService: EnvironmentService,
|
||||
private _renderer: Renderer2
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
// this.auth.getClaims();
|
||||
this.activatedProcessId$ = this.application.activatedProcessId$.pipe(map((processId) => String(processId)));
|
||||
|
||||
this.selectedBranch$ = this.activatedProcessId$.pipe(switchMap((processId) => this.application.getSelectedBranch$(Number(processId))));
|
||||
|
||||
this.application.setTitle('Artikelsuche');
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
|
||||
@@ -2,22 +2,13 @@ import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BranchSelectorComponent } from '@shared/components/branch-selector';
|
||||
import { BreadcrumbModule } from '@shared/components/breadcrumb';
|
||||
import { ShellBreadcrumbModule } from '@shell/breadcrumb';
|
||||
import { ArticleDetailsModule } from './article-details/article-details.module';
|
||||
import { ArticleSearchModule } from './article-search/article-search.module';
|
||||
import { PageCatalogRoutingModule } from './page-catalog-routing.module';
|
||||
import { PageCatalogComponent } from './page-catalog.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
PageCatalogRoutingModule,
|
||||
ShellBreadcrumbModule,
|
||||
ArticleSearchModule,
|
||||
ArticleDetailsModule,
|
||||
BreadcrumbModule,
|
||||
BranchSelectorComponent,
|
||||
],
|
||||
imports: [CommonModule, PageCatalogRoutingModule, ArticleSearchModule, ArticleDetailsModule, BreadcrumbModule, BranchSelectorComponent],
|
||||
exports: [],
|
||||
declarations: [PageCatalogComponent],
|
||||
})
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
import { AppNavigationService } from 'apps/isa-app/src/app/app-navigation.service';
|
||||
import { NavigationService } from '@core/navigation';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ProductCatalogNavigationService extends AppNavigationService {
|
||||
export class ProductCatalogNavigationService extends NavigationService {
|
||||
constructor(_router: Router, _environment: EnvironmentService) {
|
||||
super(_router, _environment);
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ export class CheckoutReviewComponent extends ComponentStore<CheckoutReviewCompon
|
||||
shoppingCart,
|
||||
shoppingCartItems,
|
||||
});
|
||||
this.checkQuantityErrors(shoppingCartItems);
|
||||
// this.checkQuantityErrors(shoppingCartItems);
|
||||
},
|
||||
(err) => {},
|
||||
() => {}
|
||||
@@ -282,15 +282,15 @@ export class CheckoutReviewComponent extends ComponentStore<CheckoutReviewCompon
|
||||
)
|
||||
);
|
||||
|
||||
checkQuantityErrors(shoppingCartItems: ShoppingCartItemDTO[]) {
|
||||
shoppingCartItems.forEach((item) => {
|
||||
if (item.features?.orderType === 'Rücklage') {
|
||||
this.setQuantityError(item, item.availability, item.quantity > item.availability?.inStock);
|
||||
} else {
|
||||
this.setQuantityError(item, item.availability, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
// checkQuantityErrors(shoppingCartItems: ShoppingCartItemDTO[]) {
|
||||
// shoppingCartItems.forEach((item) => {
|
||||
// if (item.features?.orderType === 'Abholung') {
|
||||
// this.setQuantityError(item, item.availability, item.quantity > item.availability?.inStock);
|
||||
// } else {
|
||||
// this.setQuantityError(item, item.availability, false);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
async updateBreadcrumb() {
|
||||
await this.breadcrumb.addOrUpdateBreadcrumbIfNotExists({
|
||||
@@ -485,7 +485,7 @@ export class CheckoutReviewComponent extends ComponentStore<CheckoutReviewCompon
|
||||
})
|
||||
.toPromise();
|
||||
|
||||
this.setQuantityError(shoppingCartItem, availability, availability?.inStock < quantity);
|
||||
// this.setQuantityError(shoppingCartItem, availability, availability?.inStock < quantity);
|
||||
break;
|
||||
case 'Abholung':
|
||||
availability = await this.availabilityService
|
||||
@@ -563,7 +563,7 @@ export class CheckoutReviewComponent extends ComponentStore<CheckoutReviewCompon
|
||||
},
|
||||
})
|
||||
.toPromise();
|
||||
this.setQuantityError(shoppingCartItem, availability, false);
|
||||
// this.setQuantityError(shoppingCartItem, availability, false);
|
||||
} else if (availability) {
|
||||
// Wenn das Ergebnis der Availability Abfrage keinen Preis zurückliefert (z.B. HFI Geschenkkarte), wird der Preis aus der
|
||||
// Availability vor der Abfrage verwendet
|
||||
@@ -594,16 +594,16 @@ export class CheckoutReviewComponent extends ComponentStore<CheckoutReviewCompon
|
||||
this.loadingOnQuantityChangeById$.next(undefined);
|
||||
}
|
||||
|
||||
setQuantityError(item: ShoppingCartItemDTO, availability: AvailabilityDTO, error: boolean) {
|
||||
const quantityErrors: { [key: string]: string } = this.quantityError$.value;
|
||||
if (error) {
|
||||
quantityErrors[item.product.catalogProductNumber] = `${availability.inStock} Exemplar(e) sofort lieferbar`;
|
||||
this.quantityError$.next({ ...quantityErrors });
|
||||
} else {
|
||||
delete quantityErrors[item.product.catalogProductNumber];
|
||||
this.quantityError$.next({ ...quantityErrors });
|
||||
}
|
||||
}
|
||||
// setQuantityError(item: ShoppingCartItemDTO, availability: AvailabilityDTO, error: boolean) {
|
||||
// const quantityErrors: { [key: string]: string } = this.quantityError$.value;
|
||||
// if (error) {
|
||||
// quantityErrors[item.product.catalogProductNumber] = `${availability.inStock} Exemplar(e) sofort lieferbar`;
|
||||
// this.quantityError$.next({ ...quantityErrors });
|
||||
// } else {
|
||||
// delete quantityErrors[item.product.catalogProductNumber];
|
||||
// this.quantityError$.next({ ...quantityErrors });
|
||||
// }
|
||||
// }
|
||||
|
||||
// Bei unbekannten Kunden und DIG Bestellung findet ein Vergleich der Preise statt
|
||||
compareDeliveryAndCatalogPrice(availability: AvailabilityDTO, orderType: string, shoppingCartItemPrice: number) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
<shell-breadcrumb [key]="breadcrumbKey$ | async" [includesTags]="['checkout']"></shell-breadcrumb> <router-outlet></router-outlet>
|
||||
<shared-breadcrumb [key]="breadcrumbKey$ | async" [tags]="['checkout']"></shared-breadcrumb> <router-outlet></router-outlet>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@@ -8,8 +8,12 @@ import { map } from 'rxjs/operators';
|
||||
styleUrls: ['page-checkout.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class PageCheckoutComponent {
|
||||
export class PageCheckoutComponent implements OnInit {
|
||||
readonly breadcrumbKey$ = this.applicationService.activatedProcessId$.pipe(map((processId) => String(processId)));
|
||||
|
||||
constructor(private applicationService: ApplicationService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.applicationService.setTitle('Warenkorb');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ShellBreadcrumbModule } from '@shell/breadcrumb';
|
||||
import { BreadcrumbModule } from '@shared/components/breadcrumb';
|
||||
import { CheckoutDummyModule } from './checkout-dummy/checkout-dummy.module';
|
||||
import { CheckoutReviewModule } from './checkout-review/checkout-review.module';
|
||||
import { CheckoutSummaryModule } from './checkout-summary/checkout-summary.module';
|
||||
@@ -8,14 +8,7 @@ import { PageCheckoutRoutingModule } from './page-checkout-routing.module';
|
||||
import { PageCheckoutComponent } from './page-checkout.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
CheckoutSummaryModule,
|
||||
PageCheckoutRoutingModule,
|
||||
CheckoutReviewModule,
|
||||
CheckoutDummyModule,
|
||||
ShellBreadcrumbModule,
|
||||
],
|
||||
imports: [CommonModule, CheckoutSummaryModule, PageCheckoutRoutingModule, CheckoutReviewModule, CheckoutDummyModule, BreadcrumbModule],
|
||||
declarations: [PageCheckoutComponent],
|
||||
exports: [],
|
||||
})
|
||||
|
||||
@@ -35,13 +35,10 @@ export class CustomerOrderEditComponent implements OnInit {
|
||||
|
||||
buyerNumber$ = this._activatedRoute.queryParams.pipe(map((params) => params.buyerNumber));
|
||||
|
||||
items$ = combineLatest([this.orderNumber$, this.compartmentCode$, this.archive$]).pipe(
|
||||
switchMap(([orderNumber, compartmentCode, archive]) =>
|
||||
// compartmentCode
|
||||
// ? this._domainGoodsInService.getWarenausgabeItemByCompartment(compartmentCode, archive)
|
||||
// : this._domainGoodsInService.getWarenausgabeItemByOrderNumber(orderNumber, archive)
|
||||
this._domainGoodsInService.getOrderItemsByOrderNumber(orderNumber)
|
||||
),
|
||||
items$ = combineLatest([this.orderNumber$, this.compartmentCode$]).pipe(
|
||||
switchMap(([orderNumber, compartmentCode]) => {
|
||||
return this._domainGoodsInService.getOrderItemsByOrderNumber(compartmentCode ?? orderNumber);
|
||||
}),
|
||||
withLatestFrom(this.processingStatus$, this.buyerNumber$),
|
||||
map(([response, processingStatus, buyerNumber]) => {
|
||||
return response.result.filter(
|
||||
|
||||
@@ -6,7 +6,7 @@ import { CustomerOrderSearchFilterComponent, OrderBranchIdInputComponent } from
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { UiFilterNextModule } from '@ui/filter';
|
||||
import { ShellFilterOverlayModule } from '@shell/filter-overlay';
|
||||
import { SharedFilterOverlayModule } from '@shared/components/filter-overlay';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
import { CustomerOrderSearchStore } from './customer-order-search.store';
|
||||
|
||||
@@ -16,7 +16,7 @@ import { CustomerOrderSearchStore } from './customer-order-search.store';
|
||||
UiIconModule,
|
||||
RouterModule,
|
||||
UiFilterNextModule,
|
||||
ShellFilterOverlayModule,
|
||||
SharedFilterOverlayModule,
|
||||
UiSpinnerModule,
|
||||
OrderBranchIdInputComponent,
|
||||
],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { AuthService } from '@core/auth';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
import { BranchDTO } from '@swagger/checkout';
|
||||
@@ -30,7 +31,8 @@ export class CustomerOrderComponent implements OnInit {
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _uiModal: UiModalService,
|
||||
private _breadcrumb: BreadcrumbService,
|
||||
private _environmentService: EnvironmentService
|
||||
private _environmentService: EnvironmentService,
|
||||
public auth: AuthService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -44,6 +46,8 @@ export class CustomerOrderComponent implements OnInit {
|
||||
this.selectedBranch$ = this.application.activatedProcessId$.pipe(
|
||||
switchMap((processId) => this.application.getSelectedBranch$(Number(processId)))
|
||||
);
|
||||
|
||||
this.application.setTitle('Kundenbestellung');
|
||||
}
|
||||
|
||||
async patchProcessData(selectedBranch: BranchDTO) {
|
||||
|
||||
@@ -42,7 +42,7 @@ export class CreateB2BCustomerComponent extends AbstractCreateCustomer {
|
||||
deviatingNameRequiredMarks: (keyof NameFormBlockData)[] = ['gender', 'firstName', 'lastName'];
|
||||
|
||||
deviatingNameValidationFns: Record<string, ValidatorFn[]> = {
|
||||
gender: [Validators.required],
|
||||
gender: [Validators.required, Validators.min(1)],
|
||||
firstName: [Validators.required],
|
||||
lastName: [Validators.required],
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ export class CreateGuestCustomerComponent extends AbstractCreateCustomer {
|
||||
nameValidationFns: Record<keyof NameFormBlockData, ValidatorFn[]> = {
|
||||
firstName: [Validators.required],
|
||||
lastName: [Validators.required],
|
||||
gender: [Validators.required],
|
||||
gender: [Validators.required, Validators.min(1)],
|
||||
title: [],
|
||||
};
|
||||
|
||||
@@ -45,7 +45,7 @@ export class CreateGuestCustomerComponent extends AbstractCreateCustomer {
|
||||
deviatingNameRequiredMarks: (keyof NameFormBlockData)[] = ['gender', 'firstName', 'lastName'];
|
||||
|
||||
deviatingNameValidationFns: Record<string, ValidatorFn[]> = {
|
||||
gender: [Validators.required],
|
||||
gender: [Validators.required, Validators.min(1)],
|
||||
firstName: [Validators.required],
|
||||
lastName: [Validators.required],
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ export class CreateP4MCustomerComponent extends AbstractCreateCustomer implement
|
||||
nameValidationFns: Record<keyof NameFormBlockData, ValidatorFn[]> = {
|
||||
firstName: [Validators.required],
|
||||
lastName: [Validators.required],
|
||||
gender: [Validators.required],
|
||||
gender: [Validators.required, Validators.min(1)],
|
||||
title: [],
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ export class CreateStoreCustomerComponent extends AbstractCreateCustomer {
|
||||
nameRequiredMarks: (keyof NameFormBlockData)[] = ['gender', 'firstName', 'lastName'];
|
||||
|
||||
nameValidationFns: Record<string, ValidatorFn[]> = {
|
||||
gender: [Validators.required],
|
||||
gender: [Validators.required, Validators.min(1)],
|
||||
firstName: [Validators.required],
|
||||
lastName: [Validators.required],
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ export class CreateWebshopCustomerComponent extends AbstractCreateCustomer {
|
||||
nameValidationFns: Record<keyof NameFormBlockData, ValidatorFn[]> = {
|
||||
firstName: [Validators.required],
|
||||
lastName: [Validators.required],
|
||||
gender: [Validators.required],
|
||||
gender: [Validators.required, Validators.min(1)],
|
||||
title: [],
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ export class UpdateP4MWebshopCustomerComponent extends AbstractCreateCustomer im
|
||||
nameValidationFns: Record<keyof NameFormBlockData, ValidatorFn[]> = {
|
||||
firstName: [Validators.required],
|
||||
lastName: [Validators.required],
|
||||
gender: [Validators.required],
|
||||
gender: [Validators.required, Validators.min(1)],
|
||||
title: [],
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { UiCommonModule } from '@ui/common';
|
||||
import { CustomerResultCardComponent } from './search-results/customer-result-card/customer-result-card.component';
|
||||
import { CustomerSearchFilterComponent } from './search-filter/search-filter.component';
|
||||
import { UiFilterNextModule } from '@ui/filter';
|
||||
import { ShellFilterOverlayModule } from '@shell/filter-overlay';
|
||||
import { SharedFilterOverlayModule } from '@shared/components/filter-overlay';
|
||||
import { UiScrollContainerModule } from '@ui/scroll-container';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
|
||||
@@ -23,7 +23,7 @@ import { UiSpinnerModule } from '@ui/spinner';
|
||||
UiCommonModule,
|
||||
UiIconModule,
|
||||
ReactiveFormsModule,
|
||||
ShellFilterOverlayModule,
|
||||
SharedFilterOverlayModule,
|
||||
UiFilterNextModule,
|
||||
UiScrollContainerModule,
|
||||
UiSpinnerModule,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<shell-breadcrumb [key]="activatedProcessId$ | async" [includesTags]="['customer']"></shell-breadcrumb>
|
||||
<shared-breadcrumb [key]="activatedProcessId$ | async" tags="customer"></shared-breadcrumb>
|
||||
|
||||
<div class="content-container">
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@@ -9,8 +9,12 @@ import { map } from 'rxjs/operators';
|
||||
providers: [],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class PageCustomerComponent {
|
||||
export class PageCustomerComponent implements OnInit {
|
||||
activatedProcessId$ = this.application.activatedProcessId$.pipe(map((p) => String(p)));
|
||||
|
||||
constructor(public application: ApplicationService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.application.setTitle('Kundensuche');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
|
||||
|
||||
import { PageCustomerComponent } from './page-customer.component';
|
||||
import { PageCustomerRoutingModule } from './page-customer-routing.module';
|
||||
import { ShellBreadcrumbModule } from '@shell/breadcrumb';
|
||||
import { BreadcrumbModule } from '@shared/components/breadcrumb';
|
||||
import { CustomerSearchModule } from './customer-search/customer-search.module';
|
||||
import { CustomerDetailsModule } from './customer-details/customer-details.module';
|
||||
import { UiInputModule } from '@ui/input';
|
||||
@@ -14,7 +14,7 @@ import { CustomerModalModuleModule } from './modals';
|
||||
imports: [
|
||||
CommonModule,
|
||||
PageCustomerRoutingModule,
|
||||
ShellBreadcrumbModule,
|
||||
BreadcrumbModule,
|
||||
CustomerSearchModule,
|
||||
CustomerDetailsModule,
|
||||
UiInputModule,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { DomainDashboardService } from '@domain/isa';
|
||||
import { of } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
@@ -14,7 +15,12 @@ export class DashboardComponent implements OnInit {
|
||||
catchError(() => of([]))
|
||||
);
|
||||
|
||||
constructor(private readonly _domainIsaDashboardService: DomainDashboardService) {}
|
||||
constructor(private readonly _domainIsaDashboardService: DomainDashboardService, private _app: ApplicationService) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
ngOnInit(): void {
|
||||
this._app.setSection('customer');
|
||||
this._app.activateProcess(undefined);
|
||||
|
||||
this._app.setTitle('Dashboard');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import { UiIconModule } from '@ui/icon';
|
||||
import { GoodsInSearchFilterComponent } from './goods-in-search-filter';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { UiFilterNextModule } from '@ui/filter';
|
||||
import { ShellFilterOverlayModule } from '@shell/filter-overlay';
|
||||
import { SharedFilterOverlayModule } from '@shared/components/filter-overlay';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, RouterModule, UiIconModule, UiFilterNextModule, ShellFilterOverlayModule, UiSpinnerModule],
|
||||
imports: [CommonModule, RouterModule, UiIconModule, UiFilterNextModule, SharedFilterOverlayModule, UiSpinnerModule],
|
||||
exports: [GoodsInSearchComponent],
|
||||
declarations: [GoodsInSearchComponent, GoodsInSearchFilterComponent],
|
||||
})
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<shell-breadcrumb [key]="goodsInKey"></shell-breadcrumb>
|
||||
<shared-breadcrumb [key]="goodsInKey"></shared-breadcrumb>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { Config } from '@core/config';
|
||||
|
||||
@Component({
|
||||
@@ -10,7 +11,9 @@ import { Config } from '@core/config';
|
||||
export class GoodsInComponent implements OnInit {
|
||||
goodsInKey = this._config.get('process.ids.goodsIn');
|
||||
|
||||
constructor(private readonly _config: Config) {}
|
||||
constructor(private readonly _config: Config, private _app: ApplicationService) {}
|
||||
|
||||
ngOnInit() {}
|
||||
ngOnInit() {
|
||||
this._app.setTitle('Abholfach');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { GoodsInRoutingModule } from './good-in-routing.module';
|
||||
import { GoodsInComponent } from './goods-in.component';
|
||||
import { ShellBreadcrumbModule } from '@shell/breadcrumb';
|
||||
import { BreadcrumbModule } from '@shared/components/breadcrumb';
|
||||
import { CoreCommandModule } from '@core/command';
|
||||
import {
|
||||
AcceptedActionHandler,
|
||||
@@ -42,11 +42,12 @@ import {
|
||||
CreateReturnItemActionHandler,
|
||||
PrintPriceDiffQrCodeLabelActionHandler,
|
||||
} from '@domain/oms';
|
||||
|
||||
@NgModule({
|
||||
declarations: [GoodsInComponent],
|
||||
imports: [
|
||||
GoodsInRoutingModule,
|
||||
ShellBreadcrumbModule,
|
||||
BreadcrumbModule,
|
||||
CoreCommandModule.forChild([
|
||||
AcceptedActionHandler,
|
||||
ArrivedActionHandler,
|
||||
|
||||
@@ -6,11 +6,11 @@ import { GoodsOutSearchFilterComponent } from './goods-out-search-filter';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { UiFilterNextModule } from '@ui/filter';
|
||||
import { ShellFilterOverlayModule } from '@shell/filter-overlay';
|
||||
import { SharedFilterOverlayModule } from '@shared/components/filter-overlay';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, UiIconModule, RouterModule, UiFilterNextModule, ShellFilterOverlayModule, UiSpinnerModule],
|
||||
imports: [CommonModule, UiIconModule, RouterModule, UiFilterNextModule, SharedFilterOverlayModule, UiSpinnerModule],
|
||||
exports: [GoodsOutSearchComponent],
|
||||
declarations: [GoodsOutSearchComponent, GoodsOutSearchFilterComponent],
|
||||
})
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<shell-breadcrumb [key]="processId$ | async" [includesTags]="['goods-out']"></shell-breadcrumb>
|
||||
<shared-breadcrumb [key]="processId$ | async" tags="goods-out"></shared-breadcrumb>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
@@ -8,8 +9,12 @@ import { map } from 'rxjs/operators';
|
||||
styleUrls: ['goods-out.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class GoodsOutComponent {
|
||||
export class GoodsOutComponent implements OnInit {
|
||||
processId$ = this._activatedRoute.data.pipe(map((data) => String(data.processId)));
|
||||
|
||||
constructor(private _activatedRoute: ActivatedRoute) {}
|
||||
constructor(private _activatedRoute: ActivatedRoute, private _app: ApplicationService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._app.setTitle('Warenausgabe');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ import {
|
||||
PrintPriceDiffQrCodeLabelActionHandler,
|
||||
} from '@domain/oms';
|
||||
import { CoreCommandModule } from '@core/command';
|
||||
import { ShellBreadcrumbModule } from '@shell/breadcrumb';
|
||||
import { BreadcrumbModule } from '@shared/components/breadcrumb';
|
||||
import { GoodsInRoutingModule } from './good-out-routing.module';
|
||||
|
||||
@NgModule({
|
||||
@@ -49,7 +49,7 @@ import { GoodsInRoutingModule } from './good-out-routing.module';
|
||||
imports: [
|
||||
CommonModule,
|
||||
GoodsInRoutingModule,
|
||||
ShellBreadcrumbModule,
|
||||
BreadcrumbModule,
|
||||
CoreCommandModule.forChild([
|
||||
AcceptedActionHandler,
|
||||
ArrivedActionHandler,
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="package-details-list-item__product-details-2">
|
||||
<div class="package-details-list-item__product-details-2" *ngIf="showStockInfos$ | async">
|
||||
<div class="package-details-list-item__inventory-quantity py-2">
|
||||
<div class="grow">
|
||||
<ng-container *ngIf="showStockInfoTooltip$ | async">
|
||||
@@ -52,7 +52,7 @@
|
||||
Filialbestand
|
||||
</div>
|
||||
<div class="w-16">
|
||||
<span class="filialbestand isa-label bg-accent-green px-2 font-bold">{{ inStock$ | async }} x</span>
|
||||
<span class="filialbestand isa-label bg-accent-green px-2 font-bold">{{ inStock$ | async | max: 0 }} x</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="package-details-list-item__package-quantity">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { fakeAsync } from '@angular/core/testing';
|
||||
import { ProductImagePipe } from '@cdn/product-image';
|
||||
import { createComponentFactory, Spectator } from '@ngneat/spectator';
|
||||
import { MathPipesModule } from '@shared/pipes/math';
|
||||
import { ArrivalStatus } from '@swagger/wws';
|
||||
import { UiCommonModule } from '@ui/common';
|
||||
import { UiTooltipModule } from '@ui/tooltip';
|
||||
@@ -16,7 +17,7 @@ describe('PackageDetailsListItemComponent', () => {
|
||||
|
||||
const createComponent = createComponentFactory({
|
||||
component: PackageDetailsListItemComponent,
|
||||
imports: [UiCommonModule, UiTooltipModule],
|
||||
imports: [UiCommonModule, UiTooltipModule, MathPipesModule],
|
||||
declarations: [MockPipe(ProductImagePipe, (value) => `base/karma/assets/unit-test.svg#${value}`)],
|
||||
});
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ export class PackageDetailsListItemComponent implements OnChanges {
|
||||
|
||||
showStockInfoTooltip$ = this._store.arrivalStatus$.pipe(map((arrivalStatus) => arrivalStatus === 0));
|
||||
|
||||
showStockInfos$ = this._store.arrivalStatus$.pipe(map((arrivalStatus) => arrivalStatus !== 8));
|
||||
|
||||
constructor(private _store: PackageDetailsListStore) {}
|
||||
|
||||
ngOnChanges({ item }: SimpleChanges): void {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
class="mb-[2px]"
|
||||
[item]="item"
|
||||
*cdkVirtualFor="let item of items$ | async; trackBy: trackByItemId; let first = first"
|
||||
[light]="!first"
|
||||
[light]="!first || arrivalStatus == 8"
|
||||
></page-package-details-list-item>
|
||||
<div class="h-[100px]" *ngIf="hasActions"></div>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
|
||||
@@ -36,13 +36,6 @@ describe('PackageDetailsListComponent', () => {
|
||||
expect(spectator.component.items).toEqual(items);
|
||||
});
|
||||
|
||||
it('should call store.setItems and loadStockInfos when items are set', () => {
|
||||
const items = [{ id: '1' }, { id: '2' }] as PackageItemDTO[];
|
||||
const setItemsSpy = spyOn(packageDetailsListStore, 'setItems');
|
||||
spectator.component.items = items;
|
||||
expect(setItemsSpy).toHaveBeenCalledWith(items);
|
||||
});
|
||||
|
||||
it('should not call patchState and loadStockInfos when items are set to the same value', () => {
|
||||
const items = [{ id: '1' }, { id: '2' }] as PackageItemDTO[];
|
||||
spyOnProperty(spectator.component, 'items', 'get').and.returnValue(items);
|
||||
|
||||
@@ -30,7 +30,6 @@ export class PackageDetailsListComponent implements OnChanges {
|
||||
}
|
||||
set items(value: PackageItemDTO[]) {
|
||||
if (isEqual(this.items, value)) return;
|
||||
this._store.setItems(value ?? []);
|
||||
}
|
||||
|
||||
@Input()
|
||||
@@ -48,10 +47,14 @@ export class PackageDetailsListComponent implements OnChanges {
|
||||
|
||||
constructor(private _store: PackageDetailsListStore) {}
|
||||
|
||||
ngOnChanges({ height }: SimpleChanges) {
|
||||
ngOnChanges({ height, arrivalStatus, items }: SimpleChanges) {
|
||||
if (height) {
|
||||
this.checkViewportSize();
|
||||
}
|
||||
|
||||
if (arrivalStatus && items) {
|
||||
this._store.setItems(items.currentValue ?? [], arrivalStatus.currentValue !== 8);
|
||||
}
|
||||
}
|
||||
|
||||
checkViewportSize() {
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { PackageInspectionPipesModule } from '../../pipes/package-inspection-pipes.module';
|
||||
import { PackageDetailsListComponent } from './package-details-list.component';
|
||||
import { PackageDetailsListItemComponent } from './package-details-list-item.component';
|
||||
import { ProductImageModule } from '@cdn/product-image';
|
||||
import { ScrollingModule } from '@angular/cdk/scrolling';
|
||||
import { UiTooltipModule } from '@ui/tooltip';
|
||||
import { UiCommonModule } from '@ui/common';
|
||||
import { PackageInspectionPipesModule } from '@shared/pipes/package-inspection';
|
||||
import { MathPipesModule } from '@shared/pipes/math';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, ProductImageModule, PackageInspectionPipesModule, ScrollingModule, UiTooltipModule, UiCommonModule],
|
||||
imports: [
|
||||
CommonModule,
|
||||
ProductImageModule,
|
||||
PackageInspectionPipesModule,
|
||||
ScrollingModule,
|
||||
UiTooltipModule,
|
||||
UiCommonModule,
|
||||
MathPipesModule,
|
||||
],
|
||||
exports: [PackageDetailsListComponent, PackageDetailsListItemComponent],
|
||||
declarations: [PackageDetailsListComponent, PackageDetailsListItemComponent],
|
||||
})
|
||||
|
||||
@@ -124,10 +124,13 @@ export class PackageDetailsListStore extends ComponentStore<PackageDetailsListSt
|
||||
console.error(error);
|
||||
};
|
||||
|
||||
setItems(items: PackageItemDTO[]) {
|
||||
setItems(items: PackageItemDTO[], loadStockInfos: boolean) {
|
||||
this.patchState({ items });
|
||||
if (items.length === 0) return;
|
||||
this.loadStockInfos(items);
|
||||
|
||||
if (loadStockInfos) {
|
||||
this.loadStockInfos(items);
|
||||
}
|
||||
}
|
||||
|
||||
setArrivalStatus(arrivalStatus: ArrivalStatus) {
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './package-list.component';
|
||||
export * from './package-list.module';
|
||||
@@ -1,3 +0,0 @@
|
||||
.page-package-list {
|
||||
@apply bg-customer -mx-4 mt-10 border-t border-b-2 border-solid border-customer;
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
korrekt?
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-white" *ngSwitchCase="'Fehlt'">
|
||||
<div class="bg-white" *ngSwitchCa se="'Fehlt'">
|
||||
<p class="text-center text-xl py-10">
|
||||
Prüfen Sie bitte stichprobenartig den Filialbestand <br />
|
||||
des dargestellten Artikels. Ist der angezeigte Filialbestand <br />
|
||||
@@ -39,10 +39,18 @@
|
||||
{{ packageDetails.package.deliveryNoteNumber }}
|
||||
</div>
|
||||
<div class="col-span-3">
|
||||
Filialstopp
|
||||
<span class="font-bold ml-2">
|
||||
{{ packageDetails.package.area }}
|
||||
</span>
|
||||
<ng-container *ngIf="packageDetails.package.arrivalStatus !== 8; else irrlauferTmplt">
|
||||
Filialstopp
|
||||
<span class="font-bold ml-2">
|
||||
{{ packageDetails.package.area }}
|
||||
</span>
|
||||
</ng-container>
|
||||
<ng-template #irrlauferTmplt>
|
||||
Filiale
|
||||
<span class="font-bold ml-2">
|
||||
{{ packageDetails.package.misrouted | split: ':' | at: 1 }}
|
||||
</span>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<ng-container *ngIf="(packageDetails.package.arrivalStatus | arrivalStatus) === 'Fehlt'">
|
||||
|
||||
@@ -2,12 +2,14 @@ import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { PackageDetailsComponent } from './package-details.component';
|
||||
import { PackageInspectionPipesModule } from '../pipes';
|
||||
import { PackageDetailsListModule } from '../components/package-details-list';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { UiTooltipModule } from '@ui/tooltip';
|
||||
import { UiCommonModule } from '@ui/common';
|
||||
import { ElementLifecycleModule } from '@shared/directives/element-lifecycle';
|
||||
import { PackageInspectionPipesModule } from '@shared/pipes/package-inspection';
|
||||
import { StringPipesModule } from '@shared/pipes/string';
|
||||
import { ArrayPipesModule } from '@shared/pipes/array';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -18,6 +20,8 @@ import { ElementLifecycleModule } from '@shared/directives/element-lifecycle';
|
||||
UiTooltipModule,
|
||||
UiCommonModule,
|
||||
ElementLifecycleModule,
|
||||
StringPipesModule,
|
||||
ArrayPipesModule,
|
||||
],
|
||||
exports: [PackageDetailsComponent],
|
||||
declarations: [PackageDetailsComponent],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ApplicationService } from '@core/application';
|
||||
import { Breadcrumb, BreadcrumbService } from '@core/breadcrumb';
|
||||
import { Config } from '@core/config';
|
||||
|
||||
@@ -13,10 +14,12 @@ export class PackageInspectionComponent implements OnInit {
|
||||
return this._config.get('process.ids.packageInspection');
|
||||
}
|
||||
|
||||
constructor(private _config: Config, private _breadcrumb: BreadcrumbService) {}
|
||||
constructor(private _config: Config, private _breadcrumb: BreadcrumbService, private _app: ApplicationService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.createBreadcrumbIfNotExists();
|
||||
|
||||
this._app.setTitle('Packstück Prüfung');
|
||||
}
|
||||
|
||||
async createBreadcrumbIfNotExists(): Promise<void> {
|
||||
|
||||
@@ -4,16 +4,15 @@ import { Breadcrumb, BreadcrumbService } from '@core/breadcrumb';
|
||||
import { CacheService } from '@core/cache';
|
||||
import { Config } from '@core/config';
|
||||
import { provideComponentStore } from '@ngrx/component-store';
|
||||
import { ShellFilterOverlayComponent } from '@shell/filter-overlay';
|
||||
import { ArrivalStatus, ListResponseArgsOfPackageDTO2 } from '@swagger/wws';
|
||||
import { UiFilter, UiFilterComponent } from '@ui/filter';
|
||||
import { isNumber, isString } from 'lodash';
|
||||
import { UiFilter } from '@ui/filter';
|
||||
import moment from 'moment';
|
||||
import { combineLatest, Subject, Subscription } from 'rxjs';
|
||||
import { filter, first, map } from 'rxjs/operators';
|
||||
import { PackageListComponent } from '../components/package-list';
|
||||
import { PackageResultCacheData } from './package-result-cache-data';
|
||||
import { PackageResultComponentStore } from './package-result.component.store';
|
||||
import { SharedFilterOverlayComponent } from '@shared/components/filter-overlay';
|
||||
import { PackageListComponent } from '@shared/components/package-inspection/package-list';
|
||||
|
||||
@Component({
|
||||
selector: 'page-package-result',
|
||||
@@ -31,8 +30,8 @@ export class PackageResultComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
|
||||
hint$ = new Subject<string>();
|
||||
|
||||
@ViewChild(ShellFilterOverlayComponent)
|
||||
filterOverlay: ShellFilterOverlayComponent;
|
||||
@ViewChild(SharedFilterOverlayComponent)
|
||||
filterOverlay: SharedFilterOverlayComponent;
|
||||
|
||||
/**
|
||||
* Zeigt die liste an, wenn entweder keine packages geladen werden oder wenn packages geladen wurden
|
||||
|
||||
@@ -2,14 +2,14 @@ import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { PackageResultComponent } from './package-result.component';
|
||||
import { PackageListModule } from '../components/package-list';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { ShellFilterOverlayModule } from '@shell/filter-overlay';
|
||||
import { SharedFilterOverlayModule } from '@shared/components/filter-overlay';
|
||||
import { UiFilterNextModule } from '@ui/filter';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
import { PackageListModule } from '@shared/components/package-inspection/package-list';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, PackageListModule, UiIconModule, UiFilterNextModule, ShellFilterOverlayModule, UiSpinnerModule],
|
||||
imports: [CommonModule, PackageListModule, UiIconModule, UiFilterNextModule, SharedFilterOverlayModule, UiSpinnerModule],
|
||||
exports: [PackageResultComponent],
|
||||
declarations: [PackageResultComponent],
|
||||
})
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export * from './arrival-status-color-class.pipe';
|
||||
export * from './arrival-status.pipe';
|
||||
export * from './package-inspection-pipes.module';
|
||||
@@ -3,7 +3,7 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { Config } from '@core/config';
|
||||
import { DomainRemissionService } from '@domain/remission';
|
||||
import { ReturnDTO } from '@swagger/remi';
|
||||
import { ReceiptDTO, ReturnDTO } from '@swagger/remi';
|
||||
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
|
||||
import { UiSearchboxNextComponent } from '@ui/searchbox';
|
||||
import { Subject } from 'rxjs';
|
||||
@@ -52,10 +52,9 @@ export class CreateRemissionComponent implements OnInit {
|
||||
const returnGroup = this._activatedRoute.snapshot.params?.returnGroup;
|
||||
|
||||
const supplier = await this.getSupplier();
|
||||
const returnDTO = await this.createReturn(supplier.id, returnGroup);
|
||||
const receipt = await this.createReceipt({ returnDTO, receiptNumber });
|
||||
if (receipt) {
|
||||
await this.navigateToFinishShippingDocument(returnDTO.id, receipt.id);
|
||||
const returnReceipt = await this.createReturnAndReceipt(supplier.id, returnGroup, receiptNumber);
|
||||
if (returnReceipt) {
|
||||
await this.navigateToFinishShippingDocument(returnReceipt);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
@@ -71,16 +70,25 @@ export class CreateRemissionComponent implements OnInit {
|
||||
return suppliers.find((s) => s.id === this.supplierId);
|
||||
}
|
||||
|
||||
async createReturn(supplierId: number, returnGroup: string) {
|
||||
return await this._domainRemissionService.createReturn(supplierId, returnGroup);
|
||||
async createReturnAndReceipt(
|
||||
supplierId: number,
|
||||
returnGroup: string,
|
||||
receiptNumber: string
|
||||
): Promise<{ returnDto: ReturnDTO; receiptDto: ReceiptDTO }> {
|
||||
try {
|
||||
const returnDto = await this._domainRemissionService.createReturn(supplierId, returnGroup);
|
||||
const receiptDto = await this._domainRemissionService.createReceipt(returnDto, receiptNumber);
|
||||
return {
|
||||
returnDto,
|
||||
receiptDto,
|
||||
};
|
||||
} catch (error) {
|
||||
this._modal.error('Fehler beim Erstellen der Remission', error);
|
||||
}
|
||||
}
|
||||
|
||||
async createReceipt({ returnDTO, receiptNumber }: { returnDTO: ReturnDTO; receiptNumber?: string }) {
|
||||
return await this._domainRemissionService.createReceipt(returnDTO, receiptNumber);
|
||||
}
|
||||
|
||||
async navigateToFinishShippingDocument(returnId: number, receiptId: number) {
|
||||
await this._router.navigate(['/filiale', 'remission', returnId, 'finish-shipping-document', receiptId], {
|
||||
async navigateToFinishShippingDocument({ returnDto, receiptDto }: { returnDto: ReturnDTO; receiptDto: ReceiptDTO }) {
|
||||
await this._router.navigate(['/filiale', 'remission', returnDto.id, 'finish-shipping-document', receiptDto.id], {
|
||||
queryParams: { ...this._activatedRoute.snapshot.queryParams, supplier: this.supplierId, source: this.source },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@ import { ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewChild } from
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { Config } from '@core/config';
|
||||
import { DomainRemissionService } from '@domain/remission';
|
||||
import { DialogModel, UiDialogModalComponent, UiModalService } from '@ui/modal';
|
||||
import { UiSearchboxNextComponent } from '@ui/searchbox';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { first, takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'page-finish-shipping-document',
|
||||
@@ -35,12 +36,17 @@ export class FinishShippingDocumentComponent implements OnInit, OnDestroy {
|
||||
return Number(this._activatedRoute?.snapshot?.params?.returnId);
|
||||
}
|
||||
|
||||
get receiptId(): number {
|
||||
return Number(this._activatedRoute?.snapshot?.params?.receiptId);
|
||||
}
|
||||
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _modal: UiModalService,
|
||||
private _router: Router,
|
||||
private _breadcrumb: BreadcrumbService,
|
||||
private _config: Config
|
||||
private _config: Config,
|
||||
private _remissionService: DomainRemissionService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -53,6 +59,7 @@ export class FinishShippingDocumentComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
search(query: string) {
|
||||
this.hint$.next('');
|
||||
if (!query) {
|
||||
this.hint$.next('Ungültige Eingabe');
|
||||
return;
|
||||
@@ -77,6 +84,7 @@ export class FinishShippingDocumentComponent implements OnInit, OnDestroy {
|
||||
|
||||
modal.afterClosed$.pipe(takeUntil(this._onDestroy$)).subscribe(async (result) => {
|
||||
if (result?.data === 'correct') {
|
||||
await this.createReceiptAndAssignPackageNumber(query);
|
||||
await this.navigateToRemissionList(query);
|
||||
} else if (result?.data === 'rescan') {
|
||||
this.searchboxComponent.clear();
|
||||
@@ -90,14 +98,28 @@ export class FinishShippingDocumentComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
async createReceiptAndAssignPackageNumber(packageNumber: string) {
|
||||
const returnDTO = await this._remissionService.getReturn(this.returnId).pipe(first()).toPromise();
|
||||
// const receipt = await this._remissionService.createReceipt(returnDTO, this.receiptId);
|
||||
try {
|
||||
return await this._remissionService.createReceiptAndAssignPackage({
|
||||
returnId: returnDTO.id,
|
||||
receiptId: this.receiptId,
|
||||
packageNumber,
|
||||
});
|
||||
} catch (error) {
|
||||
this._modal.error('Fehler beim Speichern der Wannennummer', error);
|
||||
}
|
||||
}
|
||||
|
||||
addBreadcrumbIfNotExists() {
|
||||
const returnId = +this._activatedRoute.snapshot.params?.returnId;
|
||||
const receiptId = +this._activatedRoute.snapshot.params?.receiptId;
|
||||
const receiptNumber = this._activatedRoute.snapshot.params?.receiptNumber;
|
||||
|
||||
this._breadcrumb.addBreadcrumbIfNotExists({
|
||||
key: this._config.get('process.ids.remission'),
|
||||
name: 'Wannennummer scannen',
|
||||
path: `/filiale/remission/${returnId}/finish-shipping-document/${receiptId}`,
|
||||
path: `/filiale/remission/${returnId}/finish-shipping-document/${receiptNumber}`,
|
||||
params: this._activatedRoute.snapshot.queryParams,
|
||||
section: 'branch',
|
||||
tags: ['remission', 'finish-shipping-document'],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, ChangeDetectionStrategy, Input, OnDestroy } from '@angular/core';
|
||||
import { Component, ChangeDetectionStrategy, Input, OnDestroy, Host } from '@angular/core';
|
||||
import { DomainRemissionService, RemissionListItem } from '@domain/remission';
|
||||
import { RemissionPlacementType } from '@isa/remission';
|
||||
import {
|
||||
@@ -8,12 +8,13 @@ import {
|
||||
ReturnItemDTO,
|
||||
ReturnSuggestionDTO,
|
||||
} from '@swagger/remi';
|
||||
import { DialogModel, UiDialogModalComponent, UiErrorModalComponent, UiModalService } from '@ui/modal';
|
||||
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
|
||||
import { mapFromReturnItemDTO, mapFromReturnSuggestionDTO } from 'apps/domain/remission/src/lib/mappings';
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
import { first, takeUntil } from 'rxjs/operators';
|
||||
import { AddProductToShippingDocumentModalComponent } from '../../modals/add-product-to-shipping-document-modal/add-product-to-shipping-document-modal.component';
|
||||
import { RemissionListComponentStore } from '../remission-list.component-store';
|
||||
import { RemissionListComponent } from '../remission-list.component';
|
||||
|
||||
@Component({
|
||||
selector: 'page-remission-list-item',
|
||||
@@ -52,12 +53,13 @@ export class RemissionListItemComponent implements OnDestroy {
|
||||
return !!this.returnDto && (returnItem?.descendantOf?.enabled || this.item?.dto?.impediment);
|
||||
}
|
||||
|
||||
loading$ = new BehaviorSubject<boolean>(false);
|
||||
loading$ = this._listComponent.remittingItem$.asObservable();
|
||||
|
||||
constructor(
|
||||
private _modal: UiModalService,
|
||||
private _remissionService: DomainRemissionService,
|
||||
private _store: RemissionListComponentStore
|
||||
private _store: RemissionListComponentStore,
|
||||
@Host() private _listComponent: RemissionListComponent
|
||||
) {}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -90,32 +92,14 @@ export class RemissionListItemComponent implements OnDestroy {
|
||||
}
|
||||
|
||||
remit() {
|
||||
const modal = this._modal.open({
|
||||
content: UiDialogModalComponent,
|
||||
title: 'Remittieren',
|
||||
data: {
|
||||
content: `Sie sind gerade dabei alle ${this.item.remissionQuantity} Exemplare von einem ${
|
||||
this.item.placementType && this.item.placementType === 'Stapel' ? 'Stapel' : 'Leistungsplatz'
|
||||
} zu\nremittieren. Sind wirklich alle Exemplare in ${
|
||||
this.item.placementType && this.item.placementType === 'Stapel' ? 'dem Stapel' : 'der Leistung'
|
||||
}?`,
|
||||
handleCommand: false,
|
||||
actions: [
|
||||
{ label: 'Ja', selected: true, command: 'remit' },
|
||||
{ label: 'Abbrechen', command: 'close' },
|
||||
],
|
||||
} as DialogModel,
|
||||
});
|
||||
|
||||
modal.afterClosed$.pipe(takeUntil(this._onDestroy$)).subscribe((result) => {
|
||||
if (result?.data === 'remit') {
|
||||
this.addReturnItemOrSuggestion({ quantity: this.item.remissionQuantity });
|
||||
}
|
||||
});
|
||||
this.addReturnItemOrSuggestion({ quantity: this.item.remissionQuantity });
|
||||
}
|
||||
|
||||
async removeReturnItem() {
|
||||
this.loading$.next(true);
|
||||
if (this._listComponent.remittingItem$.value) {
|
||||
return;
|
||||
}
|
||||
this._listComponent.remittingItem$.next(true);
|
||||
try {
|
||||
await this._remissionService.removeReturnItemFromList({ itemId: this.item?.dto?.id }).toPromise();
|
||||
this._store.removeItem(this.item);
|
||||
@@ -127,7 +111,7 @@ export class RemissionListItemComponent implements OnDestroy {
|
||||
});
|
||||
this.reload();
|
||||
}
|
||||
this.loading$.next(false);
|
||||
this._listComponent.remittingItem$.next(false);
|
||||
}
|
||||
|
||||
async addReturnItemOrSuggestion({
|
||||
@@ -141,7 +125,10 @@ export class RemissionListItemComponent implements OnDestroy {
|
||||
impedimentComment?: string;
|
||||
remainingQuantity?: number;
|
||||
}) {
|
||||
this.loading$.next(true);
|
||||
if (this._listComponent.remittingItem$.value) {
|
||||
return;
|
||||
}
|
||||
this._listComponent.remittingItem$.next(true);
|
||||
try {
|
||||
let response: ValueTupleOfReceiptItemDTOAndReturnItemDTO | ValueTupleOfReceiptItemDTOAndReturnSuggestionDTO;
|
||||
|
||||
@@ -205,11 +192,14 @@ export class RemissionListItemComponent implements OnDestroy {
|
||||
});
|
||||
this.reload();
|
||||
}
|
||||
this.loading$.next(false);
|
||||
this._listComponent.remittingItem$.next(false);
|
||||
}
|
||||
|
||||
async returnImpediment() {
|
||||
this.loading$.next(true);
|
||||
if (this._listComponent.remittingItem$.value) {
|
||||
return;
|
||||
}
|
||||
this._listComponent.remittingItem$.next(true);
|
||||
|
||||
let updatedDto: ReturnItemDTO | ReturnSuggestionDTO;
|
||||
|
||||
@@ -239,7 +229,7 @@ export class RemissionListItemComponent implements OnDestroy {
|
||||
});
|
||||
this.reload();
|
||||
}
|
||||
this.loading$.next(false);
|
||||
this._listComponent.remittingItem$.next(false);
|
||||
}
|
||||
|
||||
reload() {
|
||||
|
||||
@@ -125,6 +125,8 @@ export class RemissionListComponent implements OnInit, OnDestroy {
|
||||
|
||||
showScrollArrow$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
remittingItem$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
constructor(
|
||||
private readonly _remissionListStore: RemissionListComponentStore,
|
||||
private readonly _remissionStore: RemissionComponentStore,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ScrollingModule } from '@angular/cdk/scrolling';
|
||||
import { RemissionListComponent } from './remission-list.component';
|
||||
import { ShellFilterOverlayModule } from '@shell/filter-overlay';
|
||||
import { SharedFilterOverlayModule } from '@shared/components/filter-overlay';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { RemissionFilterModule } from './remission-filter/remission-filter.module';
|
||||
import { RemissionListItemModule } from './remission-list-item';
|
||||
@@ -14,7 +14,7 @@ import { RemissionListItemLoadingModule } from './remission-list-item-loading/re
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
ShellFilterOverlayModule,
|
||||
SharedFilterOverlayModule,
|
||||
UiIconModule,
|
||||
RemissionFilterModule,
|
||||
RemissionListItemModule,
|
||||
|
||||
@@ -23,10 +23,18 @@ const routes: Routes = [
|
||||
path: 'list',
|
||||
component: RemissionListComponent,
|
||||
},
|
||||
{
|
||||
path: ':returnId/list',
|
||||
component: RemissionListComponent,
|
||||
},
|
||||
{
|
||||
path: ':returnId/:packageNumber/list',
|
||||
component: RemissionListComponent,
|
||||
},
|
||||
{
|
||||
path: ':returnId/shipping-document',
|
||||
component: ShippingDocumentDetailsComponent,
|
||||
},
|
||||
{
|
||||
path: ':returnId/:packageNumber/shipping-document',
|
||||
component: ShippingDocumentDetailsComponent,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user