Skip to content

Commit

Permalink
feat: order list filtering (#1571)
Browse files Browse the repository at this point in the history
* filter orders by date range, order number, sku and state
* hide order filter if there are no orders
* load more orders button
* update order include types
* add date range picker formly component
* vertical formly wrapper

Co-authored-by: Dilara Gueler <D.Gueler@intershop.de>
Co-authored-by: Silke <s.grueber@intershop.de>
  • Loading branch information
3 people committed Mar 27, 2024
1 parent 650dcf3 commit 564d5c8
Show file tree
Hide file tree
Showing 30 changed files with 886 additions and 59 deletions.
30 changes: 16 additions & 14 deletions docs/guides/formly.md
Expand Up @@ -254,20 +254,22 @@ Refer to the tables below for an overview of these parts.
- Template option `inputClass`: These CSS class(es) will be added to all input/select/textarea/text tags.
- Template option `ariaLabel`: Adds an aria-label to all input/select/textarea tags.

| Name | Description | Relevant props |
| -------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ish-text-input-field | Basic input field, supports all text types | type: 'text' (default),'email','tel','password' |
| ish-select-field | Basic select field | `options`: `{ value: any; label: string}[]` or Observable. `placeholder`: Translation key or string for the default selection |
| ish-textarea-field | Basic textarea field | `cols` & `rows`: Specifies the dimensions of the textarea |
| ish-checkbox-field | Basic checkbox input | `title`: Title for a checkbox |
| ish-email-field | Email input field that automatically adds an e-mail validator and error messages | ---- |
| ish-password-field | Password input field that automatically adds a password validator and error messages | ---- |
| ish-phone-field | Phone number input field that automatically adds a phone number validator and error messages | ---- |
| ish-fieldset-field | Wraps fields in a `<fieldset>` tag for styling | `fieldsetClass`: Class that will be added to the fieldset tag. `childClass`: Class that will be added to the child div. `legend`: Legend element that will be added to the fieldset, use the value as the legend text. `legendClass`: Class that will be added to the legend tag. |
| ish-captcha-field | Includes the `<ish-lazy-captcha>` component and adds the relevant `formControls` to the form | `topic`: Topic that will be passed to the Captcha component. |
| ish-radio-field | Basic radio input | ---- |
| ish-plain-text-field | Only display the form value | ---- |
| ish-html-text-field | Only display the form value as html | ---- |
| Name | Description | Relevant props |
| --------------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ish-text-input-field | Basic input field, supports all text types | type: 'text' (default),'email','tel','password' |
| ish-select-field | Basic select field | `options`: `{ value: any; label: string}[]` or Observable. `placeholder`: Translation key or string for the default selection |
| ish-textarea-field | Basic textarea field | `cols` & `rows`: Specifies the dimensions of the textarea |
| ish-checkbox-field | Basic checkbox input | `title`: Title for a checkbox |
| ish-email-field | Email input field that automatically adds an e-mail validator and error messages | ---- |
| ish-password-field | Password input field that automatically adds a password validator and error messages | ---- |
| ish-phone-field | Phone number input field that automatically adds a phone number validator and error messages | ---- |
| ish-fieldset-field | Wraps fields in a `<fieldset>` tag for styling | `fieldsetClass`: Class that will be added to the fieldset tag. `childClass`: Class that will be added to the child div. `legend`: Legend element that will be added to the fieldset, use the value as the legend text. `legendClass`: Class that will be added to the legend tag. |
| ish-captcha-field | Includes the `<ish-lazy-captcha>` component and adds the relevant `formControls` to the form | `topic`: Topic that will be passed to the Captcha component. |
| ish-radio-field | Basic radio input | ---- |
| ish-plain-text-field | Only display the form value | ---- |
| ish-html-text-field | Only display the form value as html | ---- |
| ish-date-picker-field | Basic datepicker | `minDays`: Computes the minDate by adding the minimum allowed days to today. `maxDays`: Computes the maxDate by adding the maximum allowed days to today. `isSatExcluded`: Specifies if saturdays can be disabled. `isSunExcluded`: Specifies if sundays can be disabled. |
| ish-date-range-picker-field | Datepicker with range | `minDays`: Computes the minDate by adding the minimum allowed days to today. `maxDays`: Computes the maxDate by adding the maximum allowed days to today. `startDate`: The start date. `placeholder`: Placeholder that displays the date format in the input field. |

### Wrappers

Expand Down
15 changes: 12 additions & 3 deletions src/app/core/facades/account.facade.ts
Expand Up @@ -7,11 +7,11 @@ import { Address } from 'ish-core/models/address/address.model';
import { Credentials } from 'ish-core/models/credentials/credentials.model';
import { Customer, CustomerRegistrationType, SsoRegistrationType } from 'ish-core/models/customer/customer.model';
import { HttpError } from 'ish-core/models/http-error/http-error.model';
import { OrderListQuery } from 'ish-core/models/order-list-query/order-list-query.model';
import { PasswordReminderUpdate } from 'ish-core/models/password-reminder-update/password-reminder-update.model';
import { PasswordReminder } from 'ish-core/models/password-reminder/password-reminder.model';
import { PaymentInstrument } from 'ish-core/models/payment-instrument/payment-instrument.model';
import { User } from 'ish-core/models/user/user.model';
import { OrderListQuery } from 'ish-core/services/order/order.service';
import { MessagesPayloadType } from 'ish-core/store/core/messages';
import { getServerConfigParameter } from 'ish-core/store/core/server-config';
import {
Expand All @@ -30,10 +30,12 @@ import {
getDataRequestLoading,
} from 'ish-core/store/customer/data-requests';
import {
getMoreOrdersAvailable,
getOrders,
getOrdersError,
getOrdersLoading,
getSelectedOrder,
loadMoreOrders,
loadOrders,
} from 'ish-core/store/customer/orders';
import {
Expand Down Expand Up @@ -173,9 +175,16 @@ export class AccountFacade {

// ORDERS

orders$(query?: OrderListQuery) {
orders$ = this.store.pipe(select(getOrders));

loadOrders(query?: OrderListQuery) {
this.store.dispatch(loadOrders({ query: query || { limit: 30 } }));
return this.store.pipe(select(getOrders));
}

moreOrdersAvailable$ = this.store.pipe(select(getMoreOrdersAvailable));

loadMoreOrders() {
this.store.dispatch(loadMoreOrders());
}

selectedOrder$ = this.store.pipe(select(getSelectedOrder));
Expand Down
34 changes: 34 additions & 0 deletions src/app/core/models/order-list-query/order-list-query.model.ts
@@ -0,0 +1,34 @@
export type OrderIncludeType =
| 'all'
| 'buckets'
| 'buckets_discounts'
| 'buckets_shipToAddress'
| 'buckets_shippingMethod'
| 'buyingContext'
| 'commonShipToAddress'
| 'commonShippingMethod'
| 'discounts'
| 'discounts_promotion'
| 'invoiceToAddress'
| 'lineItems'
| 'lineItems_discounts'
| 'lineItems_product'
| 'lineItems_shipToAddress'
| 'lineItems_shippingMethod'
| 'lineItems_warranty'
| 'payments'
| 'payments_paymentInstrument'
| 'payments_paymentMethod';

export interface OrderListQuery {
limit: number;
include?: OrderIncludeType[];
offset?: number;
documentNumber?: string[];
customerOrderID?: string[];
creationDateFrom?: string;
creationDateTo?: string;
lineItem_product?: string[];
lineItem_customerProductID?: string[];
lineItem_partialOrderNo?: string[];
}
3 changes: 2 additions & 1 deletion src/app/core/services/order/order.service.spec.ts
Expand Up @@ -5,13 +5,14 @@ import { provideMockStore } from '@ngrx/store/testing';
import { of } from 'rxjs';
import { anything, capture, instance, mock, verify, when } from 'ts-mockito';

import { OrderListQuery } from 'ish-core/models/order-list-query/order-list-query.model';
import { OrderBaseData } from 'ish-core/models/order/order.interface';
import { Order } from 'ish-core/models/order/order.model';
import { ApiService, AvailableOptions } from 'ish-core/services/api/api.service';
import { getCurrentLocale } from 'ish-core/store/core/configuration';
import { BasketMockData } from 'ish-core/utils/dev/basket-mock-data';

import { OrderListQuery, OrderService, orderListQueryToHttpParams } from './order.service';
import { OrderService, orderListQueryToHttpParams } from './order.service';

describe('Order Service', () => {
let orderService: OrderService;
Expand Down
19 changes: 2 additions & 17 deletions src/app/core/services/order/order.service.ts
Expand Up @@ -5,36 +5,21 @@ import { Store, select } from '@ngrx/store';
import { EMPTY, Observable, of, throwError } from 'rxjs';
import { catchError, concatMap, map, withLatestFrom } from 'rxjs/operators';

import { OrderIncludeType, OrderListQuery } from 'ish-core/models/order-list-query/order-list-query.model';
import { OrderData } from 'ish-core/models/order/order.interface';
import { OrderMapper } from 'ish-core/models/order/order.mapper';
import { Order } from 'ish-core/models/order/order.model';
import { ApiService } from 'ish-core/services/api/api.service';
import { getCurrentLocale } from 'ish-core/store/core/configuration';

type OrderIncludeType =
| 'invoiceToAddress'
| 'commonShipToAddress'
| 'commonShippingMethod'
| 'discounts'
| 'lineItems_discounts'
| 'lineItems'
| 'payments'
| 'payments_paymentMethod'
| 'payments_paymentInstrument';

export interface OrderListQuery {
limit: number;
include?: OrderIncludeType[];
}

export function orderListQueryToHttpParams(query: OrderListQuery): HttpParams {
return Object.entries(query).reduce(
(acc, [key, value]: [keyof OrderListQuery, OrderListQuery[keyof OrderListQuery]]) => {
if (Array.isArray(value)) {
if (key === 'include') {
return acc.set(key, value.join(','));
} else {
return value.reduce((acc, value) => acc.append(key, value.toString()), acc);
return (value as string[]).reduce((acc, value) => acc.append(key, value?.toString()), acc);
}
} else if (value !== undefined) {
return acc.set(key, value.toString());
Expand Down
11 changes: 8 additions & 3 deletions src/app/core/store/customer/orders/orders.actions.ts
@@ -1,8 +1,8 @@
import { Params } from '@angular/router';
import { createAction } from '@ngrx/store';

import { OrderListQuery } from 'ish-core/models/order-list-query/order-list-query.model';
import { Order } from 'ish-core/models/order/order.model';
import { OrderListQuery } from 'ish-core/services/order/order.service';
import { httpError, payload } from 'ish-core/utils/ngrx-creators';

export const createOrder = createAction('[Orders] Create Order');
Expand All @@ -11,11 +11,16 @@ export const createOrderFail = createAction('[Orders API] Create Order Fail', ht

export const createOrderSuccess = createAction('[Orders API] Create Order Success', payload<{ order: Order }>());

export const loadOrders = createAction('[Orders Internal] Load Orders', payload<{ query: OrderListQuery }>());
export const loadOrders = createAction('[Orders] Load Orders', payload<{ query: OrderListQuery }>());

export const loadMoreOrders = createAction('[Orders] Load More Orders');

export const loadOrdersFail = createAction('[Orders API] Load Orders Fail', httpError());

export const loadOrdersSuccess = createAction('[Orders API] Load Orders Success', payload<{ orders: Order[] }>());
export const loadOrdersSuccess = createAction(
'[Orders API] Load Orders Success',
payload<{ orders: Order[]; query: OrderListQuery; allRetrieved?: boolean }>()
);

export const loadOrder = createAction('[Orders Internal] Load Order', payload<{ orderId: string }>());

Expand Down

0 comments on commit 564d5c8

Please sign in to comment.