Commit c10a4af3 authored by oussamasic's avatar oussamasic Committed by Ro3034
Browse files

create customers with customized colors

parent 5c56566c
......@@ -2,7 +2,6 @@ import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms';
import { ColorPickerDirective } from 'ngx-color-picker';
import { hexToRgb, rgbToHsl } from 'ui-frontend-common';
import { ColorErrorEnum } from './color-error.enum';
@Component({
......@@ -23,7 +22,7 @@ export class InputColorComponent implements OnInit {
public colorErrorEnum: typeof ColorErrorEnum = ColorErrorEnum;
public colorError: ColorErrorEnum = ColorErrorEnum.NONE;
constructor() { }
constructor() {}
public ngOnInit(): void {
this.color = this.colorInput.value;
......@@ -85,10 +84,7 @@ export class InputColorComponent implements OnInit {
if (inputValue.length === 3 && pickerValue.length === 6) {
for (let i = 0; i < 3; i++) {
if (
inputValue.charAt(i) !== pickerValue.charAt(2 * i) ||
inputValue.charAt(i) !== pickerValue.charAt(2 * i + 1)
) {
if (inputValue.charAt(i) !== pickerValue.charAt(2 * i) || inputValue.charAt(i) !== pickerValue.charAt(2 * i + 1)) {
continue;
}
return;
......
......@@ -34,22 +34,20 @@
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
import { EMPTY, of } from 'rxjs';
import { ConfirmDialogService, LoggerModule, OtpState } from 'ui-frontend-common';
import { VitamUICommonTestModule } from 'ui-frontend-common/testing';
/* tslint:disable: max-classes-per-file directive-selector */
import { Component, EventEmitter, forwardRef, Input, NO_ERRORS_SCHEMA, Output } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { CountryService } from 'ui-frontend-common';
import { EMPTY, of } from 'rxjs';
import { ConfirmDialogService, CountryService, LoggerModule, OtpState } from 'ui-frontend-common';
import { VitamUICommonTestModule } from 'ui-frontend-common/testing';
import { CustomerService } from '../../core/customer.service';
import { OwnerFormValidators } from '../owner-form/owner-form.validators';
import { OwnerService } from '../owner.service';
......@@ -61,11 +59,13 @@ import { CustomerCreateValidators } from './customer-create.validators';
@Component({
selector: 'app-domains-input',
template: '',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DomainInputStubComponent),
multi: true
}]
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DomainInputStubComponent),
multi: true,
},
],
})
class DomainInputStubComponent implements ControlValueAccessor {
@Input() placeholder: string;
......@@ -81,11 +81,13 @@ class DomainInputStubComponent implements ControlValueAccessor {
@Component({
selector: 'app-owner-form',
template: '',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => OwnerFormStubComponent),
multi: true,
}]
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => OwnerFormStubComponent),
multi: true,
},
],
})
class OwnerFormStubComponent implements ControlValueAccessor {
@Input() customerInfo: any;
......@@ -97,19 +99,20 @@ class OwnerFormStubComponent implements ControlValueAccessor {
@Component({
selector: 'app-customer-colors-input',
template: '',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomerColorsInputStubComponent),
multi: true,
}
]
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomerColorsInputStubComponent),
multi: true,
},
],
})
class CustomerColorsInputStubComponent implements ControlValueAccessor {
@Input() placeholder: string;
@Input() spinnerDiameter = 25;
writeValue() {}
registerOnChange() {}
registerOnTouched() {}
@Input() placeholder: string;
@Input() spinnerDiameter = 25;
writeValue() {}
registerOnChange() {}
registerOnTouched() {}
}
const expectedCustomer = {
......@@ -130,87 +133,86 @@ const expectedCustomer = {
language: 'en',
emailDomains: ['test.com', 'toto.co.uk'],
defaultEmailDomain: 'test.com',
owners: [{
code: '666666',
name: 'Alice Vans',
companyName: 'Vans',
address: {
street: 'street2',
zipCode: '43121',
city: 'Paris',
country: 'FR',
}
}],
owners: [
{
code: '666666',
name: 'Alice Vans',
companyName: 'Vans',
address: {
street: 'street2',
zipCode: '43121',
city: 'Paris',
country: 'FR',
},
},
],
themeColors: {},
gdprAlert : true,
gdprAlertDelay : 72,
gdprAlert: true,
gdprAlertDelay: 72,
portalMessages: {},
portalTitles: {},
tenantName: 'tenantName'
tenantName: 'tenantName',
};
let component: CustomerCreateComponent;
let fixture: ComponentFixture<CustomerCreateComponent>;
class Page {
get submit() { return fixture.nativeElement.querySelector('button[type=submit]'); }
control(name: string) { return fixture.nativeElement.querySelector('[formControlName=' + name + ']'); }
get submit() {
return fixture.nativeElement.querySelector('button[type=submit]');
}
control(name: string) {
return fixture.nativeElement.querySelector('[formControlName=' + name + ']');
}
}
let page: Page;
describe('CustomerCreateComponent', () => {
beforeEach(waitForAsync(() => {
const matDialogRefSpy = jasmine.createSpyObj('MatDialogRef', ['close']);
const customerServiceSpy = jasmine.createSpyObj('CustomerService', { create: of({}) });
const customerCreateValidatorsSpy = jasmine.createSpyObj(
'CustomerCreateValidators',
{ uniqueCode: () => of(null), uniqueDomain: of(null) }
);
const ownerServiceSpy = jasmine.createSpyObj('OwnerService', { create: of({}) });
const ownerFormValidatorsSpy = jasmine.createSpyObj('OwnerFormValidators', { uniqueCode: () => of(null) });
const tenantServiceSpy = jasmine.createSpyObj('TenantService', { getTenantsByCustomerIds: of([]) });
const tenantFormValidatorsSpy = jasmine.createSpyObj('TenantFormValidators', {
uniqueName: () => of(null)
});
TestBed.configureTestingModule({
imports: [
ReactiveFormsModule,
MatFormFieldModule,
MatSelectModule,
MatButtonToggleModule,
MatProgressBarModule,
NoopAnimationsModule,
MatProgressSpinnerModule,
VitamUICommonTestModule,
LoggerModule.forRoot()
],
declarations: [
CustomerCreateComponent,
OwnerFormStubComponent,
CustomerColorsInputStubComponent,
DomainInputStubComponent
],
providers: [
{ provide: MatDialogRef, useValue: matDialogRefSpy },
{ provide: MAT_DIALOG_DATA, useValue: {} },
{ provide: CustomerService, useValue: customerServiceSpy },
{ provide: CustomerCreateValidators, useValue: customerCreateValidatorsSpy },
{ provide: OwnerService, useValue: ownerServiceSpy },
{ provide: OwnerFormValidators, useValue: ownerFormValidatorsSpy },
{ provide: TenantService, useValue: tenantServiceSpy },
{ provide: ConfirmDialogService, useValue: { listenToEscapeKeyPress: () => EMPTY } },
{ provide: TenantFormValidators, useValue: tenantFormValidatorsSpy },
{ provide: CountryService, useValue: { getAvailableCountries: () => EMPTY } },
{ provide : MatDialog , useValue : {} }
],
schemas: [NO_ERRORS_SCHEMA]
beforeEach(
waitForAsync(() => {
const matDialogRefSpy = jasmine.createSpyObj('MatDialogRef', ['close']);
const customerServiceSpy = jasmine.createSpyObj('CustomerService', { create: of({}), getMyCustomer: of({}) });
const customerCreateValidatorsSpy = jasmine.createSpyObj('CustomerCreateValidators', {
uniqueCode: () => of(null),
uniqueDomain: of(null),
});
const ownerServiceSpy = jasmine.createSpyObj('OwnerService', { create: of({}) });
const ownerFormValidatorsSpy = jasmine.createSpyObj('OwnerFormValidators', { uniqueCode: () => of(null) });
const tenantServiceSpy = jasmine.createSpyObj('TenantService', { getTenantsByCustomerIds: of([]) });
const tenantFormValidatorsSpy = jasmine.createSpyObj('TenantFormValidators', {
uniqueName: () => of(null),
});
TestBed.configureTestingModule({
imports: [
ReactiveFormsModule,
MatFormFieldModule,
MatSelectModule,
MatButtonToggleModule,
MatProgressBarModule,
NoopAnimationsModule,
MatProgressSpinnerModule,
VitamUICommonTestModule,
LoggerModule.forRoot(),
],
declarations: [CustomerCreateComponent, OwnerFormStubComponent, CustomerColorsInputStubComponent, DomainInputStubComponent],
providers: [
{ provide: MatDialogRef, useValue: matDialogRefSpy },
{ provide: MAT_DIALOG_DATA, useValue: {} },
{ provide: CustomerService, useValue: customerServiceSpy },
{ provide: CustomerCreateValidators, useValue: customerCreateValidatorsSpy },
{ provide: OwnerService, useValue: ownerServiceSpy },
{ provide: OwnerFormValidators, useValue: ownerFormValidatorsSpy },
{ provide: TenantService, useValue: tenantServiceSpy },
{ provide: ConfirmDialogService, useValue: { listenToEscapeKeyPress: () => EMPTY } },
{ provide: TenantFormValidators, useValue: tenantFormValidatorsSpy },
{ provide: CountryService, useValue: { getAvailableCountries: () => EMPTY } },
{ provide: MatDialog, useValue: {} },
],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();
})
.compileComponents();
}));
);
beforeEach(() => {
fixture = TestBed.createComponent(CustomerCreateComponent);
......@@ -237,8 +239,6 @@ describe('CustomerCreateComponent', () => {
expect(page.control('otp')).toBeTruthy();
expect(page.control('emailDomains')).toBeTruthy();
});
});
describe('Form', () => {
......@@ -252,7 +252,6 @@ describe('CustomerCreateComponent', () => {
});
describe('Validators', () => {
describe('code', () => {
it('should check the code format', () => {
expect(setControlValue('code', '').invalid).toBeTruthy();
......@@ -293,7 +292,6 @@ describe('CustomerCreateComponent', () => {
expect(setControlValue('defaultEmailDomain', '').invalid).toBeTruthy();
expect(setControlValue('defaultEmailDomain', 't').valid).toBeTruthy();
});
});
......@@ -308,17 +306,15 @@ describe('CustomerCreateComponent', () => {
describe('Component', () => {
it('should call dialogRef.close', () => {
const matDialogRef = TestBed.inject(MatDialogRef);
const matDialogRef = TestBed.inject(MatDialogRef);
component.onCancel();
expect(matDialogRef.close).toHaveBeenCalledTimes(1);
});
it('should not call create()', () => {
const customerService = TestBed.inject(CustomerService);
const customerService = TestBed.inject(CustomerService);
component.onSubmit();
expect(customerService.create).toHaveBeenCalledTimes(0);
});
});
});
......@@ -34,33 +34,30 @@
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
import { merge, Observable, Subject } from 'rxjs';
import {ConfirmDialogService, CountryOption, CountryService, Customer, Logo, OtpState } from 'ui-frontend-common';
import { ComponentType } from '@angular/cdk/portal';
import { Component, Inject, OnDestroy, OnInit, TemplateRef } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { ComponentType } from '@angular/cdk/portal';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { merge, Observable, Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';
import { ConfirmDialogService, CountryOption, CountryService, Customer, Logo, OtpState } from 'ui-frontend-common';
import { CustomerService } from '../../core/customer.service';
import { TenantFormValidators } from '../tenant-create/tenant-form.validators';
import { CustomerAlertingComponent } from './customer-alerting/customer-alerting.component';
import { CustomerCreateValidators } from './customer-create.validators';
interface CustomerInfo {
code: string;
name: string;
companyName: string;
code: string;
name: string;
companyName: string;
}
@Component({
selector: 'app-customer-create',
templateUrl: './customer-create.component.html',
styleUrls: ['./customer-create.component.scss']
styleUrls: ['./customer-create.component.scss'],
})
export class CustomerCreateComponent implements OnInit, OnDestroy {
private destroy = new Subject();
public form: FormGroup;
public hasError = true;
......@@ -74,7 +71,9 @@ export class CustomerCreateComponent implements OnInit, OnDestroy {
public stepIndex = 0;
public stepCount = 6;
private _customerForm: FormGroup;
public get customerForm(): FormGroup { return this._customerForm; }
public get customerForm(): FormGroup {
return this._customerForm;
}
public set customerForm(form: FormGroup) {
this._customerForm = form;
}
......@@ -82,7 +81,9 @@ export class CustomerCreateComponent implements OnInit, OnDestroy {
// tslint:disable-next-line: variable-name
private _homepageMessageForm: FormGroup;
public get homepageMessageForm(): FormGroup { return this._homepageMessageForm; }
public get homepageMessageForm(): FormGroup {
return this._homepageMessageForm;
}
public set homepageMessageForm(form: FormGroup) {
this._homepageMessageForm = form;
}
......@@ -99,6 +100,8 @@ export class CustomerCreateComponent implements OnInit, OnDestroy {
public countries: CountryOption[];
customer: Customer;
constructor(
public dialogRef: MatDialogRef<CustomerCreateComponent>,
@Inject(MAT_DIALOG_DATA) public data: any,
......@@ -108,20 +111,15 @@ export class CustomerCreateComponent implements OnInit, OnDestroy {
private confirmDialogService: ConfirmDialogService,
private matDialog: MatDialog,
private tenantFormValidators: TenantFormValidators,
private countryService: CountryService,
) {
}
private countryService: CountryService
) {}
ngOnInit() {
this.form = this.formBuilder.group({
gdprAlert: true,
gdprAlertDelay: [72, Validators.min(1)],
enabled: [true, Validators.required],
code: [
null,
[Validators.required, Validators.pattern(/^[0-9]{4,25}$/)],
this.customerCreateValidators.uniqueCode(),
],
code: [null, [Validators.required, Validators.pattern(/^[0-9]{4,25}$/)], this.customerCreateValidators.uniqueCode()],
name: [null, Validators.required],
companyName: [null, Validators.required],
passwordRevocationDelay: 6,
......@@ -130,7 +128,7 @@ export class CustomerCreateComponent implements OnInit, OnDestroy {
street: [null, Validators.required],
zipCode: [null, Validators.required],
city: [null, Validators.required],
country: ['FR', Validators.required]
country: ['FR', Validators.required],
}),
internalCode: [null],
language: ['FRENCH', Validators.required],
......@@ -140,16 +138,10 @@ export class CustomerCreateComponent implements OnInit, OnDestroy {
themeColors: [null],
portalMessages: [null],
portalTitles: [null],
owners: this.formBuilder.array([
this.formBuilder.control(null, Validators.required),
]),
tenantName: [
null,
[Validators.required],
this.tenantFormValidators.uniqueName(),
]
owners: this.formBuilder.array([this.formBuilder.control(null, Validators.required)]),
tenantName: [null, [Validators.required], this.tenantFormValidators.uniqueName()],
});
if(this.data){
if (this.data) {
this.gdprReadOnlyStatus = this.data.gdprReadOnlySettingStatus;
}
this.form.get('gdprAlert').valueChanges.subscribe(() => {
......@@ -158,11 +150,16 @@ export class CustomerCreateComponent implements OnInit, OnDestroy {
}
});
this.customerService.getMyCustomer().subscribe((customerDetails) => {
this.customer = customerDetails;
});
this.onChanges();
this.confirmDialogService.listenToEscapeKeyPress(this.dialogRef)
.pipe(takeUntil(this.destroy))
.subscribe(() => this.onCancel());
this.confirmDialogService
.listenToEscapeKeyPress(this.dialogRef)
.pipe(takeUntil(this.destroy))
.subscribe(() => this.onCancel());
this.countryService.getAvailableCountries().subscribe((values: CountryOption[]) => {
this.countries = values;
......@@ -174,18 +171,15 @@ export class CustomerCreateComponent implements OnInit, OnDestroy {
}
onChanges() {
merge(
this.form.get('code').valueChanges,
this.form.get('name').valueChanges,
this.form.get('companyName').valueChanges,
)
.subscribe(() => {
this.customerInfo = {
code: this.form.get('code').value,
name: this.form.get('name').value,
companyName: this.form.get('companyName').value,
};
});
merge(this.form.get('code').valueChanges, this.form.get('name').valueChanges, this.form.get('companyName').valueChanges).subscribe(
() => {
this.customerInfo = {
code: this.form.get('code').value,
name: this.form.get('name').value,
companyName: this.form.get('companyName').value,
};
}
);
}
getOwnerName(): string {
......@@ -201,45 +195,55 @@ export class CustomerCreateComponent implements OnInit, OnDestroy {
}
confirm(componentOrTemplateRef: TemplateRef<unknown> | ComponentType<unknown>): Observable<boolean> {
return this.matDialog.open(componentOrTemplateRef, { panelClass: 'vitamui-dialog' }).beforeClosed().pipe(
filter((result) => !result)
);
return this.matDialog
.open(componentOrTemplateRef, { panelClass: 'vitamui-dialog' })
.beforeClosed()
.pipe(filter((result) => !result));
}
onSubmit() {
if (this.lastStepIsInvalid() || this.stepIndex !== this.stepCount - 1) { return; }
if (this.lastStepIsInvalid() || this.stepIndex !== this.stepCount - 1) {
return;
}
this.creating = true;
const customer: Customer = this.updateForCustomerModel(this.form.value);
this.customerService.create(customer, this.logos)
this.customerService
.create(customer, this.logos)
.pipe(takeUntil(this.destroy))
.subscribe(
() => {
this.dialogRef.close(true);
},
(error) => {
this.creating = false;
console.error(error);
});
() => {
this.dialogRef.close(true);
},
(error) => {
this.creating = false;
console.error(error);
}
);
}
private updateForCustomerModel(formValue: any): Customer {
let customer = formValue;
if (this.customerForm && this.customerForm.get('hasCustomGraphicIdentity').value === true) {
customer = {...formValue, ...{
hasCustomGraphicIdentity: this.customerForm.get('hasCustomGraphicIdentity').value,
themeColors: this.customerForm.get('themeColors').value,
}};
customer = {
...formValue,
...{
hasCustomGraphicIdentity: this.customerForm.get('hasCustomGraphicIdentity').value,
themeColors: this.customerForm.get('themeColors').value,
},
};
}