Skip to content

Commit

Permalink
feat: implement switch component and use it for the active status of …
Browse files Browse the repository at this point in the history
…recurring orders
  • Loading branch information
suschneider authored and shauke committed Aug 23, 2024
1 parent 5d21abd commit d4125b1
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 16 deletions.
4 changes: 4 additions & 0 deletions src/app/core/facades/account.facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ export class AccountFacade {
recurringOrdersError$ = this.store.pipe(select(getRecurringOrdersError));
selectedRecurringOrder$ = this.store.pipe(select(getSelectedRecurringOrder));

switchActiveStatusRecurringOrder(recurringOrderId: string, active: boolean) {
this.store.dispatch(recurringOrdersActions.updateRecurringOrder({ recurringOrderId, active }));
}

// PAYMENT

private eligiblePaymentMethods$ = this.store.pipe(select(getUserPaymentMethods));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { iif, map, switchMap, take } from 'rxjs';
import { iif, map, switchMap, take, throwError } from 'rxjs';

import { RecurringOrderData, RecurringOrderLinkData } from 'ish-core/models/recurring-order/recurring-order.interface';
import { RecurringOrderMapper } from 'ish-core/models/recurring-order/recurring-order.mapper';
Expand Down Expand Up @@ -48,4 +48,28 @@ export class RecurringOrdersService {
)
);
}

updateRecurringOrder(recurringOrderId: string, active: boolean) {
if (!recurringOrderId) {
return throwError(() => new Error('updateRecurringOrder() called without recurringOrderId'));
}
return this.currentCustomer$.pipe(
switchMap(customer =>
iif(
() => customer.isBusinessCustomer,
this.apiService
.b2bUserEndpoint()
.put<RecurringOrderData>(`recurringorders/${this.apiService.encodeResourceId(recurringOrderId)}`, {
active,
}),
this.apiService.put<RecurringOrderData>(
`privatecustomers/${this.apiService.encodeResourceId(
customer.customerNo
)}/recurringorders/${this.apiService.encodeResourceId(recurringOrderId)}`,
{ active }
)
).pipe(map(data => RecurringOrderMapper.fromData(data)))
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const recurringOrdersActions = createActionGroup({
events: {
'Load Recurring Orders': emptyProps(),
'Load Recurring Order': payload<{ recurringOrderId: string }>(),
'Update Recurring Order': payload<{ recurringOrderId: string; active: boolean }>(),
},
});

Expand All @@ -18,5 +19,7 @@ export const recurringOrdersApiActions = createActionGroup({
'Load Recurring Orders Fail': httpError<{}>(),
'Load Recurring Order Success': payload<{ recurringOrder: RecurringOrder }>(),
'Load Recurring Order Fail': httpError<{}>(),
'Update Recurring Order Success': payload<{ recurringOrder: RecurringOrder }>(),
'Update Recurring Order Fail': httpError<{}>(),
},
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Store, select } from '@ngrx/store';
import { map, switchMap } from 'rxjs/operators';
import { map, mergeMap, switchMap } from 'rxjs/operators';

import { RecurringOrdersService } from 'ish-core/services/recurring-orders/recurring-orders.service';
import { selectRouteParam } from 'ish-core/store/core/router';
import { mapErrorToAction, mapToPayloadProperty, whenTruthy } from 'ish-core/utils/operators';
import { mapErrorToAction, mapToPayload, mapToPayloadProperty, whenTruthy } from 'ish-core/utils/operators';

import { recurringOrdersActions, recurringOrdersApiActions } from './recurring-orders.actions';

Expand Down Expand Up @@ -49,4 +49,18 @@ export class RecurringOrdersEffects {
map(recurringOrderId => recurringOrdersActions.loadRecurringOrder({ recurringOrderId }))
)
);

updateProductNotification$ = createEffect(() =>
this.actions$.pipe(
ofType(recurringOrdersActions.updateRecurringOrder),
mapToPayload(),
whenTruthy(),
mergeMap(payload =>
this.recurringOrdersService.updateRecurringOrder(payload.recurringOrderId, payload.active).pipe(
mergeMap(recurringOrder => [recurringOrdersApiActions.updateRecurringOrderSuccess({ recurringOrder })]),
mapErrorToAction(recurringOrdersApiActions.updateRecurringOrderFail)
)
)
)
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,11 @@
<ng-container cdkColumnDef="actions">
<th cdk-header-cell *cdkHeaderCellDef data-testing-id="th-order-actions"></th>
<td cdk-cell *cdkCellDef="let recurringOrder" class="column-price text-nowrap">
<span class="custom-control custom-switch d-inline">
<input type="checkbox" class="custom-control-input" />
<label class="custom-control-label" for="customSwitch1"></label>
</span>
<!-- Delete -->
<button
type="button"
class="btn-tool btn-link"
title="{{ 'account.costcenter.delete.link' | translate }}"
data-testing-id="delete-cost-center"
>
<fa-icon [icon]="['fas', 'trash-alt']" />
</button>
<ish-switch
id="{{ recurringOrder.id }}"
[active]="recurringOrder.active"
(switchActiveStatus)="switchActiveStatus($event)"
/>
</td>
</ng-container>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';

import { AccountFacade } from 'ish-core/facades/account.facade';
import { RecurringOrder } from 'ish-core/models/recurring-order/recurring-order.model';

export type RecurringOrderColumnsType =
Expand All @@ -19,4 +20,10 @@ export type RecurringOrderColumnsType =
export class RecurringOrderListComponent {
@Input() recurringOrders: RecurringOrder[];
@Input() columnsToDisplay: RecurringOrderColumnsType[];

constructor(private accountFacade: AccountFacade) {}

switchActiveStatus(recurringOrder: { id: string; active: boolean }) {
this.accountFacade.switchActiveStatusRecurringOrder(recurringOrder.id, recurringOrder.active);
}
}
12 changes: 12 additions & 0 deletions src/app/shared/components/common/switch/switch.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<span class="custom-control custom-switch d-inline">
<input
[formControl]="activeSwitch"
type="checkbox"
role="switch"
class="custom-control-input"
id="{{ id }}"
[ngModel]="active"
(ngModelChange)="switchActive(id, $event)"
/>
<label class="custom-control-label" for="{{ id }}">{{ label }}</label>
</span>
15 changes: 15 additions & 0 deletions src/app/shared/components/common/switch/switch.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@import 'variables';

.custom-control-input ~ .custom-control-label::before {
background-color: #999;
border-color: #999;
}

.custom-control-input:checked ~ .custom-control-label::before {
background-color: $color-corporate;
border-color: $color-corporate;
}

.custom-switch .custom-control-label::after {
background-color: #fff;
}
27 changes: 27 additions & 0 deletions src/app/shared/components/common/switch/switch.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { SwitchComponent } from './switch.component';

describe('Switch Component', () => {
let component: SwitchComponent;
let fixture: ComponentFixture<SwitchComponent>;
let element: HTMLElement;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [SwitchComponent],
}).compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(SwitchComponent);
component = fixture.componentInstance;
element = fixture.nativeElement;
});

it('should be created', () => {
expect(component).toBeTruthy();
expect(element).toBeTruthy();
expect(() => fixture.detectChanges()).not.toThrow();
});
});
22 changes: 22 additions & 0 deletions src/app/shared/components/common/switch/switch.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
selector: 'ish-switch',
templateUrl: './switch.component.html',
styleUrls: ['./switch.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SwitchComponent {
@Input({ required: true }) id: string;
@Input() active = false;
@Input() label = '';

@Output() switchActiveStatus = new EventEmitter<{ id: string; active: boolean }>();

activeSwitch: FormControl = new FormControl();

switchActive(id: string, active: boolean) {
this.switchActiveStatus.emit({ id, active });
}
}
2 changes: 2 additions & 0 deletions src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ import { ModalDialogLinkComponent } from './components/common/modal-dialog-link/
import { ModalDialogComponent } from './components/common/modal-dialog/modal-dialog.component';
import { PagingComponent } from './components/common/paging/paging.component';
import { SuccessMessageComponent } from './components/common/success-message/success-message.component';
import { SwitchComponent } from './components/common/switch/switch.component';
import { FilterCheckboxComponent } from './components/filter/filter-checkbox/filter-checkbox.component';
import { FilterCollapsibleComponent } from './components/filter/filter-collapsible/filter-collapsible.component';
import { FilterDropdownComponent } from './components/filter/filter-dropdown/filter-dropdown.component';
Expand Down Expand Up @@ -321,6 +322,7 @@ const exportedComponents = [
PromotionRemoveComponent,
SearchBoxComponent,
SuccessMessageComponent,
SwitchComponent,
];

@NgModule({
Expand Down

0 comments on commit d4125b1

Please sign in to comment.