#680 [Filter] Statusleiste

This commit is contained in:
Sebastian
2020-06-25 10:28:11 +02:00
parent 7aa258ac9e
commit 6930f44633
17 changed files with 491 additions and 122 deletions

View File

@@ -3,7 +3,6 @@
.breadacrumb-grid {
display: grid;
grid-template-columns: min-content auto;
margin-bottom: 7px;
grid-gap: 15px;
height: 40px;
position: relative;

View File

@@ -2,6 +2,7 @@
<app-breadcrumbs *ngIf="showBreadCrumbs$ | async"> </app-breadcrumbs>
<app-filter-button
[active]="isFilterActive$ | async"
[module]="activeModule$ | async"
*ngIf="showFilter$ | async"
(toggleFilter)="toggleFilter()"
></app-filter-button>

View File

@@ -3,6 +3,8 @@ $filter-width: 106px;
.container {
display: flex;
align-items: center;
margin-top: 8px;
margin-bottom: 16px;
app-breadcrumbs {
flex-grow: 1;

View File

@@ -1,14 +1,8 @@
import {
Component,
ChangeDetectionStrategy,
Input,
OnInit,
} from '@angular/core';
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { RemissionOverlayService } from '../../modules/remission/services/remission-overlay.service';
import { RemissionSelectors } from '../../core/store/selectors/remission.selectors';
import { Select } from '@ngxs/store';
import { map } from 'rxjs/operators';
import { ContentHeaderService } from '../../core/services';
@Component({
selector: 'app-content-header',
@@ -20,23 +14,21 @@ export class ContentHeaderComponent implements OnInit {
@Select(RemissionSelectors.getRemissionActiveFilters)
remissionFilters$: Observable<string[]>;
@Input() showFilter$: Observable<boolean>;
@Input() showBreadCrumbs$: Observable<boolean>;
showFilter$: Observable<boolean>;
showBreadCrumbs$: Observable<boolean>;
isFilterActive$: Observable<boolean>;
activeModule$: Observable<'Customer' | 'Branch'>;
constructor(private remissionOverlayService: RemissionOverlayService) {}
constructor(private contentHeaderService: ContentHeaderService) {}
ngOnInit() {
this.isFilterActive$ = this.remissionFilters$.pipe(
map(
(selectedFilters) =>
selectedFilters && !!Object.entries(selectedFilters).length
)
);
this.showFilter$ = this.contentHeaderService.showFilter$;
this.showBreadCrumbs$ = this.contentHeaderService.showBreadcrumbs$;
this.isFilterActive$ = this.contentHeaderService.isFilterActive$;
this.activeModule$ = this.contentHeaderService.module$;
}
toggleFilter() {
this.remissionOverlayService.openRemissionListFilter();
this.contentHeaderService.toggleFilter();
}
}

View File

@@ -0,0 +1,5 @@
import { TestBed } from '@angular/core/testing';
describe('ContentHeaderService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
});

View File

@@ -0,0 +1,127 @@
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map, switchMap, filter, startWith } from 'rxjs/operators';
import { LocationService } from './location-service';
import { RemissionOverlayService } from '../../modules/remission/services';
import { Select } from '@ngxs/store';
import { RemissionSelectors } from '../store/selectors/remission.selectors';
import { SearchStateFacade } from '../../store/customer';
import { isNullOrUndefined } from 'util';
import { SharedSelectors } from '../store/selectors/shared.selectors';
@Injectable({ providedIn: 'root' })
export class ContentHeaderService {
@Select(RemissionSelectors.getRemissionActiveFilters)
remissionFilters$: Observable<string[]>;
@Select(SharedSelectors.getActiveModule)
activeModule$: Observable<{ id: number; name: 'Customer' | 'Branch' }>;
whiteList = {
breadcrumbs: [],
filter: ['/remission/create', '/remission/started', '/shelf'],
};
blackList = { breadcrumbs: ['/dashboard', '/branch/main'], filter: [] };
constructor(
private locationService: LocationService,
private searchStore: SearchStateFacade,
private remissionOverlayService: RemissionOverlayService
) {}
get showBreadcrumbs$(): Observable<boolean> {
return this.locationService.currentPath$.pipe(this.shouldShowBreadcrumbs);
}
get showFilter$(): Observable<boolean> {
return this.locationService.currentPath$.pipe(this.shouldShowFilter);
}
get isFilterActive$(): Observable<boolean> {
return this.activeSection$.pipe(
switchMap((activeSection) => {
let filters$: Observable<string[]> = of([]);
switch (activeSection) {
case 'remission':
filters$ = this.remissionFilters$;
break;
case 'shelf':
filters$ = this.searchStore.currentSearchProcessFilters$.pipe(
filter((filters) => !isNullOrUndefined(filters)),
map((filters) =>
Object.values(filters).reduce(
(acc, curr) => [...acc, ...curr],
[]
)
),
// To ensure if no filter is set on process that filter is inactive
startWith([])
);
break;
default:
return of(false);
}
return filters$.pipe(
map(
(selectedFilters) =>
selectedFilters && !!Object.entries(selectedFilters).length
)
);
})
);
}
get module$(): Observable<'Customer' | 'Branch'> {
return this.activeModule$.pipe(map((module) => module.name));
}
get activeSection$(): Observable<'remission' | 'shelf'> {
return this.locationService.currentPath$.pipe(
map((url) => {
if (url.includes('remission')) {
return 'remission';
}
if (url.includes('shelf')) {
return 'shelf';
}
})
);
}
toggleFilter() {
return this.remissionOverlayService.openRemissionListFilter();
}
shouldShowBreadcrumbs = (url: Observable<string>): Observable<boolean> => {
return url.pipe(map((path) => this.isAllowed('breadcrumbs', path)));
};
shouldShowFilter = (url: Observable<string>): Observable<boolean> => {
return url.pipe(map((path) => this.isAllowed('filter', path)));
};
private isAllowed(type: 'breadcrumbs' | 'filter', url: string): boolean {
const applicableWhitelist = this.whiteList[type];
const applicableBlacklist = this.blackList[type];
if (type === 'filter') {
const isOnWhiteList = !!applicableWhitelist.find(
(whitelistetUrl) =>
whitelistetUrl.includes(url) || url.includes(whitelistetUrl)
);
return isOnWhiteList;
}
if (type === 'breadcrumbs') {
const isOnBlackList = !!applicableBlacklist.find(
(blacklistetUrl) =>
blacklistetUrl.includes(url) || url.includes(blacklistetUrl)
);
return !isOnBlackList;
}
}
}

View File

@@ -4,6 +4,7 @@ export * from './branch.service';
export * from './checkout.service';
export * from './clipboard.service';
export * from './collecting-shelf.service';
export * from './content-header.service';
export * from './customer.service';
export * from './dashboard-feed.service';
export * from './filter.service';

View File

@@ -1,6 +1,9 @@
import { Selector, StateContext, createSelector } from '@ngxs/store';
import { CustomerState, CustomerStateModel } from '../state/customer.state';
import { BreadcrumbsState, BreadcrumbsStateModel } from '../state/breadcrumbs.state';
import {
BreadcrumbsState,
BreadcrumbsStateModel,
} from '../state/breadcrumbs.state';
import { ProcessStateModel, ProcessState } from '../state/process.state';
import { EditCustomerData } from '../../models/edit-customer.model';
import { CartState, CartStateModel } from '../state/cart.state';
@@ -16,19 +19,31 @@ import { CartEntryStateModel, CartEntryState } from '../state/cart-entry.state';
import { BranchesStateModel, BranchState } from '../state/branches.state';
import { Cart } from '../../models/cart.model';
import { DisplayOrderDTO, DisplayOrderItemDTO } from '@swagger/oms';
import { DeliveryType, DeliveryOption } from '../../models/delivery-option.model';
import {
DeliveryType,
DeliveryOption,
} from '../../models/delivery-option.model';
import { OrderItem } from '../../models/order-item';
import { ProcessCartConfirmed } from '../../models/process-cart-confirmed.model';
import { User } from '../../models/user.model';
import { FilterItem } from '../../models/filter-item.model';
import { CollectingShelfState, CollectingShelfStateModel } from '../state/collecting-shelf.state';
import { mapToIterable, undefinedToEmptyStringOrValue } from '../../utils/app.utils';
import {
CollectingShelfState,
CollectingShelfStateModel,
} from '../state/collecting-shelf.state';
import {
mapToIterable,
undefinedToEmptyStringOrValue,
} from '../../utils/app.utils';
import { CollectingShelfOrder } from '../../models/collecting-shelf-order.model';
import { ItemDTO } from '@swagger/cat';
import { Process } from '../../models/process.model';
import { isNullOrUndefined } from 'util';
import { FilterType } from '../../models/filter-type.enum';
import { BranchProcessState, BranchProcessStateModel } from '../state/branch-process.state';
import {
BranchProcessState,
BranchProcessStateModel,
} from '../state/branch-process.state';
import { ModuleSwitcher } from '../../models/app-switcher.enum';
import { BranchProcess } from '../../models/branch-process.model';
@@ -56,10 +71,18 @@ export class SharedSelectors {
const currentProcessId = state.currentProcesssId;
const currentProcess = process.processes[currentProcessId];
if (currentProcess && currentProcessId && breadcrumbs.activeCrumbs && breadcrumbs.activeCrumbs[currentProcessId]) {
if (
currentProcess &&
currentProcessId &&
breadcrumbs.activeCrumbs &&
breadcrumbs.activeCrumbs[currentProcessId]
) {
const activeCrumbs = breadcrumbs.activeCrumbs[currentProcessId];
const currentBreadcrumbs = breadcrumbs.processesBreadcrumbs[activeCrumbs].find((t) => t.processId === currentProcessId);
const detailsCustomer = customer.customers[currentProcess.detailsCustomer];
const currentBreadcrumbs = breadcrumbs.processesBreadcrumbs[
activeCrumbs
].find((t) => t.processId === currentProcessId);
const detailsCustomer =
customer.customers[currentProcess.detailsCustomer];
return {
processId: currentProcessId,
customer: detailsCustomer,
@@ -71,7 +94,11 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState, CustomerState])
static getActiveCustomer(state: AppStateModel, process: ProcessStateModel, customer: CustomerStateModel): User {
static getActiveCustomer(
state: AppStateModel,
process: ProcessStateModel,
customer: CustomerStateModel
): User {
const currentProcessId = state.currentProcesssId;
const currentProcess = process.processes[currentProcessId];
@@ -83,7 +110,11 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState, CustomerState])
static getFinishedOrderCustomer(state: AppStateModel, process: ProcessStateModel, customer: CustomerStateModel): User {
static getFinishedOrderCustomer(
state: AppStateModel,
process: ProcessStateModel,
customer: CustomerStateModel
): User {
const currentProcessId = state.currentProcesssId;
const currentProcess = process.processes[currentProcessId];
@@ -95,7 +126,11 @@ export class SharedSelectors {
}
@Selector([ProcessState, CartState, CartEntryState])
static getCartTabData(process: ProcessStateModel, cartState: CartStateModel, cartEntriesState: CartEntryStateModel) {
static getCartTabData(
process: ProcessStateModel,
cartState: CartStateModel,
cartEntriesState: CartEntryStateModel
) {
return (processId: number) => {
if (process && processId) {
const currentProcess = process.processes[processId];
@@ -121,7 +156,12 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState, CartState, CartEntryState])
static cartHasItemsFor(state: AppStateModel, process: ProcessStateModel, cart: CartStateModel, cartEntry: CartEntryStateModel) {
static cartHasItemsFor(
state: AppStateModel,
process: ProcessStateModel,
cart: CartStateModel,
cartEntry: CartEntryStateModel
) {
return (option: DeliveryOption) => {
let found = false;
const currentProcessId = state.currentProcesssId;
@@ -147,7 +187,12 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState, CartState, CartEntryState])
static cartHasDownloadForProcess(state: AppStateModel, process: ProcessStateModel, cart: CartStateModel, cartEntry: CartEntryStateModel) {
static cartHasDownloadForProcess(
state: AppStateModel,
process: ProcessStateModel,
cart: CartStateModel,
cartEntry: CartEntryStateModel
) {
let found = false;
const currentProcessId = state.currentProcesssId;
if (currentProcessId && process && process.processes) {
@@ -171,7 +216,11 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState, CartState])
static cartEntriesOfCurrentProcessCart(state: AppStateModel, process: ProcessStateModel, cart: CartStateModel) {
static cartEntriesOfCurrentProcessCart(
state: AppStateModel,
process: ProcessStateModel,
cart: CartStateModel
) {
const currentProcessId = state.currentProcesssId;
if (currentProcessId) {
const currentProcess = process.processes[currentProcessId];
@@ -201,12 +250,19 @@ export class SharedSelectors {
if (entryId) {
const entry = cartEntry.cartEntries[entryId];
if (entry && entry.bookId) {
const currentProcessArticles = product.products[currentProcessId];
const currentProcessArticles =
product.products[currentProcessId];
if (currentProcessArticles) {
if (currentProcessArticles && currentProcessArticles[entry.bookId]) {
if (
currentProcessArticles &&
currentProcessArticles[entry.bookId]
) {
const article = currentProcessArticles[entry.bookId];
if (article && article.product && article.product.format) {
if (article.product.format === 'EB' || article.product.format === 'DL') {
if (
article.product.format === 'EB' ||
article.product.format === 'DL'
) {
response.push(article.id);
}
}
@@ -222,7 +278,12 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState, CartState, CartEntryState, ProductState])
static cartHasItems(state: AppStateModel, process: ProcessStateModel, cart: CartStateModel, cartEntry: CartEntryStateModel): boolean {
static cartHasItems(
state: AppStateModel,
process: ProcessStateModel,
cart: CartStateModel,
cartEntry: CartEntryStateModel
): boolean {
const currentProcessId = state.currentProcesssId;
let response = false;
if (currentProcessId) {
@@ -244,7 +305,15 @@ export class SharedSelectors {
return response;
}
@Selector([AppState, ProcessState, CartState, CustomerState, ProductState, CartEntryState, BranchState])
@Selector([
AppState,
ProcessState,
CartState,
CustomerState,
ProductState,
CartEntryState,
BranchState,
])
static getCart(
state: AppStateModel,
process: ProcessStateModel,
@@ -271,7 +340,9 @@ export class SharedSelectors {
cartEntries.forEach((cartEntryId: number) => {
const cartEntry = cartEntriesState.cartEntries[cartEntryId];
const book = products[cartEntry.bookId];
const branch = branches[cartEntry.branch] ? branches[cartEntry.branch] : null;
const branch = branches[cartEntry.branch]
? branches[cartEntry.branch]
: null;
promotionPoints += book.promoPoints * cartEntry.quantity;
cartData.push({
cartId: cartId,
@@ -301,7 +372,11 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState, CustomerState])
static currentCustomer(state: AppStateModel, process: ProcessStateModel, customer: CustomerStateModel): User {
static currentCustomer(
state: AppStateModel,
process: ProcessStateModel,
customer: CustomerStateModel
): User {
const currentProcess = process.processes[state.currentProcesssId];
if (!currentProcess) {
return;
@@ -310,7 +385,10 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState])
static getCurrentCartId(appState: AppStateModel, processState: ProcessStateModel) {
static getCurrentCartId(
appState: AppStateModel,
processState: ProcessStateModel
) {
const processId = appState.currentProcesssId;
if (processId) {
const currentProcess = processState.processes[processId];
@@ -322,17 +400,28 @@ export class SharedSelectors {
}
@Selector([AppState, FilterState])
static getSelectedFilterItems(state: AppStateModel, filterState: FilterStateModel): Filter[] {
static getSelectedFilterItems(
state: AppStateModel,
filterState: FilterStateModel
): Filter[] {
const currentProcessId = state.currentProcesssId;
if (currentProcessId) {
const filterType = filterState.filterType[currentProcessId];
const processesSelectedFilters =
filterType === FilterType.Negative ? filterState.negativeProcessesSelectedFilters : filterState.processesSelectedFilters;
const currentProcessSelectedFilters = processesSelectedFilters.find((f) => f.processId === currentProcessId);
filterType === FilterType.Negative
? filterState.negativeProcessesSelectedFilters
: filterState.processesSelectedFilters;
const currentProcessSelectedFilters = processesSelectedFilters.find(
(f) => f.processId === currentProcessId
);
if (currentProcessSelectedFilters) {
const filter: Filter[] = [];
currentProcessSelectedFilters.selectedFilters.map((f) => {
if (f.items && f.items.filter((t) => t.selected === true) && f.items.filter((t) => t.selected === true).length > 0) {
if (
f.items &&
f.items.filter((t) => t.selected === true) &&
f.items.filter((t) => t.selected === true).length > 0
) {
filter.push(f);
}
});
@@ -345,15 +434,24 @@ export class SharedSelectors {
}
@Selector([AppState, FilterState])
static getProcessFilters(state: AppStateModel, filterState: FilterStateModel): Filter[] {
static getProcessFilters(
state: AppStateModel,
filterState: FilterStateModel
): Filter[] {
const currentProcessId = state.currentProcesssId;
if (currentProcessId) {
const filterType = filterState.filterType[currentProcessId];
const processesSelectedFilters =
filterType === FilterType.Negative ? filterState.negativeProcessesSelectedFilters : filterState.processesSelectedFilters;
const currentProcessSelectedFilters = processesSelectedFilters.find((f) => f.processId === currentProcessId);
return currentProcessSelectedFilters ? currentProcessSelectedFilters.selectedFilters : null;
filterType === FilterType.Negative
? filterState.negativeProcessesSelectedFilters
: filterState.processesSelectedFilters;
const currentProcessSelectedFilters = processesSelectedFilters.find(
(f) => f.processId === currentProcessId
);
return currentProcessSelectedFilters
? currentProcessSelectedFilters.selectedFilters
: null;
}
}
@@ -368,7 +466,11 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState, CustomerState, BreadcrumbsState])
static getSearchedCustomers(state: AppStateModel, process: ProcessStateModel, customer: CustomerStateModel): CustomerSearchResult {
static getSearchedCustomers(
state: AppStateModel,
process: ProcessStateModel,
customer: CustomerStateModel
): CustomerSearchResult {
const processId = state.currentProcesssId;
const currentProcess = process.processes[processId];
@@ -387,7 +489,10 @@ export class SharedSelectors {
}
@Selector([AppState, ProductState])
static getSearchedProducts(state: AppStateModel, products: ProductStateModel): ProductSearchResult {
static getSearchedProducts(
state: AppStateModel,
products: ProductStateModel
): ProductSearchResult {
const currentProcessId = state.currentProcesssId;
if (currentProcessId) {
@@ -402,13 +507,23 @@ export class SharedSelectors {
}
@Selector([AppState, BreadcrumbsState])
static getBreadcrumbs(state: AppStateModel, breadcrumbs: BreadcrumbsStateModel): Breadcrumb[] {
static getBreadcrumbs(
state: AppStateModel,
breadcrumbs: BreadcrumbsStateModel
): Breadcrumb[] {
const activeModule = state.activeModule;
const currentProcessId = activeModule === ModuleSwitcher.Customer ? state.currentProcesssId : -1;
const currentProcessId =
activeModule === ModuleSwitcher.Customer ? state.currentProcesssId : -1;
if (currentProcessId && breadcrumbs.activeCrumbs && breadcrumbs.activeCrumbs[currentProcessId]) {
if (
currentProcessId &&
breadcrumbs.activeCrumbs &&
breadcrumbs.activeCrumbs[currentProcessId]
) {
const activeCrumbs = breadcrumbs.activeCrumbs[currentProcessId];
const currentBreadcrumbs = breadcrumbs.processesBreadcrumbs[activeCrumbs].find((t) => t.processId === currentProcessId);
const currentBreadcrumbs = breadcrumbs.processesBreadcrumbs[
activeCrumbs
].find((t) => t.processId === currentProcessId);
return currentBreadcrumbs ? currentBreadcrumbs.breadcrumbs : null;
}
@@ -416,11 +531,19 @@ export class SharedSelectors {
}
@Selector([AppState, BreadcrumbsState])
static getPreviousRoute(state: AppStateModel, breadcrumbs: BreadcrumbsStateModel): { crumb: string; path: string } {
static getPreviousRoute(
state: AppStateModel,
breadcrumbs: BreadcrumbsStateModel
): { crumb: string; path: string } {
const activeModule = state.activeModule;
const currentProcessId = activeModule === ModuleSwitcher.Customer ? state.currentProcesssId : -1;
const currentProcessId =
activeModule === ModuleSwitcher.Customer ? state.currentProcesssId : -1;
if (currentProcessId && breadcrumbs.previusMenuPath && breadcrumbs.previusMenuPath[currentProcessId]) {
if (
currentProcessId &&
breadcrumbs.previusMenuPath &&
breadcrumbs.previusMenuPath[currentProcessId]
) {
const previousPath = breadcrumbs.previusMenuPath[currentProcessId];
if (previousPath && previousPath[previousPath.length - 1]) {
return previousPath[previousPath.length - 1];
@@ -431,7 +554,10 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState])
static getConfirmedCart(state: AppStateModel, process: ProcessStateModel): ProcessCartConfirmed {
static getConfirmedCart(
state: AppStateModel,
process: ProcessStateModel
): ProcessCartConfirmed {
const processId = state.currentProcesssId;
const currentProcess = process.processes[processId];
@@ -454,9 +580,13 @@ export class SharedSelectors {
if (order.orderType === DeliveryType['Branch']) {
targetBranchName = order.targetBranch.name;
// tslint:disable-next-line: max-line-length
targetBranchAddress = `${undefinedToEmptyStringOrValue(order.targetBranch.address.street)} ${undefinedToEmptyStringOrValue(
targetBranchAddress = `${undefinedToEmptyStringOrValue(
order.targetBranch.address.street
)} ${undefinedToEmptyStringOrValue(
order.targetBranch.address.streetNumber
)}, ${undefinedToEmptyStringOrValue(order.targetBranch.address.zipCode)} ${undefinedToEmptyStringOrValue(
)}, ${undefinedToEmptyStringOrValue(
order.targetBranch.address.zipCode
)} ${undefinedToEmptyStringOrValue(
order.targetBranch.address.city
)}`;
}
@@ -466,7 +596,8 @@ export class SharedSelectors {
if (item.promotion) {
promotionPoints += item.quantity * item.promotion.points;
}
const isDownload = item.product.format === 'EB' || item.product.format === 'DL';
const isDownload =
item.product.format === 'EB' || item.product.format === 'DL';
const orderItem: OrderItem = {
id: +item.product.catalogProductNumber,
orderId: order.id,
@@ -477,7 +608,8 @@ export class SharedSelectors {
currency: item.price.value.currency,
price: item.price.value.value,
imgUrl: item.product.ean,
isTakeNow: item.subsetItems[0].supplierLabel === 'F' ? true : false,
isTakeNow:
item.subsetItems[0].supplierLabel === 'F' ? true : false,
isDownload: isDownload,
orderDate: item.orderDate,
targetBranchName: targetBranchName,
@@ -485,19 +617,26 @@ export class SharedSelectors {
};
if (order.orderType === DeliveryType['ShippingAddress']) {
orderItem.deliveryDate = item.subsetItems[0].estimatedShippingDate;
orderItem.deliveryDate =
item.subsetItems[0].estimatedShippingDate;
}
if (order.orderType === DeliveryType['Branch']) {
orderItem.pickUpDate = item.subsetItems[0].estimatedShippingDate;
orderItem.pickUpDate =
item.subsetItems[0].estimatedShippingDate;
}
cartData.push(orderItem);
});
});
const takeNowItems = cartData.filter((item: OrderItem) => item.isTakeNow);
const pickUpItems = cartData.filter((item: OrderItem) => !item.isTakeNow && item.orderType === DeliveryType['Branch']);
const takeNowItems = cartData.filter(
(item: OrderItem) => item.isTakeNow
);
const pickUpItems = cartData.filter(
(item: OrderItem) =>
!item.isTakeNow && item.orderType === DeliveryType['Branch']
);
// Prepare object for components
return {
@@ -507,8 +646,16 @@ export class SharedSelectors {
totalQuantity: totalQuantity,
cartId: currentProcess.cartId,
orderIds: orderIds,
isTakeNowOnly: takeNowItems && cartData && takeNowItems.length === cartData.length ? true : false,
isPickUpOnly: pickUpItems && cartData && pickUpItems.length === cartData.length ? true : false,
isTakeNowOnly:
takeNowItems &&
cartData &&
takeNowItems.length === cartData.length
? true
: false,
isPickUpOnly:
pickUpItems && cartData && pickUpItems.length === cartData.length
? true
: false,
promotionPoints: promotionPoints,
};
}
@@ -525,24 +672,36 @@ export class SharedSelectors {
const currentProcessId = state.currentProcesssId;
const currentProcessIds = state.processIds;
return { currentProcessId: currentProcessId, currentProcessIds: currentProcessIds };
return {
currentProcessId: currentProcessId,
currentProcessIds: currentProcessIds,
};
}
@Selector([AppState, FilterState])
static getFilters(appState: AppStateModel, state: FilterStateModel): Filter[] {
static getFilters(
appState: AppStateModel,
state: FilterStateModel
): Filter[] {
const currenProcessId = appState.currentProcesssId;
const filterType = state.filterType[currenProcessId];
const processesSelectedFilters =
filterType === FilterType.Negative ? state.negativeProcessesSelectedFilters : state.processesSelectedFilters;
filterType === FilterType.Negative
? state.negativeProcessesSelectedFilters
: state.processesSelectedFilters;
const processFilters = processesSelectedFilters[currenProcessId];
return state.filters.map((filter) => {
return <Filter>{
...filter,
items: filter.items.map((item) => {
if (processFilters) {
const selectedFilter = processFilters.selectedFilters.find((f) => f.id === filter.id);
const selectedFilter = processFilters.selectedFilters.find(
(f) => f.id === filter.id
);
if (selectedFilter) {
const selectedItem = selectedFilter.items.find((i) => i.id === item.id);
const selectedItem = selectedFilter.items.find(
(i) => i.id === item.id
);
if (selectedItem) {
return <FilterItem>{ ...item, selected: selectedItem.selected };
} else {
@@ -600,7 +759,10 @@ export class SharedSelectors {
}
@Selector([AppState, CollectingShelfState])
static getIterableOrderForCurrentProcess(appState: AppStateModel, orderState: CollectingShelfStateModel): CollectingShelfOrder[] {
static getIterableOrderForCurrentProcess(
appState: AppStateModel,
orderState: CollectingShelfStateModel
): CollectingShelfOrder[] {
const currenProcessId = appState.currentProcesssId;
if (!currenProcessId) {
return [];
@@ -618,7 +780,10 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState])
static getProcessSelectedItem(appState: AppStateModel, process: ProcessStateModel): ItemDTO {
static getProcessSelectedItem(
appState: AppStateModel,
process: ProcessStateModel
): ItemDTO {
const currenProcessId = appState.currentProcesssId;
if (!currenProcessId) {
return;
@@ -627,7 +792,11 @@ export class SharedSelectors {
}
@Selector([AppState, ProcessState, CustomerState])
static getCurrentProcessDetailsCustomer(appState: AppStateModel, processes: ProcessStateModel, customers: CustomerStateModel) {
static getCurrentProcessDetailsCustomer(
appState: AppStateModel,
processes: ProcessStateModel,
customers: CustomerStateModel
) {
const currentProcessId = appState.currentProcesssId;
if (!currentProcessId) {
return;
@@ -648,4 +817,16 @@ export class SharedSelectors {
}
return filterState.filterType[currentProcessId];
}
@Selector([AppState])
static getActiveModule(appState: AppStateModel) {
const activeModule = appState.activeModule;
const module = {
id: activeModule,
name: !activeModule ? 'Customer' : 'Branch',
};
return module;
}
}

View File

@@ -1,5 +1,5 @@
<div class="content-body">
<app-content-header [showFilter$]="showFilter$" [showBreadCrumbs$]="showBreadcrumbs$"></app-content-header>
<app-content-header></app-content-header>
<router-outlet></router-outlet>
<div style="height: 97px;"></div>
</div>

View File

@@ -16,13 +16,16 @@ import { RemissionStartedLeaveDialogComponent } from '../../modules/remission/co
@Component({
selector: 'app-content',
templateUrl: './content.component.html',
styleUrls: ['./content.component.scss']
styleUrls: ['./content.component.scss'],
})
export class ContentPageComponent implements OnInit, OnDestroy {
@ViewChild(ErrorComponent, { static: false }) element: ErrorComponent;
@ViewChild(RemissionStartedLeaveDialogComponent, { static: false }) remissionStartedLeaveDialog: RemissionStartedLeaveDialogComponent;
@ViewChild(RemissionLeaveDialogComponent, { static: false }) remissionLeavingDialog: RemissionLeaveDialogComponent;
@ViewChild(RemissionReminderDialogComponent, { static: false }) remissionReminderDialog: RemissionReminderDialogComponent;
@ViewChild(RemissionStartedLeaveDialogComponent, { static: false })
remissionStartedLeaveDialog: RemissionStartedLeaveDialogComponent;
@ViewChild(RemissionLeaveDialogComponent, { static: false })
remissionLeavingDialog: RemissionLeaveDialogComponent;
@ViewChild(RemissionReminderDialogComponent, { static: false })
remissionReminderDialog: RemissionReminderDialogComponent;
module: ModuleSwitcher = ModuleSwitcher.Customer;
destroy$ = new Subject();
showBreadcrumbs$: Observable<boolean>;
@@ -30,58 +33,49 @@ export class ContentPageComponent implements OnInit, OnDestroy {
constructor(
private errorService: ErrorService,
private locationService: LocationService,
private moduleSwitcherService: ModuleSwitcherService,
private appService: AppService
) {
this.errorService
.getErrors()
.pipe(takeUntil(this.destroy$))
.subscribe(errors => {
.subscribe((errors) => {
this.element.openErrorModal(errors);
});
this.appService.openStartedRemissionLeavingDialog$.pipe(takeUntil(this.destroy$)).subscribe(() => {
this.remissionStartedLeaveDialog.openDialog();
});
this.appService.openStartedRemissionLeavingDialog$
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
this.remissionStartedLeaveDialog.openDialog();
});
this.appService.leavingRemission$.pipe(takeUntil(this.destroy$)).subscribe(() => {
this.remissionLeavingDialog.openDialog();
});
this.appService.leavingRemission$
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
this.remissionLeavingDialog.openDialog();
});
this.appService.remissionReminder$.pipe(takeUntil(this.destroy$)).subscribe(() => {
this.remissionReminderDialog.openDialog();
});
this.appService.remissionReminder$
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
this.remissionReminderDialog.openDialog();
});
}
ngOnInit() {
this.moduleSwitcherService.moduleSwitcher$
.pipe(
takeUntil(this.destroy$),
distinctUntilChanged((prev, curr) => (prev && curr ? prev === curr : false))
distinctUntilChanged((prev, curr) =>
prev && curr ? prev === curr : false
)
)
.subscribe((activeModule: ModuleSwitcher) => {
this.module = activeModule;
});
this.initView()
}
ngOnDestroy(): void {
this.destroy$.next();
}
initView() {
this.showBreadcrumbs$ = this.locationService.currentPath$.pipe(this.shouldShowBreadcrumbs);
this.showFilter$ = this.locationService.currentPath$.pipe(this.shouldShowFilter);
}
private shouldShowBreadcrumbs(url: Observable<string>): Observable<boolean> {
return url.pipe(map(path =>
path !== '/dashboard' && path !== '/' && path !== '/branch/main'))
}
private shouldShowFilter(url: Observable<string>): Observable<boolean> {
return url.pipe(map(path => path === '/remission/create' || path === '/remission/started'))
}
}

View File

@@ -3,7 +3,11 @@ import { Store } from '@ngrx/store';
import { Store as NgxsStore } from '@ngxs/store';
import * as actions from './search.actions';
import { SharedSelectors } from 'apps/sales/src/app/core/store/selectors/shared.selectors';
import { map, first } from 'rxjs/operators';
import { map, first, take, switchMap, filter } from 'rxjs/operators';
import { from, Observable } from 'rxjs';
import { selectSearchProcessById } from './search.selectors';
import { SearchProcess } from './defs';
import { isNullOrUndefined } from 'util';
@Injectable({ providedIn: 'root' })
export class SearchStateFacade {
@@ -13,12 +17,29 @@ export class SearchStateFacade {
return this.ngxsStore
.select(SharedSelectors.getCurrentProcess)
.pipe(
filter((currentProcess) => !isNullOrUndefined(currentProcess)),
map((currentProcess) => currentProcess.id),
first()
)
.toPromise();
}
get currentSearchProcess$(): Observable<SearchProcess> {
return from(this.getProcessId()).pipe(
take(1),
switchMap((processId) =>
this.store.select(selectSearchProcessById, processId)
)
);
}
get currentSearchProcessFilters$(): Observable<{ [key: string]: string[] }> {
return this.currentSearchProcess$.pipe(
filter((process) => !isNullOrUndefined(process)),
map((process) => process.filters)
);
}
async setInput(input: string, id?: number) {
if (id) {
return this.store.dispatch(actions.setInput({ input, id }));

View File

@@ -1,7 +1,33 @@
import { createSelector } from '@ngrx/store';
import { selectShelfState } from '../shelf.selectors';
import { searchStateAdapter } from './search.state';
import { SearchProcess } from './defs';
export const selectSearchState = createSelector(
selectShelfState,
(s) => s.search
);
export const { selectAll } = searchStateAdapter.getSelectors();
export const selectAllSearchProcesses = createSelector(
selectSearchState,
selectAll
);
export const selectSearchProcessById = createSelector(
selectAllSearchProcesses,
(s: SearchProcess[], processId: number) =>
s.find((searchProcess) => searchProcess.id === processId)
);
export const selectSearchProcessFiltersById = createSelector(
selectAllSearchProcesses,
(s: SearchProcess[], processId: number) => {
const searchProcess = s.find((p) => p.id === processId);
if (searchProcess) {
return searchProcess.filters;
}
}
);

View File

@@ -14,6 +14,8 @@ $text-black: #000000;
$isa-red: #f70400;
$isa-white: #ffffff;
$isa-lightgray: #e2e2e2;
$isa-customer-active: #59647a;
$isa-customer-active: #1f466c;
/* LAYOUT */
$layout-border-radius: 5px;

View File

@@ -1,4 +1,13 @@
<div class="container" (click)="toggleFilter.emit()" [class.active]="active">
<lib-icon class="icon" width="20px" [name]="active ? 'Icon_Filter_active' : 'Icon_Filter'"></lib-icon>
<p class="text" >Filter</p>
<div
class="container"
(click)="toggleFilter.emit()"
[class.active]="active"
[class.customer]="module === 'Customer'"
>
<lib-icon
class="icon"
width="20px"
[name]="active ? 'Icon_Filter_active' : 'Icon_Filter'"
></lib-icon>
<p class="text">Filter</p>
</div>

View File

@@ -10,8 +10,12 @@
width: 106px;
&.active {
background: rgba(89, 100, 112, 1);
background: #59647a;
color: rgba(255, 255, 255, 1);
&.customer {
background: #1f466c;
}
}
.icon {

View File

@@ -1,15 +1,21 @@
import { Component, ChangeDetectionStrategy, Output, EventEmitter, Input } from '@angular/core';
import {
Component,
ChangeDetectionStrategy,
Output,
EventEmitter,
Input,
} from '@angular/core';
@Component({
selector: 'app-filter-button',
templateUrl: 'filter-button.component.html',
styleUrls: ['./filter-button.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FilterButtonComponent {
@Input() active = false;
@Input() module: 'Branch' | 'Customer' = 'Branch';
@Output() toggleFilter = new EventEmitter();
constructor() { }
constructor() {}
}

View File

@@ -3,10 +3,9 @@ import { CommonModule } from '@angular/common';
import { IconModule } from '../icon';
import { FilterButtonComponent } from './filter-button.component';
@NgModule({
imports: [CommonModule, IconModule],
exports: [FilterButtonComponent],
declarations: [FilterButtonComponent],
})
export class FilterButtonModule { }
export class FilterButtonModule {}