#1437 #1420 HFI Customer Details History

This commit is contained in:
Nino Righi
2021-03-08 11:23:30 +01:00
committed by Lorenz Hilpert
parent d17b19689e
commit bacf1bec37
24 changed files with 486 additions and 24 deletions

View File

@@ -1976,6 +1976,46 @@
}
}
}
},
"@modal/history": {
"projectType": "library",
"root": "apps/modal/history",
"sourceRoot": "apps/modal/history/src",
"prefix": "modal",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:ng-packagr",
"options": {
"tsConfig": "apps/modal/history/tsconfig.lib.json",
"project": "apps/modal/history/ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "apps/modal/history/tsconfig.lib.prod.json"
}
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "apps/modal/history/src/test.ts",
"tsConfig": "apps/modal/history/tsconfig.spec.json",
"karmaConfig": "apps/modal/history/karma.conf.js"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"apps/modal/history/tsconfig.lib.json",
"apps/modal/history/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "sales"

View File

@@ -0,0 +1,25 @@
# History
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.2.
## Code scaffolding
Run `ng generate component component-name --project history` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project history`.
> Note: Don't forget to add `--project history` or else it will be added to the default project in your `angular.json` file.
## Build
Run `ng build history` to build the project. The build artifacts will be stored in the `dist/` directory.
## Publishing
After building your library with `ng build history`, go to the dist folder `cd dist/history` and run `npm publish`.
## Running unit tests
Run `ng test history` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

View File

@@ -0,0 +1,32 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma'),
],
client: {
clearContext: false, // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../../../coverage/modal/history'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true,
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true,
});
};

View File

@@ -0,0 +1,7 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/modal/history",
"lib": {
"entryFile": "src/apps/modal.ts"
}
}

View File

@@ -0,0 +1,11 @@
{
"name": "@modal/history",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^10.1.2",
"@angular/core": "^10.1.2"
},
"dependencies": {
"tslib": "^2.0.0"
}
}

View File

@@ -0,0 +1,52 @@
<div class="wrapper">
<div class="actions">
<button class="close-btn" (click)="ref.close()">
<ui-icon icon="close" size="21px"></ui-icon>
</button>
</div>
<h2>Historie</h2>
<div class="customer">
<div class="row">
<span class="label">Kundenname</span>
<strong>{{ ref.data.lastName }}, {{ ref.data.firstName }}</strong>
</div>
<div class="row">
<span class="label">Kundennummer</span>
<strong>{{ ref.data.customerNumber }}</strong>
</div>
</div>
<hr />
<div class="scroll-container">
<div *ngFor="let history of history$ | async; first as isFirst; last as isLast" class="content-wrapper">
<div class="log-entry" [class.last]="isLast" [class.first]="isFirst">
<span class="timeline-dot"></span>
<div class="row details header">
<div *ngIf="history.changed">{{ history.changed | date }} | {{ history.changed | date: 'shortTime' }} Uhr</div>
<div *ngIf="history.location">| {{ history.location }}</div>
<div *ngIf="history.changedBy">| {{ history.changedBy }}</div>
</div>
<div class="row details title">
Kundendaten wurden geändert
</div>
<br />
<div *ngFor="let values of history?.values" class="row details changes">
<p>{{ values.caption }}:</p>
<p class="changes-gap">
<strong>{{ values.value }} </strong>(neu)
</p>
<p *ngIf="values.previousValue">
<strong>{{ values.previousValue }} </strong>(alt)
</p>
</div>
</div>
</div>
<div *ngIf="spinner$ | async" class="loading-spinner">
<ui-spinner [show]="true"></ui-spinner>
</div>
<div *ngIf="historyError$ | async">
<h3 class="error">
Abruf der Historie fehlgeschlagen.
</h3>
</div>
</div>
</div>

View File

@@ -0,0 +1,146 @@
@import 'variables';
$offset: 10px;
$line-top-offset: 3px;
$dot-size: 16px;
$dot-size-lg: 20px;
$border-size: 1px;
$border-size-cover: 2px;
:host {
@apply bg-white;
}
.actions {
@apply flex flex-row justify-end;
}
.close-btn {
@apply bg-transparent border-none text-ucla-blue;
}
h2 {
@apply mt-0 font-bold text-center text-card-sub;
}
.row {
@apply w-full flex flex-row flex-grow items-center px-2 my-2;
.label {
width: 150px;
}
}
hr {
height: 2px;
@apply bg-disabled-customer my-6;
margin-left: -1rem;
width: calc(100% + 2rem);
}
.error {
@apply text-warning text-center;
}
.loading-spinner {
@apply p-8;
}
.scroll-container {
@apply overflow-y-scroll overflow-x-hidden mr-10 mb-8;
max-height: 800px;
}
.scroll-container::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.1);
border-radius: 10px;
background-color: $isa-light-blue-platinum;
}
.scroll-container::-webkit-scrollbar {
width: 12px;
background-color: white;
}
.scroll-container::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
background-color: #0f2942;
}
.content-wrapper {
@apply flex flex-col pl-2 pr-9 mb-10;
}
.details {
@apply my-0;
}
.title {
@apply font-bold text-lg;
}
.changes {
@apply flex flex-row my-0;
p {
@apply m-0;
}
.changes-gap {
@apply mx-1;
}
}
.log-entry {
position: relative;
// calculate offset relative to container offset (22px)
padding-left: calc(70px - 22px);
&:before {
content: '';
position: absolute;
height: calc(100% + 40px);
width: 1px;
top: $line-top-offset;
left: $offset;
border: $border-size solid $isa-light-blue-platinum;
background: $isa-light-blue-platinum;
}
&.last:before {
height: 30%;
border: $border-size-cover solid #fff;
background: #fff;
left: calc(#{$offset} - #{$border-size-cover});
}
.timeline-dot {
position: absolute;
top: 0;
left: $offset;
background: #fff;
width: 2px;
&:before {
content: '';
position: absolute;
background: $isa-light-blue-platinum;
top: $line-top-offset;
left: calc((#{$dot-size} - #{$line-top-offset}) / -2);
border-radius: 50%;
width: $dot-size;
height: $dot-size;
}
}
&.first {
.timeline-dot:before {
width: $dot-size-lg;
height: $dot-size-lg;
background: $isa-neutral-info;
left: calc(#{$dot-size} / -2);
}
}
}

View File

@@ -0,0 +1,35 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { CrmCustomerService } from '@domain/crm';
import { HistoryDTO } from '@swagger/crm';
import { UiModalRef } from '@ui/modal';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
@Component({
selector: 'lib-history',
templateUrl: 'history.component.html',
styleUrls: ['history.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HistoryComponent {
historyError$ = new BehaviorSubject<boolean>(false);
spinner$ = new BehaviorSubject<boolean>(true);
history$: Observable<HistoryDTO> = this.customerService.getCustomerHistory(this.ref.data.customerId).pipe(
tap((response) => console.log(response.result)),
map((response) => {
this.spinner$.next(false);
return response.result;
}),
catchError(() => {
this.historyError$.next(true);
this.spinner$.next(false);
return of();
})
);
constructor(
public ref: UiModalRef<any, { customerId: number; customerNumber: string; lastName: string; firstName: string }>,
private customerService: CrmCustomerService
) {}
}

View File

@@ -0,0 +1,13 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { UiIconModule } from '@ui/icon';
import { UiModalModule } from '@ui/modal';
import { UiSpinnerModule } from 'apps/ui/spinner/src/lib/ui-spinner.module';
import { HistoryComponent } from './history.component';
@NgModule({
declarations: [HistoryComponent],
imports: [CommonModule, UiModalModule, UiIconModule, UiSpinnerModule],
exports: [HistoryComponent],
})
export class HistoryModule {}

View File

@@ -0,0 +1,6 @@
/*
* Public API Surface of history
*/
export * from './lib/history.module';
export * from './lib/history.component';

View File

@@ -0,0 +1,24 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone';
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
declare const require: {
context(
path: string,
deep?: boolean,
filter?: RegExp
): {
keys(): string[];
<T>(id: string): T;
};
};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

View File

@@ -0,0 +1,25 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "../../../out-tsc/lib",
"target": "es2015",
"declaration": true,
"declarationMap": true,
"inlineSources": true,
"types": [],
"lib": [
"dom",
"es2018"
]
},
"angularCompilerOptions": {
"skipTemplateCodegen": true,
"strictMetadataEmit": true,
"enableResourceInlining": true
},
"exclude": [
"src/test.ts",
"**/*.spec.ts"
]
}

View File

@@ -0,0 +1,10 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.lib.json",
"compilerOptions": {
"declarationMap": false
},
"angularCompilerOptions": {
"enableIvy": false
}
}

View File

@@ -0,0 +1,17 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "../../../out-tsc/spec",
"types": [
"jasmine"
]
},
"files": [
"src/test.ts"
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}

View File

@@ -0,0 +1,17 @@
{
"extends": "../../../tslint.json",
"rules": {
"directive-selector": [
true,
"attribute",
"lib",
"camelCase"
],
"component-selector": [
true,
"element",
"lib",
"kebab-case"
]
}
}

View File

@@ -8,9 +8,9 @@
<div class="card-customer-details">
<div class="header-container">
<h1 class="title">{{ (customerType$ | async) === 'b2b' ? 'Firmendetails' : 'Kundendetails' }}</h1>
<!-- <a class="button-customer-history">
<button (click)="openHistory()" class="button-customer-history">
Historie
</a> -->
</button>
</div>
<p class="info">Sind Ihre {{ (customerType$ | async) === 'b2b' ? 'Firmendaten' : 'Kundendaten' }} korrekt?</p>
<div class="tags">

View File

@@ -105,7 +105,7 @@ ui-inline-input {
@apply relative;
}
a.button-customer-history {
.button-customer-history {
@apply text-card-sub bg-transparent text-brand border-none font-bold rounded-full absolute right-0 top-0 py-px-5;
}

View File

@@ -2,7 +2,6 @@ import { Component, ChangeDetectionStrategy, OnInit, ChangeDetectorRef } from '@
import { ActivatedRoute, Router } from '@angular/router';
import { ApplicationService, ProcessService } from '@core/application';
import { Breadcrumb, BreadcrumbService } from '@core/breadcrumb';
import { CartService } from '@domain/cart';
import { DomainCheckoutService } from '@domain/checkout';
import { AddressHelper, AssignedPayerHelper, CrmCustomerService } from '@domain/crm';
import { BuyerDTO, PayerDTO as CheckoutPayerDTO, ShippingAddressDTO as CheckoutShippingAddressDTO } from '@swagger/checkout';
@@ -14,6 +13,7 @@ import {
} from '@swagger/crm';
import { UiModalService } from '@ui/modal';
import { ShippingAddressHelper } from 'apps/domain/crm/src/lib/helpers/shipping-address.helper';
import { HistoryComponent } from 'apps/modal/history/src/lib/history.component';
import { Observable } from 'rxjs';
import { first, map, shareReplay, switchMap } from 'rxjs/operators';
import { CantAddCustomerToCartModalComponent } from '../modals/cant-add-customer-to-cart-modal/cant-add-customer-to-cart.component';
@@ -152,6 +152,23 @@ export class CustomerDetailsComponent implements OnInit {
this.breadcrumb.patchBreadcrumb(this.currentBreadcrumb.id, { name: name.filter((n) => !!n).join(' ') });
}
async openHistory() {
const customer = await this.customer$.pipe(first()).toPromise();
const customerId = await this.customerId$.pipe(first()).toPromise();
const customerNumber = customer.customerNumber;
const lastName = customer.lastName;
const firstName = customer.firstName;
this.modal.open({
content: HistoryComponent,
data: {
customerId,
customerNumber,
lastName,
firstName,
},
});
}
async continue() {
this.showSpinner = true;
const customer = await this.customer$.pipe(first()).toPromise();

View File

@@ -28,8 +28,8 @@ import { CustomerOrdersComponent } from './customer-orders/customer-orders.compo
import { UiCommonModule } from '@ui/common';
import { CustomerOrderDetailsComponent } from './customer-order-details/customer-order-details.component';
import { CustomerOrderItemCardComponent } from './customer-order-details/order-item-card/customer-order-item-card.component';
import { CustomerHistoryComponent } from './customer-history/customer-history.component';
import { UiSpinnerModule } from 'apps/ui/spinner/src/lib/ui-spinner.module';
import { HistoryModule } from '@modal/history';
@NgModule({
imports: [
CommonModule,
@@ -44,6 +44,7 @@ import { UiSpinnerModule } from 'apps/ui/spinner/src/lib/ui-spinner.module';
UiRadioModule,
UiCommonModule,
UiSpinnerModule,
HistoryModule,
],
exports: [CustomerDetailsComponent],
declarations: [
@@ -65,7 +66,6 @@ import { UiSpinnerModule } from 'apps/ui/spinner/src/lib/ui-spinner.module';
CustomerOrdersComponent,
CustomerOrderDetailsComponent,
CustomerOrderItemCardComponent,
CustomerHistoryComponent,
],
})
export class CustomerDetailsModule {}

View File

@@ -1,13 +0,0 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
@Component({
selector: 'page-customer-history',
templateUrl: 'customer-history.component.html',
styleUrls: ['customer-history.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CustomerHistoryComponent implements OnInit {
constructor() {}
ngOnInit(): void {}
}

View File

@@ -23,7 +23,6 @@ import { CustomerSearchMainComponent } from './customer-search/search-main/searc
import { CustomerSearchResultComponent } from './customer-search/search-results/search-results.component';
import { CustomerCreateGuard } from './guards/customer-create.guard';
import { PageCustomerComponent } from './page-customer.component';
import { CustomerHistoryComponent } from './customer-details/customer-history/customer-history.component';
import { CustomerOrderDetailsComponent } from './customer-details/customer-order-details/customer-order-details.component';
const routes: Routes = [
@@ -60,10 +59,6 @@ const routes: Routes = [
canActivate: [CustomerCardGuard],
component: CustomerCardComponent,
},
{
path: ':customerId/history',
component: CustomerHistoryComponent,
},
{
path: ':customerId/orders',
component: CustomerOrdersComponent,

View File

@@ -185,6 +185,9 @@
],
"@modal/printer": [
"apps/modal/printer/src/public-api.ts"
],
"@modal/history": [
"apps/modal/history/src/public-api.ts"
]
}
}