[DEV] remove cmmon
This commit is contained in:
parent
93f0915574
commit
d7112e0208
@ -1,3 +0,0 @@
|
|||||||
<div>
|
|
||||||
<img height="50px" [src]="getImage()"/>
|
|
||||||
</div>
|
|
@ -1,68 +0,0 @@
|
|||||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
|
||||||
import { PasswordEntryComponent } from './async-status-component';
|
|
||||||
|
|
||||||
describe('PasswordEntryComponent global test', () => {
|
|
||||||
let component: PasswordEntryComponent;
|
|
||||||
let fixture: ComponentFixture<PasswordEntryComponent>;
|
|
||||||
let input: HTMLInputElement;
|
|
||||||
let button: HTMLButtonElement;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [PasswordEntryComponent],
|
|
||||||
}).compileComponents();
|
|
||||||
fixture = TestBed.createComponent(PasswordEntryComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
input = fixture.nativeElement.querySelector('div').querySelector('input');
|
|
||||||
button = fixture.nativeElement.querySelector('div').querySelector('button');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Test mode password (default)', () => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual('');
|
|
||||||
expect(button.textContent).toEqual('visibility_off');
|
|
||||||
expect(input.type).toEqual('password');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Test mode text', () => {
|
|
||||||
component.passwordVisibility = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual('');
|
|
||||||
expect(button.textContent).toEqual('visibility');
|
|
||||||
expect(input.type).toEqual('text');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('test click on hide button', fakeAsync(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(false);
|
|
||||||
button.click();
|
|
||||||
tick();
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(true);
|
|
||||||
expect(button.textContent).toEqual('visibility');
|
|
||||||
expect(input.type).toEqual('text');
|
|
||||||
button.click();
|
|
||||||
tick();
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(false);
|
|
||||||
expect(button.textContent).toEqual('visibility_off');
|
|
||||||
expect(input.type).toEqual('password');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('Set password', fakeAsync(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(false);
|
|
||||||
let tmpData = 'My beautifull Password';
|
|
||||||
input.value = tmpData;
|
|
||||||
input.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual(tmpData);
|
|
||||||
expect(component.value).toEqual(tmpData);
|
|
||||||
tmpData = '';
|
|
||||||
input.value = tmpData;
|
|
||||||
input.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual(tmpData);
|
|
||||||
expect(component.value).toEqual(tmpData);
|
|
||||||
}));
|
|
||||||
});
|
|
@ -1,37 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
import { Component, Input } from '@angular/core';
|
|
||||||
|
|
||||||
export enum AsyncActionState {
|
|
||||||
IDLE = "idle",
|
|
||||||
LOADING = "loading",
|
|
||||||
DONE = "done",
|
|
||||||
FAIL = "fail",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-async-status-component',
|
|
||||||
templateUrl: 'async-status-component.html',
|
|
||||||
styleUrls: ['async-status-component.less'],
|
|
||||||
})
|
|
||||||
export class AsyncActionStatusComponent {
|
|
||||||
/// Value of the password
|
|
||||||
@Input() value: AsyncActionState = AsyncActionState.IDLE;
|
|
||||||
|
|
||||||
public getImage(): string {
|
|
||||||
switch(this.value) {
|
|
||||||
case AsyncActionState.IDLE:
|
|
||||||
return '';
|
|
||||||
case AsyncActionState.LOADING:
|
|
||||||
return 'assets/images/load.svg';
|
|
||||||
case AsyncActionState.DONE:
|
|
||||||
return 'assets/images/validate.svg';
|
|
||||||
case AsyncActionState.FAIL:
|
|
||||||
return 'assets/images/validate-not.svg';
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
|
|
||||||
<div>
|
|
||||||
<div class="bmp-title">
|
|
||||||
<div class="title"><ng-content select="name"></ng-content></div>
|
|
||||||
<div class="description"><ng-content select="description"></ng-content></div>
|
|
||||||
</div>
|
|
||||||
<div class="bmp-elements">
|
|
||||||
<ng-content select="body"></ng-content>
|
|
||||||
</div>
|
|
||||||
<div class="bmp-validation">
|
|
||||||
<ng-content select="footer"></ng-content>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,78 +0,0 @@
|
|||||||
.bmp-title {
|
|
||||||
width: 80%;
|
|
||||||
border: solid;
|
|
||||||
border-width: 1px;
|
|
||||||
margin: auto;
|
|
||||||
padding: 10px 20px;
|
|
||||||
|
|
||||||
border-color: black;
|
|
||||||
border-radius: 10px 10px 0px 0px;
|
|
||||||
background-color: gray;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: 24px;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 10px 0 10px 0;
|
|
||||||
text-align: Left;
|
|
||||||
}
|
|
||||||
.description {
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 16px;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 10px 0 10px 0;
|
|
||||||
text-align: Left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bmp-elements {
|
|
||||||
width: 80%;
|
|
||||||
border: solid;
|
|
||||||
border-width: 0px 1px;
|
|
||||||
margin: auto;
|
|
||||||
padding: 10px 20px;
|
|
||||||
|
|
||||||
border-color: black;
|
|
||||||
border-radius: 0px;
|
|
||||||
background-color: lightgray;
|
|
||||||
vertical-align: middle;
|
|
||||||
text-align: Left;
|
|
||||||
/*
|
|
||||||
.elem-hr {
|
|
||||||
width: 100%;
|
|
||||||
border-color: black;
|
|
||||||
border: dashed;
|
|
||||||
border-width: 1px 0 0 0;
|
|
||||||
margin: 10px auto;
|
|
||||||
}
|
|
||||||
.elem-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0 10px 0 36px;
|
|
||||||
}
|
|
||||||
.elem-description {
|
|
||||||
font-size: 14px;
|
|
||||||
margin: 0 20px 10px 50px;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.elem-input {
|
|
||||||
font-size: 14px;
|
|
||||||
margin: 0 20px 10px 36px;
|
|
||||||
input {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.bmp-validation {
|
|
||||||
width: 80%;
|
|
||||||
border: solid;
|
|
||||||
border-width: 1px;
|
|
||||||
margin: auto;
|
|
||||||
padding: 10px 20px;
|
|
||||||
|
|
||||||
border-color: black;
|
|
||||||
border-radius: 0px 0px 10px 10px;
|
|
||||||
background-color: gray;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2020, Edouard DUPIN, all right reserved
|
|
||||||
* @license MPL-2 (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
// moduleId: module.id.toString(),
|
|
||||||
selector: 'burger-property',
|
|
||||||
templateUrl: './burger-property.html',
|
|
||||||
styleUrls: ['./burger-property.less'],
|
|
||||||
})
|
|
||||||
export class BurgerPropertyComponent {
|
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
<div class="elem-checkbox">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
[checked]="value"
|
|
||||||
(change)="onChange($event.target.checked)" />
|
|
||||||
{{comment}}
|
|
||||||
</div>
|
|
@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
.elem-checkbox {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0 10px 0 10px;
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-checkbox',
|
|
||||||
templateUrl: 'checkbox.html',
|
|
||||||
styleUrls: ['checkbox.less'],
|
|
||||||
})
|
|
||||||
export class CheckboxComponent {
|
|
||||||
/// Checkbox value
|
|
||||||
@Input() value: boolean = false;
|
|
||||||
/// Description of the checkbox
|
|
||||||
@Input() comment: string = "";
|
|
||||||
/// event when change the value of the password
|
|
||||||
@Output() changeValue: EventEmitter<boolean> = new EventEmitter();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When input value change, need update the display and change the internal value.
|
|
||||||
* @param newValue New value set on the password
|
|
||||||
*/
|
|
||||||
onChange(newValue: boolean): void {
|
|
||||||
this.value = newValue;
|
|
||||||
this.changeValue.emit(this.value);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
<div class="top">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
[placeholder]="placeholder===undefined?'':placeholder"
|
|
||||||
required=""
|
|
||||||
[style.border]="hasError||notANumber? '2px dashed red' : ''"
|
|
||||||
[(ngModel)]="value"
|
|
||||||
(input)="onChangeValue($event.target.value)" />
|
|
||||||
<button class="eye-button-2 unselectable" tabindex="-1" (click)="onDecrement()" type="submit">
|
|
||||||
<i class="material-icons">arrow_back_ios</i>
|
|
||||||
</button>
|
|
||||||
<button class="eye-button unselectable" tabindex="-1" (click)="onIncrement()" type="submit">
|
|
||||||
<i class="material-icons">arrow_forward_ios</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
@ -1,39 +0,0 @@
|
|||||||
input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 12px 20px;
|
|
||||||
margin: 8px 0;
|
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
box-sizing: border-box;
|
|
||||||
z-index: 5;
|
|
||||||
}
|
|
||||||
.eye-button {
|
|
||||||
margin-left: -44px;
|
|
||||||
margin-top: 15px;
|
|
||||||
float: right;
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
border: none;
|
|
||||||
z-index: 15;
|
|
||||||
background: none;
|
|
||||||
padding: 4 1 13 1;
|
|
||||||
:hover {
|
|
||||||
background: none;
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.eye-button-2 {
|
|
||||||
margin-left: -70px;
|
|
||||||
margin-top: 12px;
|
|
||||||
float: right;
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
border: none;
|
|
||||||
z-index: 15;
|
|
||||||
background: none;
|
|
||||||
padding: 4px 30px 4px 1px;
|
|
||||||
:hover {
|
|
||||||
background: none;
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
||||||
import { isNumeric } from 'common/utils';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-entry-number',
|
|
||||||
templateUrl: 'entry-number.html',
|
|
||||||
styleUrls: ['entry-number.less'],
|
|
||||||
})
|
|
||||||
export class EntryNumberComponent implements OnInit {
|
|
||||||
/// Value of the password
|
|
||||||
@Input() value: string|undefined = '';
|
|
||||||
/// Placeholder of the Value
|
|
||||||
@Input() placeholder: string|undefined = '';
|
|
||||||
/// The element has an error
|
|
||||||
@Input() hasError: boolean = false;
|
|
||||||
/// event when change the value of the password
|
|
||||||
@Output() changeValue: EventEmitter<number|undefined> = new EventEmitter();
|
|
||||||
|
|
||||||
public notANumber: boolean = false;
|
|
||||||
ngOnInit(): void {
|
|
||||||
//if (value)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When input value change, need update the display and change the internal value.
|
|
||||||
* @param newValue New value set on the password
|
|
||||||
*/
|
|
||||||
onChangeValue(newValue: string): void {
|
|
||||||
if (newValue === "") {
|
|
||||||
this.value = undefined;
|
|
||||||
this.notANumber = false;
|
|
||||||
this.changeValue.emit(undefined);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.value = newValue;
|
|
||||||
this.notANumber = false;
|
|
||||||
if (!isNumeric(this.value)) {
|
|
||||||
this.notANumber = true;
|
|
||||||
}
|
|
||||||
const numValue = Number(this.value);
|
|
||||||
this.changeValue.emit(numValue);
|
|
||||||
}
|
|
||||||
onIncrement() {
|
|
||||||
this.notANumber = false;
|
|
||||||
let newValue = undefined;
|
|
||||||
if (!isNumeric(this.value)) {
|
|
||||||
newValue = 0;
|
|
||||||
} else {
|
|
||||||
newValue = Number(this.value) + 1;
|
|
||||||
}
|
|
||||||
this.value = "" + newValue;
|
|
||||||
this.changeValue.emit(newValue);
|
|
||||||
}
|
|
||||||
onDecrement() {
|
|
||||||
this.notANumber = false;
|
|
||||||
let newValue = undefined;
|
|
||||||
if (!isNumeric(this.value)) {
|
|
||||||
newValue = 0;
|
|
||||||
} else {
|
|
||||||
newValue = Number(this.value) - 1;
|
|
||||||
}
|
|
||||||
this.value = "" + newValue;
|
|
||||||
this.changeValue.emit(newValue);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
<div>
|
|
||||||
<app-entry
|
|
||||||
[value]="value"
|
|
||||||
[placeholder]="placeholder"
|
|
||||||
[hasError]="state !== true"
|
|
||||||
(changeValue)="check($event)"></app-entry>
|
|
||||||
<app-error-message-state [value]="state"></app-error-message-state>
|
|
||||||
</div>
|
|
@ -1,9 +0,0 @@
|
|||||||
input[type='text'] {
|
|
||||||
width: 100%;
|
|
||||||
padding: 12px 20px;
|
|
||||||
margin: 8px 0;
|
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
box-sizing: border-box;
|
|
||||||
z-index: 5;
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
||||||
import { isNullOrUndefined } from 'common/utils';
|
|
||||||
|
|
||||||
export type ReturnFunction = (a: boolean|string) => void;
|
|
||||||
|
|
||||||
export type CheckerParameter = {
|
|
||||||
value: string,
|
|
||||||
result: ReturnFunction
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-entry-validator',
|
|
||||||
templateUrl: 'entry-validator.html',
|
|
||||||
styleUrls: ['entry-validator.less'],
|
|
||||||
})
|
|
||||||
export class EntryValidatorComponent implements OnInit {
|
|
||||||
/// Value of the password
|
|
||||||
@Input() value: string = '';
|
|
||||||
/// Placeholder of the Value
|
|
||||||
@Input() placeholder: string = '';
|
|
||||||
/// The element has an error
|
|
||||||
@Output() checker: EventEmitter<CheckerParameter> = new EventEmitter();
|
|
||||||
/// event when change the value of the password
|
|
||||||
@Output() changeValue: EventEmitter<string> = new EventEmitter();
|
|
||||||
|
|
||||||
|
|
||||||
public state: boolean|string = false;
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
//if (value)
|
|
||||||
}
|
|
||||||
|
|
||||||
updateStatus(value: boolean|string): void {
|
|
||||||
this.state = value
|
|
||||||
if (this.state === true) {
|
|
||||||
this.changeValue.emit(this.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
check(newValue: string): void {
|
|
||||||
let self = this;
|
|
||||||
let lambdaCallBack = (value: boolean|string) => {self.updateStatus(value)};
|
|
||||||
this.value = newValue;
|
|
||||||
if (isNullOrUndefined(this.checker)) {
|
|
||||||
this.changeValue.emit(this.value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.checker.emit({
|
|
||||||
value: newValue,
|
|
||||||
result: lambdaCallBack,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
<div class="top">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
[placeholder]="placeholder===undefined?'':placeholder"
|
|
||||||
required=""
|
|
||||||
[style.border]="hasError? '2px dashed red' : ''"
|
|
||||||
[value]="value===undefined?'':value"
|
|
||||||
(input)="onChangeValue($event.target.value)" />
|
|
||||||
</div>
|
|
@ -1,9 +0,0 @@
|
|||||||
input[type='text'] {
|
|
||||||
width: 100%;
|
|
||||||
padding: 12px 20px;
|
|
||||||
margin: 8px 0;
|
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
box-sizing: border-box;
|
|
||||||
z-index: 5;
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
|
||||||
import { PasswordEntryComponent } from './entry';
|
|
||||||
|
|
||||||
describe('PasswordEntryComponent global test', () => {
|
|
||||||
let component: PasswordEntryComponent;
|
|
||||||
let fixture: ComponentFixture<PasswordEntryComponent>;
|
|
||||||
let input: HTMLInputElement;
|
|
||||||
let button: HTMLButtonElement;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [PasswordEntryComponent],
|
|
||||||
}).compileComponents();
|
|
||||||
fixture = TestBed.createComponent(PasswordEntryComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
input = fixture.nativeElement.querySelector('div').querySelector('input');
|
|
||||||
button = fixture.nativeElement.querySelector('div').querySelector('button');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Test mode password (default)', () => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual('');
|
|
||||||
expect(button.textContent).toEqual('visibility_off');
|
|
||||||
expect(input.type).toEqual('password');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Test mode text', () => {
|
|
||||||
component.passwordVisibility = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual('');
|
|
||||||
expect(button.textContent).toEqual('visibility');
|
|
||||||
expect(input.type).toEqual('text');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('test click on hide button', fakeAsync(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(false);
|
|
||||||
button.click();
|
|
||||||
tick();
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(true);
|
|
||||||
expect(button.textContent).toEqual('visibility');
|
|
||||||
expect(input.type).toEqual('text');
|
|
||||||
button.click();
|
|
||||||
tick();
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(false);
|
|
||||||
expect(button.textContent).toEqual('visibility_off');
|
|
||||||
expect(input.type).toEqual('password');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('Set password', fakeAsync(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(false);
|
|
||||||
let tmpData = 'My beautifull Password';
|
|
||||||
input.value = tmpData;
|
|
||||||
input.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual(tmpData);
|
|
||||||
expect(component.value).toEqual(tmpData);
|
|
||||||
tmpData = '';
|
|
||||||
input.value = tmpData;
|
|
||||||
input.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual(tmpData);
|
|
||||||
expect(component.value).toEqual(tmpData);
|
|
||||||
}));
|
|
||||||
});
|
|
@ -1,35 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-entry',
|
|
||||||
templateUrl: 'entry.html',
|
|
||||||
styleUrls: ['entry.less'],
|
|
||||||
})
|
|
||||||
export class EntryComponent implements OnInit {
|
|
||||||
/// Value of the password
|
|
||||||
@Input() value: string|undefined = '';
|
|
||||||
/// Placeholder of the Value
|
|
||||||
@Input() placeholder: string|undefined = '';
|
|
||||||
/// The element has an error
|
|
||||||
@Input() hasError: boolean = false;
|
|
||||||
/// event when change the value of the password
|
|
||||||
@Output() changeValue: EventEmitter<string> = new EventEmitter();
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
//if (value)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When input value change, need update the display and change the internal value.
|
|
||||||
* @param newValue New value set on the password
|
|
||||||
*/
|
|
||||||
onChangeValue(newValue: string): void {
|
|
||||||
this.value = newValue;
|
|
||||||
this.changeValue.emit(this.value);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
<div class="error color-shadow-black" *ngIf="value !== true && value !== false && value !== undefined">{{value}}</div>
|
|
@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
.error {
|
|
||||||
background-color: #f44336;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 10;
|
|
||||||
display: block;
|
|
||||||
max-width: 450px;
|
|
||||||
padding: 5px 8px;
|
|
||||||
margin: 2px 0 0;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 400;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 0px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&:after,
|
|
||||||
&:before {
|
|
||||||
bottom: 100%;
|
|
||||||
left: 25px;
|
|
||||||
border: solid transparent;
|
|
||||||
content: ' ';
|
|
||||||
height: 0;
|
|
||||||
width: 0;
|
|
||||||
position: absolute;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
border-bottom-color: #f44336;
|
|
||||||
border-width: 10px;
|
|
||||||
margin-left: -10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
import { Component, Input } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-error-message-state',
|
|
||||||
templateUrl: 'error-message-state.html',
|
|
||||||
styleUrls: ['error-message-state.less'],
|
|
||||||
})
|
|
||||||
export class ErrorMessageStateComponent {
|
|
||||||
/// Value of the password
|
|
||||||
@Input() value: boolean|string = false;
|
|
||||||
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
<p>error works!</p>
|
|
@ -1,18 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-error',
|
|
||||||
templateUrl: './error.html',
|
|
||||||
styleUrls: ['./error.less'],
|
|
||||||
})
|
|
||||||
export class ErrorComponent implements OnInit {
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
ngOnInit() {}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
import { AsyncActionState, AsyncActionStatusComponent } from './async-action-status/async-status-component';
|
|
||||||
import { BurgerPropertyComponent } from './burger-property/burger-property';
|
|
||||||
import { CheckboxComponent } from './checkbox/checkbox';
|
|
||||||
import { EntryNumberComponent } from './entry-number/entry-number';
|
|
||||||
import { EntryValidatorComponent } from './entry-validator/entry-validator';
|
|
||||||
import { EntryComponent } from './entry/entry';
|
|
||||||
import { ErrorMessageStateComponent } from './error-message-state/error-message-state';
|
|
||||||
import { ErrorComponent } from './error/error';
|
|
||||||
import { PasswordEntryComponent } from './password-entry/password-entry';
|
|
||||||
import { PopInComponent } from './popin/popin';
|
|
||||||
import { RenderFormComponent } from './render-settings/render-form';
|
|
||||||
import { RenderSettingsComponent } from './render-settings/render-settings';
|
|
||||||
import { SpinerComponent } from './spiner/spiner';
|
|
||||||
import { TopMenuComponent } from './top-menu/top-menu';
|
|
||||||
import { UploadFileComponent } from './upload-file/upload-file';
|
|
||||||
|
|
||||||
export { BurgerPropertyComponent, EntryNumberComponent, CheckboxComponent, RenderFormComponent, RenderSettingsComponent, ErrorMessageStateComponent, AsyncActionState, AsyncActionStatusComponent, EntryValidatorComponent, PopInComponent, TopMenuComponent, UploadFileComponent, ErrorComponent, SpinerComponent, PasswordEntryComponent, EntryComponent };
|
|
@ -1,12 +0,0 @@
|
|||||||
<div class="top">
|
|
||||||
<input
|
|
||||||
[type]="passwordVisibility?'text':'password'"
|
|
||||||
[placeholder]="placeholder===undefined?'':placeholder"
|
|
||||||
required=""
|
|
||||||
[style.border]="hasError? '2px dashed red' : ''"
|
|
||||||
[value]="value"
|
|
||||||
(input)="onChangeValue($event.target.value)" />
|
|
||||||
<button class="eye-button unselectable" tabindex="-1" (click)="onVisibility()" type="submit">
|
|
||||||
<i class="material-icons">{{passwordVisibility?"visibility":"visibility_off"}}</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
@ -1,25 +0,0 @@
|
|||||||
.eye-button {
|
|
||||||
margin-left: -44px;
|
|
||||||
margin-top: 15px;
|
|
||||||
float: right;
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
border: none;
|
|
||||||
z-index: 15;
|
|
||||||
background: none;
|
|
||||||
padding: 4 1 13 1;
|
|
||||||
:hover {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type='text'],
|
|
||||||
input[type='password'] {
|
|
||||||
width: 100%;
|
|
||||||
padding: 12px 20px;
|
|
||||||
margin: 8px 0;
|
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
box-sizing: border-box;
|
|
||||||
z-index: 5;
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
|
||||||
import { PasswordEntryComponent } from './password-entry';
|
|
||||||
|
|
||||||
describe('PasswordEntryComponent global test', () => {
|
|
||||||
let component: PasswordEntryComponent;
|
|
||||||
let fixture: ComponentFixture<PasswordEntryComponent>;
|
|
||||||
let input: HTMLInputElement;
|
|
||||||
let button: HTMLButtonElement;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [PasswordEntryComponent],
|
|
||||||
}).compileComponents();
|
|
||||||
fixture = TestBed.createComponent(PasswordEntryComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
input = fixture.nativeElement.querySelector('div').querySelector('input');
|
|
||||||
button = fixture.nativeElement.querySelector('div').querySelector('button');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Test mode password (default)', () => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual('');
|
|
||||||
expect(button.textContent).toEqual('visibility_off');
|
|
||||||
expect(input.type).toEqual('password');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Test mode text', () => {
|
|
||||||
component.passwordVisibility = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual('');
|
|
||||||
expect(button.textContent).toEqual('visibility');
|
|
||||||
expect(input.type).toEqual('text');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('test click on hide button', fakeAsync(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(false);
|
|
||||||
button.click();
|
|
||||||
tick();
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(true);
|
|
||||||
expect(button.textContent).toEqual('visibility');
|
|
||||||
expect(input.type).toEqual('text');
|
|
||||||
button.click();
|
|
||||||
tick();
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(false);
|
|
||||||
expect(button.textContent).toEqual('visibility_off');
|
|
||||||
expect(input.type).toEqual('password');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('Set password', fakeAsync(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component.passwordVisibility).toEqual(false);
|
|
||||||
let tmpData = 'My beautifull Password';
|
|
||||||
input.value = tmpData;
|
|
||||||
input.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual(tmpData);
|
|
||||||
expect(component.value).toEqual(tmpData);
|
|
||||||
tmpData = '';
|
|
||||||
input.value = tmpData;
|
|
||||||
input.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(input.textContent).toEqual(tmpData);
|
|
||||||
expect(component.value).toEqual(tmpData);
|
|
||||||
}));
|
|
||||||
});
|
|
@ -1,39 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-password-entry',
|
|
||||||
templateUrl: 'password-entry.html',
|
|
||||||
styleUrls: ['password-entry.less'],
|
|
||||||
})
|
|
||||||
export class PasswordEntryComponent {
|
|
||||||
/// Value of the password
|
|
||||||
@Input() value: string = '';
|
|
||||||
/// Placeholder of the Value
|
|
||||||
@Input() placeholder: string = 'Write password.';
|
|
||||||
/// The element has an error
|
|
||||||
@Input() hasError: boolean = false;
|
|
||||||
/// event when change the value of the password
|
|
||||||
@Output() changeValue: EventEmitter<string> = new EventEmitter();
|
|
||||||
/// Local value of the password viwibility
|
|
||||||
public passwordVisibility: boolean = false;
|
|
||||||
/**
|
|
||||||
* Ov visibility request change (toggle the visibility)
|
|
||||||
*/
|
|
||||||
onVisibility(): void {
|
|
||||||
this.passwordVisibility = !this.passwordVisibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When input value change, need update the display and change the internal value.
|
|
||||||
* @param newValue New value set on the password
|
|
||||||
*/
|
|
||||||
onChangeValue(newValue: string): void {
|
|
||||||
this.value = newValue;
|
|
||||||
this.changeValue.emit(this.value);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
<div class="popin" *ngIf="displayPopIn">
|
|
||||||
<div class="element {{popSize}}">
|
|
||||||
<div class="header">
|
|
||||||
<label class="unselectable">{{popTitle}}</label>
|
|
||||||
<div class="close" *ngIf="closeTopRight == true">
|
|
||||||
<button class="button-close color-shadow-black" (click)="onCloseTop()" type="submit">
|
|
||||||
<label class="unselectable"><i class="material-icons">close</i></label>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="body">
|
|
||||||
<ng-content></ng-content>
|
|
||||||
</div>
|
|
||||||
<div class="footer">
|
|
||||||
<div class="action" *ngIf="validateTitle != null">
|
|
||||||
<button class="button color-shadow-black" (click)="onValidate()" type="submit">
|
|
||||||
<label class="unselectable"><i class="material-icons">done</i> {{validateTitle}}</label>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="action" *ngIf="saveTitle != null">
|
|
||||||
<button class="button color-shadow-black" (click)="onSave()" type="submit">
|
|
||||||
<label class="unselectable"><i class="material-icons">save_alt</i> {{saveTitle}}</label>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="action" *ngIf="otherTitle != null">
|
|
||||||
<button class="button color-shadow-black" (click)="onOther()" type="submit">
|
|
||||||
<label class="unselectable"><i class="material-icons">star</i> {{otherTitle}}</label>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="action" *ngIf="closeTitle != null">
|
|
||||||
<button class="button color-shadow-black" (click)="onClose()" type="submit">
|
|
||||||
<label class="unselectable"><i class="material-icons">close</i> {{closeTitle}}</label>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="background"></div>
|
|
||||||
</div>
|
|
@ -1,87 +0,0 @@
|
|||||||
/* popin STYLES
|
|
||||||
-------------------------------*/
|
|
||||||
|
|
||||||
/* popins are hidden by default */
|
|
||||||
.popin {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 800;
|
|
||||||
.small {
|
|
||||||
top: 15%;
|
|
||||||
right: 35%;
|
|
||||||
bottom: 15%;
|
|
||||||
left: 35%;
|
|
||||||
}
|
|
||||||
.medium {
|
|
||||||
top: 15%;
|
|
||||||
right: 25%;
|
|
||||||
bottom: 15%;
|
|
||||||
left: 25%;
|
|
||||||
}
|
|
||||||
.big {
|
|
||||||
top: 15%;
|
|
||||||
right: 15%;
|
|
||||||
bottom: 15%;
|
|
||||||
left: 15%;
|
|
||||||
}
|
|
||||||
.element {
|
|
||||||
/* popin container fixed across whole screen */
|
|
||||||
position: fixed;
|
|
||||||
display: block;
|
|
||||||
/* z-index must be higher than .popin-background */
|
|
||||||
z-index: 1000;
|
|
||||||
/* enables scrolling for tall popins */
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
.header {
|
|
||||||
padding: 10px;
|
|
||||||
//display: block;
|
|
||||||
background: #88f;
|
|
||||||
//margin: 40px;
|
|
||||||
//margin: auto;
|
|
||||||
height: 40px;
|
|
||||||
line-height: 36px;
|
|
||||||
.close {
|
|
||||||
display: block;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.body {
|
|
||||||
//display: block;
|
|
||||||
padding: 20px;
|
|
||||||
background: #fff;
|
|
||||||
/* margin exposes part of the popin background */
|
|
||||||
//margin: 40px;
|
|
||||||
//margin: auto;
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
padding: 10px;
|
|
||||||
//display: block;
|
|
||||||
background: #888;
|
|
||||||
//margin: 40px;
|
|
||||||
//margin: auto;
|
|
||||||
height: 40px;
|
|
||||||
line-height: 36px;
|
|
||||||
.action {
|
|
||||||
padding: 0 10px;
|
|
||||||
display: block;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Pop in mush have a background over all the windows ...
|
|
||||||
.background {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
background-color: #000;
|
|
||||||
opacity: 0.85;
|
|
||||||
z-index: 900;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2020, Edouard DUPIN, all right reserved
|
|
||||||
* @license MPL-2 (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component, Input, Output, OnInit, OnDestroy, EventEmitter } from '@angular/core';
|
|
||||||
import { PopInService } from 'common/service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
// moduleId: module.id.toString(),
|
|
||||||
selector: 'app-popin',
|
|
||||||
templateUrl: './popin.html',
|
|
||||||
styleUrls: ['./popin.less'],
|
|
||||||
})
|
|
||||||
export class PopInComponent implements OnInit, OnDestroy {
|
|
||||||
@Input() id: string;
|
|
||||||
@Input() popTitle: string = 'No title';
|
|
||||||
@Input() closeTopRight: any = 'false';
|
|
||||||
@Input() popSize: string = 'medium';
|
|
||||||
|
|
||||||
@Output() callback: EventEmitter<any> = new EventEmitter();
|
|
||||||
@Input() closeTitle: any = null;
|
|
||||||
@Input() validateTitle: any = null;
|
|
||||||
@Input() saveTitle: any = null;
|
|
||||||
@Input() otherTitle: any = null;
|
|
||||||
|
|
||||||
public displayPopIn: boolean = false;
|
|
||||||
|
|
||||||
constructor(private popInService: PopInService) {}
|
|
||||||
ngOnInit(): void {
|
|
||||||
// ensure id attribute exists
|
|
||||||
if (!this.id) {
|
|
||||||
console.error('popin must have an id');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// move element to bottom of page (just before </body>) so it can be displayed above everything else
|
|
||||||
// this.element.appendTo('body');
|
|
||||||
this.popInService.add(this);
|
|
||||||
// this.element.hide();
|
|
||||||
}
|
|
||||||
// remove self from popIn service when directive is destroyed
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
this.popInService.remove(this.id);
|
|
||||||
// this.element.remove();
|
|
||||||
}
|
|
||||||
// open popIn
|
|
||||||
open(): void {
|
|
||||||
//console.log(`open pop-in: ${this.id}`);
|
|
||||||
this.displayPopIn = true;
|
|
||||||
//this.element.show();
|
|
||||||
}
|
|
||||||
// close popin
|
|
||||||
close(): void {
|
|
||||||
this.displayPopIn = false;
|
|
||||||
// this.element.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
onCloseTop(): void {
|
|
||||||
this.callback.emit(['close-top']);
|
|
||||||
}
|
|
||||||
|
|
||||||
onValidate(): void {
|
|
||||||
this.callback.emit(['validate']);
|
|
||||||
}
|
|
||||||
|
|
||||||
onClose(): void {
|
|
||||||
this.callback.emit(['close']);
|
|
||||||
}
|
|
||||||
|
|
||||||
onOther(): void {
|
|
||||||
this.callback.emit(['other']);
|
|
||||||
}
|
|
||||||
|
|
||||||
onSave(): void {
|
|
||||||
this.callback.emit(['save']);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
<table width="100%">
|
|
||||||
<tr *ngFor="let elem of values">
|
|
||||||
<td width="15%" *ngIf="elem.type === 'STRING' || elem.type === 'PASSWORD' || elem.type === 'NUMBER'"
|
|
||||||
[style.color]="getStyleRequireError(elem)"
|
|
||||||
[style.font-weight]="elem.require === true ? 'bold' : ''"
|
|
||||||
>{{elem.title}}</td>
|
|
||||||
<td width="15%" *ngIf="elem.type === 'BOOLEAN'"
|
|
||||||
[style.color]="getStyleRequireError(elem)"
|
|
||||||
[style.font-weight]="elem.require === true ? 'bold' : ''"
|
|
||||||
>{{elem.title}}</td>
|
|
||||||
<td width="15%" *ngIf="elem.type === 'VALUE'"><b>{{elem.title}}</b></td>
|
|
||||||
|
|
||||||
<td width="85%" *ngIf="elem.type === 'VALUE'">{{elem.value}}</td>
|
|
||||||
<td width="85%" *ngIf="elem.type === 'STRING'">
|
|
||||||
<app-entry
|
|
||||||
[value]="elem.value"
|
|
||||||
[placeholder]="elem.placeholder"
|
|
||||||
[hasError]="checkHasError(elem)"
|
|
||||||
(changeValue)="checkParameter($event, elem)"></app-entry>
|
|
||||||
<app-error-message-state [value]="elem.state"></app-error-message-state>
|
|
||||||
</td>
|
|
||||||
<td width="85%" *ngIf="elem.type === 'NUMBER'">
|
|
||||||
<app-entry-number
|
|
||||||
[value]="elem.value"
|
|
||||||
[placeholder]="elem.placeholder"
|
|
||||||
[hasError]="checkHasError(elem)"
|
|
||||||
(changeValue)="checkParameter($event, elem)"></app-entry-number>
|
|
||||||
<app-error-message-state [value]="elem.state"></app-error-message-state>
|
|
||||||
</td>
|
|
||||||
<td width="85%" *ngIf="elem.type === 'PASSWORD'">
|
|
||||||
<app-password-entry
|
|
||||||
[value]="elem.value"
|
|
||||||
[placeholder]="elem.placeholder"
|
|
||||||
[hasError]="checkHasError(elem)"
|
|
||||||
(changeValue)="checkParameter($event, elem)"></app-password-entry>
|
|
||||||
<app-error-message-state [value]="elem.state"></app-error-message-state>
|
|
||||||
</td>
|
|
||||||
<td width="85%" *ngIf="elem.type === 'BOOLEAN'">
|
|
||||||
<app-checkbox
|
|
||||||
[value]="elem.value"
|
|
||||||
(changeValue)="checkParameter($event, elem)"></app-checkbox>
|
|
||||||
<app-error-message-state [value]="elem.state"></app-error-message-state>
|
|
||||||
</td>
|
|
||||||
<td width="85%" *ngIf="elem.type === 'LINE'"></td>
|
|
||||||
<td width="85%" *ngIf="elem.type === 'LINE'"></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
@ -1,17 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
import { Component } from '@angular/core';
|
|
||||||
import { RenderSettingsComponent } from './render-settings';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-render-form',
|
|
||||||
templateUrl: 'render-form.html',
|
|
||||||
styleUrls: ['render-form.less'],
|
|
||||||
})
|
|
||||||
export class RenderFormComponent extends RenderSettingsComponent {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
<div *ngFor="let elem of values" class="settings-elements">
|
|
||||||
<div *ngIf="elem.type === 'LINE'">
|
|
||||||
<div class="elem-hr"></div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="elem.type === 'BOOLEAN'">
|
|
||||||
<div class="elem-checkbox">
|
|
||||||
<app-checkbox
|
|
||||||
[value]="elem.value"
|
|
||||||
[comment]="elem.title"
|
|
||||||
(changeValue)="checkParameter($event, elem)"></app-checkbox>
|
|
||||||
</div>
|
|
||||||
<div class="elem-description">{{elem.description}}</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="elem.type === 'STRING'">
|
|
||||||
<div class="elem-title">{{elem.title}}</div>
|
|
||||||
<div class="elem-description">{{elem.description}}</div>
|
|
||||||
<div class="elem-input">
|
|
||||||
<app-entry
|
|
||||||
[value]="elem.value"
|
|
||||||
[placeholder]="elem.placeholder"
|
|
||||||
[hasError]="elem.state !== undefined"
|
|
||||||
(changeValue)="checkParameter($event, elem)"></app-entry>
|
|
||||||
<app-error-message-state [value]="elem.state"></app-error-message-state>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="elem.type === 'PASSWORD'">
|
|
||||||
<div class="elem-title">{{elem.title}}</div>
|
|
||||||
<div class="elem-description">{{elem.description}}</div>
|
|
||||||
<div class="elem-input">
|
|
||||||
<input [value]="elem.value" />
|
|
||||||
<app-password-entry
|
|
||||||
[value]="elem.value"
|
|
||||||
[placeholder]="elem.placeholder"
|
|
||||||
[hasError]="elem.state !== true"
|
|
||||||
(changeValue)="checkParameter($event, elem)"></app-password-entry>
|
|
||||||
<app-error-message-state [value]="elem.state"></app-error-message-state>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
.settings-elements {
|
|
||||||
.elem-hr {
|
|
||||||
width: 100%;
|
|
||||||
border-color: black;
|
|
||||||
border: dashed;
|
|
||||||
border-width: 1px 0 0 0;
|
|
||||||
margin: 10px auto;
|
|
||||||
}
|
|
||||||
.elem-checkbox {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0 10px 0 10px;
|
|
||||||
}
|
|
||||||
.elem-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0 10px 0 36px;
|
|
||||||
}
|
|
||||||
.elem-description {
|
|
||||||
font-size: 14px;
|
|
||||||
margin: 0 20px 10px 50px;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.elem-input {
|
|
||||||
font-size: 14px;
|
|
||||||
margin: 0 20px 10px 36px;
|
|
||||||
input {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,204 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
||||||
import { isBoolean, isInArray, isNullOrUndefined, isNumber, isObject, isOptionalOf, isString, isUndefined } from 'common/utils';
|
|
||||||
|
|
||||||
export type ReturnFunction = (a: boolean|string) => void;
|
|
||||||
export type CheckerParameterType = string | number | boolean | undefined;
|
|
||||||
// if string ==> the error, if undefined, it is OK
|
|
||||||
export type CheckerParameter = (value: CheckerParameterType) => string | undefined;
|
|
||||||
|
|
||||||
|
|
||||||
export enum SettingType {
|
|
||||||
VALUE = 'VALUE',
|
|
||||||
LINE = 'LINE',
|
|
||||||
BOOLEAN = 'BOOLEAN',
|
|
||||||
NUMBER = 'NUMBER',
|
|
||||||
STRING = 'STRING',
|
|
||||||
PASSWORD = 'PASSWORD',
|
|
||||||
}
|
|
||||||
export function isSettingType(data: any): data is SettingType {
|
|
||||||
return isInArray(data, ['VALUE', 'LINE', 'NUMBER', 'BOOLEAN', 'STRING', 'PASSWORD']);
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SettingsItem {
|
|
||||||
// Type of the menu Node
|
|
||||||
type: SettingType;
|
|
||||||
// Unique key reference
|
|
||||||
key?: string;
|
|
||||||
// Displayed Title
|
|
||||||
title?: string;
|
|
||||||
// Description of the parameter
|
|
||||||
description?: string;
|
|
||||||
// placeholder of the parameter
|
|
||||||
placeholder?: string;
|
|
||||||
// Parameter key to SET/GET or the sub-menu
|
|
||||||
value?: boolean | string | Number;
|
|
||||||
// when data is change the value is set here undefined if not correct (must be set @ undefined):
|
|
||||||
newValue?: boolean | string | Number;
|
|
||||||
// checker to validate the data:
|
|
||||||
checker?: CheckerParameter
|
|
||||||
// result of the checker (must be set @ undefined):
|
|
||||||
state?: boolean | string;
|
|
||||||
// The element is require to have a valid form.
|
|
||||||
require?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isSettingsItem(data: any): data is SettingsItem {
|
|
||||||
if (isNullOrUndefined(data)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isObject(data)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isSettingType(data.type)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isString(data.key)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.title, isString)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.description, isString)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.placeholder, isString)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
!isOptionalOf(data.value, isBoolean) &&
|
|
||||||
!isOptionalOf(data.value, isString) &&
|
|
||||||
!isOptionalOf(data.value, isNumber)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isUndefined(data.newValue)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.state, isString)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.require, isBoolean)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-render-settings',
|
|
||||||
templateUrl: 'render-settings.html',
|
|
||||||
styleUrls: ['render-settings.less'],
|
|
||||||
})
|
|
||||||
export class RenderSettingsComponent {
|
|
||||||
/// Value of the password
|
|
||||||
@Input() values: SettingsItem[] = [];
|
|
||||||
/// Number of error detected (undefined: No change or not ready, else the number of error)
|
|
||||||
@Output() changeState: EventEmitter<Number> = new EventEmitter();
|
|
||||||
/// event with the changed values
|
|
||||||
@Output() deltaValues: EventEmitter<any> = new EventEmitter();
|
|
||||||
|
|
||||||
createOutputValues(): object {
|
|
||||||
let out = {};
|
|
||||||
//console.log(" Create values ... out ... ");
|
|
||||||
this.values.forEach( (value) => {
|
|
||||||
if (isNullOrUndefined(value.key)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//console.log(` key: ${value.key} : ${value.newValue}`);
|
|
||||||
if (!isNullOrUndefined(value.newValue)) {
|
|
||||||
//console.log(` ==> set`);
|
|
||||||
out[value.key] = value.newValue;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
countErrors(): number | undefined {
|
|
||||||
let out = 0;
|
|
||||||
this.values.forEach( (value) => {
|
|
||||||
if (!isUndefined(value.state)) {
|
|
||||||
out++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkMissing(): boolean | undefined {
|
|
||||||
let error = 0;
|
|
||||||
this.values.forEach( (elem) => {
|
|
||||||
if (isNumber(elem.newValue)) {
|
|
||||||
if ((isUndefined(elem.newValue) && elem.value === undefined) || elem.newValue === undefined) {
|
|
||||||
error++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((isUndefined(elem.newValue) && elem.value === "") || elem.newValue === "") {
|
|
||||||
error++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return error !== 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getStyleRequireError(elem): string {
|
|
||||||
if (elem.require !== true) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (isNumber(elem.newValue)) {
|
|
||||||
//console.log(`>>>>>>>>>>>>>>>>>>>>>>>>>>>>><Is a number : ${elem.newValue} ${elem.value}`)
|
|
||||||
if ((isUndefined(elem.newValue) && elem.value === undefined) || elem.newValue === undefined) {
|
|
||||||
return "red";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((isUndefined(elem.newValue) && elem.value === "") || elem.newValue === "") {
|
|
||||||
return "red";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
checkHasError(item: SettingsItem) {
|
|
||||||
if (!isUndefined(item.state)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (item.require === true && item.value === "" && isUndefined(item.newValue)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
checkParameter(newValue: string | number | boolean | undefined, item: SettingsItem): void {
|
|
||||||
if (isNullOrUndefined(newValue) || newValue === "") {
|
|
||||||
item.state = undefined
|
|
||||||
} else if (!isNullOrUndefined(item.checker)) {
|
|
||||||
item.state = item.checker(newValue);
|
|
||||||
}
|
|
||||||
if (item.value === newValue) {
|
|
||||||
item.newValue = undefined;
|
|
||||||
} else {
|
|
||||||
item.newValue = newValue;
|
|
||||||
}
|
|
||||||
const missing = this.checkMissing();
|
|
||||||
const outValue = this.createOutputValues();
|
|
||||||
const nbError = this.countErrors();
|
|
||||||
const nbValuesChanges = Object.keys(outValue).length;
|
|
||||||
//console.log(`outValue=${JSON.stringify(outValue, null, 2)}`);
|
|
||||||
//console.log(`nbError=${nbError} nbValuesChanges=${nbValuesChanges}`);
|
|
||||||
if (nbValuesChanges === 0) {
|
|
||||||
this.changeState.emit(undefined);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (missing === true) {
|
|
||||||
this.changeState.emit(undefined);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.changeState.emit(nbError);
|
|
||||||
if (nbError === 0) {
|
|
||||||
this.deltaValues.emit(outValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2023, Edouard DUPIN, all right reserved
|
|
||||||
* @license MPL-2 (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component} from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'spiner',
|
|
||||||
template: '<img height="50px" src="assets/images/load.svg"/>',
|
|
||||||
})
|
|
||||||
export class SpinerComponent {
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
<div class="top">
|
|
||||||
<div id="main-menu" class="main-menu color-menu-background">
|
|
||||||
<div *ngFor="let data of menu">
|
|
||||||
<div
|
|
||||||
class="inert_element unselectable"
|
|
||||||
*ngIf="isNotButton(data)"
|
|
||||||
[ngStyle]="{'float': data.position}"
|
|
||||||
[ngClass]="getClassModel(data.model)">
|
|
||||||
<div class="xdesktop" *ngIf="data.icon"><i class="material-icons">{{data.icon}}</i> {{data.title}}</div>
|
|
||||||
<div class="xmobile" *ngIf="data.icon">
|
|
||||||
<i class="material-icons">{{data.icon}}</i>
|
|
||||||
</div>
|
|
||||||
<div class="xdesktop" *ngIf="!data.icon">{{data.title}}</div>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
class="item unselectable"
|
|
||||||
*ngIf="!isNotButton(data)"
|
|
||||||
(click)="onGeneric(data, $event)"
|
|
||||||
(auxclick)="onGeneric(data, $event)"
|
|
||||||
[ngStyle]="{'float': data.position}"
|
|
||||||
[ngClass]="getClassModel(data.model)"
|
|
||||||
[disable]="false">
|
|
||||||
<div class="avatar unselectable" *ngIf="data.image"><img class="avatar" src="{{data.image}}" /> {{data.title}}</div>
|
|
||||||
<div class="xdesktop" *ngIf="data.icon && !data.image">
|
|
||||||
<i class="material-icons">{{data.icon}}</i> {{data.title}}
|
|
||||||
</div>
|
|
||||||
<div class="xmobile" *ngIf="data.icon && !data.image">
|
|
||||||
<i class="material-icons">{{data.icon}}</i>
|
|
||||||
</div>
|
|
||||||
<div class="xdesktop" *ngIf="!data.icon && !data.image">{{data.title}}</div>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="subMenu" (click)="onOutUserProperty()">
|
|
||||||
<div class="sub-menu color-menu-background unselectable" [ngClass]="getClassMenuPosition()">
|
|
||||||
<div *ngFor="let data of subMenu">
|
|
||||||
<div
|
|
||||||
class="inert_element unselectable"
|
|
||||||
*ngIf="isNotButton(data)"
|
|
||||||
[ngStyle]="{'float': data.position}"
|
|
||||||
[ngClass]="getClassModel(data.model)">
|
|
||||||
<div class="xdesktop" *ngIf="data.icon" [ngStyle]="{'float': data.position}">
|
|
||||||
<i class="material-icons">{{data.icon}}</i> {{data.title}}
|
|
||||||
</div>
|
|
||||||
<div class="xmobile" *ngIf="data.icon" [ngStyle]="{'float': data.position}">
|
|
||||||
<i class="material-icons">{{data.icon}}</i>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!data.icon" [ngStyle]="{'float': data.position}">{{data.title}}</div>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
class="item"
|
|
||||||
*ngIf="isEnable(data) && !isNotButton(data)"
|
|
||||||
(click)="onGeneric(data, $event)"
|
|
||||||
(auxclick)="onGeneric(data, $event)"
|
|
||||||
[ngStyle]="{'float': data.position}"
|
|
||||||
[ngClass]="getClassModel(data.model)"
|
|
||||||
[disable]="false">
|
|
||||||
<div *ngIf="data.icon" [ngStyle]="{'float': data.position}">
|
|
||||||
<i class="material-icons">{{data.icon}}</i> {{data.title}}
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!data.icon" [ngStyle]="{'float': data.position}">{{data.title}}</div>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,182 +0,0 @@
|
|||||||
.element-pos-left {
|
|
||||||
z-index: 5;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
.element-pos-right {
|
|
||||||
z-index: 5;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
.element-pos-center {
|
|
||||||
z-index: 5;
|
|
||||||
float: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.model_happy {
|
|
||||||
color: yellow;
|
|
||||||
}
|
|
||||||
.model_disable {
|
|
||||||
color: rgb(100, 100, 100);
|
|
||||||
}
|
|
||||||
.model_error {
|
|
||||||
color: darkred;
|
|
||||||
}
|
|
||||||
.top {
|
|
||||||
.sub-menu {
|
|
||||||
position: fixed;
|
|
||||||
|
|
||||||
min-width: 150px;
|
|
||||||
min-height: 70px;
|
|
||||||
|
|
||||||
display: block;
|
|
||||||
overflow: visible;
|
|
||||||
|
|
||||||
box-shadow: none;
|
|
||||||
flex-direction: column;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
justify-content: flex-start;
|
|
||||||
box-sizing: border-box;
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 3px 0 3px;
|
|
||||||
border: none;
|
|
||||||
z-index: 300;
|
|
||||||
box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.6);
|
|
||||||
|
|
||||||
.item {
|
|
||||||
display: block;
|
|
||||||
float: top;
|
|
||||||
line-height: 56px;
|
|
||||||
z-index: 4;
|
|
||||||
margin: 3px 0px 3px 0px;
|
|
||||||
/*padding: 0px 3px 0px 3px;*/
|
|
||||||
border: 0px; /*0px 3px 0px 3px solid transparent;*/
|
|
||||||
/*text-transform: uppercase;*/
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 17px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.material-icons {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
/* Create an Arraw on the top ob the box ... */
|
|
||||||
&:after,
|
|
||||||
&:before {
|
|
||||||
bottom: 100%;
|
|
||||||
right: 13px;
|
|
||||||
border: solid transparent;
|
|
||||||
content: ' ';
|
|
||||||
height: 0;
|
|
||||||
width: 0;
|
|
||||||
position: absolute;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
border-color: rgba(136, 183, 213, 0);
|
|
||||||
border-bottom-color: #263238;
|
|
||||||
border-width: 15px;
|
|
||||||
margin-left: -15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.menu-left {
|
|
||||||
top: 75px;
|
|
||||||
left: 15px;
|
|
||||||
}
|
|
||||||
.menu-right {
|
|
||||||
top: 75px;
|
|
||||||
right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fill-all {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
/*
|
|
||||||
background-color: #0F0;
|
|
||||||
*/
|
|
||||||
z-index: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-menu {
|
|
||||||
position: fixed;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
|
|
||||||
display: block;
|
|
||||||
overflow: visible;
|
|
||||||
|
|
||||||
box-shadow: none;
|
|
||||||
min-height: 56px;
|
|
||||||
flex-direction: column;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
justify-content: flex-start;
|
|
||||||
box-sizing: border-box;
|
|
||||||
flex-shrink: 0;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 12px 0 12px;
|
|
||||||
border: none;
|
|
||||||
max-height: 1000px;
|
|
||||||
z-index: 3;
|
|
||||||
box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.6);
|
|
||||||
|
|
||||||
.item {
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
line-height: 56px;
|
|
||||||
z-index: 4;
|
|
||||||
margin: 0 3px 0 3px;
|
|
||||||
border: 0;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 17px;
|
|
||||||
.comment {
|
|
||||||
visibility: 'hidden';
|
|
||||||
}
|
|
||||||
@media all and (min-width: 700px) {
|
|
||||||
.comment {
|
|
||||||
visibility: 'visible';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.inert_element {
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
line-height: 56px;
|
|
||||||
z-index: 4;
|
|
||||||
margin: 0 3px 0 3px;
|
|
||||||
border: 0;
|
|
||||||
//text-transform: uppercase;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 17px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ariane {
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
line-height: 56px;
|
|
||||||
z-index: 4;
|
|
||||||
padding: 0 0 0 15px;
|
|
||||||
margin: 0 3px 0 3px;
|
|
||||||
border: 0;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.material-icons {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
height: 42px;
|
|
||||||
width: 42px;
|
|
||||||
border-radius: 50%;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
|
|
||||||
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
import { isNullOrUndefined } from 'common/utils';
|
|
||||||
import { MenuItem } from 'common/model/menu-item';
|
|
||||||
|
|
||||||
export interface EventOnMenu {
|
|
||||||
menu: MenuItem;
|
|
||||||
newWindows: boolean;
|
|
||||||
ctrl: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-top-menu',
|
|
||||||
templateUrl: './top-menu.html',
|
|
||||||
styleUrls: ['./top-menu.less'],
|
|
||||||
})
|
|
||||||
export class TopMenuComponent implements OnInit {
|
|
||||||
@Input() menu: MenuItem[];
|
|
||||||
subMenu: MenuItem[] = undefined;
|
|
||||||
subMenuPosition: String = undefined;
|
|
||||||
@Output() callback: EventEmitter<EventOnMenu> = new EventEmitter();
|
|
||||||
|
|
||||||
constructor(private router: Router) {}
|
|
||||||
|
|
||||||
isNotButton(data: MenuItem) {
|
|
||||||
return (
|
|
||||||
isNullOrUndefined(data.navigateTo) &&
|
|
||||||
(isNullOrUndefined(data.callback) || data.callback === false) &&
|
|
||||||
isNullOrUndefined(data.subMenu)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
isEnable(data: MenuItem) {
|
|
||||||
if (!isNullOrUndefined(data) && !isNullOrUndefined(data.enable) && data.enable === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
getPosition(data: string): string {
|
|
||||||
return `float: ${data}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {}
|
|
||||||
onOutUserProperty(): void {
|
|
||||||
//console.log('onOutUserProperty ==> event...');
|
|
||||||
this.subMenu = undefined;
|
|
||||||
}
|
|
||||||
getClassMenuPosition(): string {
|
|
||||||
if (isNullOrUndefined(this.subMenuPosition)) {
|
|
||||||
return 'menu-left';
|
|
||||||
}
|
|
||||||
return 'menu-' + this.subMenuPosition;
|
|
||||||
}
|
|
||||||
getClassModel(data?: string): string {
|
|
||||||
if (isNullOrUndefined(data)) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return 'model_' + data;
|
|
||||||
}
|
|
||||||
|
|
||||||
onGeneric(data: MenuItem, event: any): void {
|
|
||||||
//console.log(`onGeneric()`);
|
|
||||||
// check if we need to navigate
|
|
||||||
if (!isNullOrUndefined(data.navigateTo)) {
|
|
||||||
// remove in every case the subMenu:
|
|
||||||
this.subMenu = undefined;
|
|
||||||
this.subMenuPosition = undefined;
|
|
||||||
this.router.navigate([data.navigateTo]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!isNullOrUndefined(data.callback) && data.callback === true) {
|
|
||||||
//console.log(`Emit message on ${JSON.stringify(data)}`);
|
|
||||||
this.callback.emit({
|
|
||||||
menu: data,
|
|
||||||
newWindows: event.which === 2,
|
|
||||||
ctrl: event.ctrlKey,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// check if we need to display a submenu
|
|
||||||
if (isNullOrUndefined(data.subMenu)) {
|
|
||||||
//just a toggle mode:
|
|
||||||
data.subMenu = undefined;
|
|
||||||
this.subMenuPosition = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.subMenu === data.subMenu) {
|
|
||||||
//just a toggle mode:
|
|
||||||
this.subMenu = undefined;
|
|
||||||
this.subMenuPosition = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//console.log(`Set Menu: ${JSON.stringify(data.subMenu)}`);
|
|
||||||
// set the requested menu
|
|
||||||
this.subMenu = data.subMenu;
|
|
||||||
this.subMenuPosition = data.position;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
<div>
|
|
||||||
<div class="uploadfilecontainer" (click)="fileInput.click()" appDragDrop (onFileDropped)="uploadFile($event)">
|
|
||||||
<input hidden type="file" #fileInput (change)="uploadFile($event.target.files)" />
|
|
||||||
</div>
|
|
||||||
<div class="files-list" *ngFor="let file of files;let i=index">
|
|
||||||
<p>{{ file }}</p>
|
|
||||||
<button class="delete-file" (click)="deleteAttachment(i)">// DELETE //</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,39 +0,0 @@
|
|||||||
.uploadfilecontainer {
|
|
||||||
//background-image: url("../../../assets/cloud-2044823_960_720.png");
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 100px;
|
|
||||||
background-position: center;
|
|
||||||
height: 200px;
|
|
||||||
width: 80%;
|
|
||||||
margin: 20px auto;
|
|
||||||
border: 2px dashed #1c8adb;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uploadfilecontainer:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #9ecbec !important;
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.files-list {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
width: 80%;
|
|
||||||
margin: 10px auto;
|
|
||||||
background: #ffffff;
|
|
||||||
border: 1px dashed;
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 5px;
|
|
||||||
color: #1c8adb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.files-list .delete-file {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.files-list .delete-file img {
|
|
||||||
width: 30px;
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-upload-file',
|
|
||||||
templateUrl: './upload-file.html',
|
|
||||||
styleUrls: ['./upload-file.less'],
|
|
||||||
})
|
|
||||||
export class UploadFileComponent {
|
|
||||||
files: any = [];
|
|
||||||
uploadFile(event) {
|
|
||||||
for (let index = 0; index < event.length; index++) {
|
|
||||||
const element = event[index];
|
|
||||||
this.files.push(element.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deleteAttachment(index) {
|
|
||||||
this.files.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
import { isMenuItem, isMenuPosition, MenuItem, MenuPosition } from './menu-item';
|
|
||||||
import { NodeData, isNodeData } from './node';
|
|
||||||
|
|
||||||
export { NodeData, isNodeData, MenuPosition, isMenuPosition, MenuItem, isMenuItem };
|
|
@ -1,67 +0,0 @@
|
|||||||
import { isObject, isOptionalOf, isString, isNullOrUndefined, isOptionalArrayOf, isInArray } from 'common/utils';
|
|
||||||
|
|
||||||
export enum MenuPosition {
|
|
||||||
LEFT = 'left',
|
|
||||||
RIGHT = 'right',
|
|
||||||
CENTER = 'none',
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isMenuPosition(data: any): data is MenuPosition {
|
|
||||||
return isInArray(data, ['left', 'right', 'none']);
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MenuItem {
|
|
||||||
// Position of the menue element
|
|
||||||
position: MenuPosition;
|
|
||||||
// Hover help
|
|
||||||
hover?: string;
|
|
||||||
// Icon of the menue (need to be a meterial-icon name
|
|
||||||
icon?: string;
|
|
||||||
// Displayed Title
|
|
||||||
image?: string;
|
|
||||||
// Displayed Title
|
|
||||||
title: string;
|
|
||||||
// Model of the display:
|
|
||||||
model?: string;
|
|
||||||
// Jump Link (If undefined: it is considered as text and not a button)
|
|
||||||
navigateTo?: string;
|
|
||||||
// Menu model For a subList of elements
|
|
||||||
callback?: boolean;
|
|
||||||
// Other data that want to be set by the user
|
|
||||||
otherData?: any;
|
|
||||||
// Menu model For a subList of elements
|
|
||||||
enable?: boolean;
|
|
||||||
// Menu model For a subList of elements
|
|
||||||
subMenu?: MenuItem[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isMenuItem(data: any): data is MenuItem {
|
|
||||||
if (isNullOrUndefined(data)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isObject(data)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isMenuPosition(data.position)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.hover, isString)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.icon, isString)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.image, isString)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isString(data.title)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.navigateTo, isString)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalArrayOf(data.subMenu, isMenuItem)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
import { isArrayOf, isNumberFinite, isObject, isOptionalOf, isOptionalArrayOf, isString } from 'common/utils';
|
|
||||||
|
|
||||||
export interface NodeData {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
description?: string;
|
|
||||||
parentId?: number;
|
|
||||||
covers?: number[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isNodeData(data: any): data is NodeData {
|
|
||||||
if (!isObject(data)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isNumberFinite(data.id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isString(data.name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.description, isString)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.parentId, isNumberFinite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalArrayOf(data.cover, isNumberFinite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
<div>
|
|
||||||
<app-popin
|
|
||||||
id="popin-delete-confirm"
|
|
||||||
popSize="small"
|
|
||||||
popTitle="Confirm Remove"
|
|
||||||
[closeTitle]="closeButtonTitle"
|
|
||||||
[validateTitle]="validateButtonTitle"
|
|
||||||
closeTopRight="true"
|
|
||||||
(callback)="eventPopUp($event[0])">
|
|
||||||
<div class="expand" *ngIf="imageUrl != null">
|
|
||||||
<img src="{{imageUrl}}" class="cover" />
|
|
||||||
</div>
|
|
||||||
<p class="expand">
|
|
||||||
<label class="unselectable"><b>{{comment}}</b></label>
|
|
||||||
</p>
|
|
||||||
</app-popin>
|
|
||||||
</div>
|
|
@ -1,13 +0,0 @@
|
|||||||
.expand {
|
|
||||||
width: 100%;
|
|
||||||
input {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
textarea {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
|
||||||
|
|
||||||
import { PopInService } from 'common/service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'delete-confirm',
|
|
||||||
templateUrl: './delete-confirm.html',
|
|
||||||
styleUrls: ['./delete-confirm.less'],
|
|
||||||
})
|
|
||||||
export class PopInDeleteConfirm implements OnInit {
|
|
||||||
@Input() comment: string = null;
|
|
||||||
@Input() imageUrl: string = null;
|
|
||||||
@Output() callback: EventEmitter<any> = new EventEmitter();
|
|
||||||
|
|
||||||
public closeButtonTitle: string = 'Cancel';
|
|
||||||
public validateButtonTitle: string = 'Validate';
|
|
||||||
|
|
||||||
constructor(private popInService: PopInService) {}
|
|
||||||
|
|
||||||
OnDestroy() {}
|
|
||||||
|
|
||||||
ngOnInit() {}
|
|
||||||
|
|
||||||
eventPopUp(_event: string): void {
|
|
||||||
console.log(`GET event: ${_event}`);
|
|
||||||
this.popInService.close('popin-delete-confirm');
|
|
||||||
if (_event === 'validate') {
|
|
||||||
this.callback.emit(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
import { PopInDeleteConfirm } from './delete-confirm/delete-confirm';
|
|
||||||
import { PopInUploadProgress } from './upload-progress/upload-progress';
|
|
||||||
|
|
||||||
export { PopInDeleteConfirm, PopInUploadProgress };
|
|
@ -1,34 +0,0 @@
|
|||||||
<div>
|
|
||||||
<app-popin
|
|
||||||
id="popin-upload-progress"
|
|
||||||
popSize="medium"
|
|
||||||
popTitle="Upload Media File"
|
|
||||||
[closeTitle]="closeButtonTitle"
|
|
||||||
[otherTitle]="otherButtonTitle"
|
|
||||||
[validateTitle]="validateButtonTitle"
|
|
||||||
(callback)="eventPopUp($event[0])">
|
|
||||||
<p class="expand">
|
|
||||||
<label class="unselectable"><b>{{mediaTitle}}</b></label>
|
|
||||||
</p>
|
|
||||||
<div *ngIf="progress != 100" class="progress-back">
|
|
||||||
<div class="progress-bar" style="width:{{progress}}%"> {{progress}}%</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="progress != 100">
|
|
||||||
<label class="unselectable">Upload:</label><label style="text-align: right">{{uploadDisplay}}</label><br />
|
|
||||||
<label class="unselectable">Size:</label><label style="text-align: right">{{sizeDisplay}}</label>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="progress == 100 && error == null && result == null">
|
|
||||||
<label class="unselectable">Upload done ... waiting server answer</label>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="error != null">
|
|
||||||
<label class="unselectable"><b>Get an error From the server:</b></label
|
|
||||||
><br />
|
|
||||||
<label class="unselectable">{{error}}</label>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="result != null">
|
|
||||||
<label class="unselectable"><b>Upload finished:</b></label
|
|
||||||
><br />
|
|
||||||
<label class="unselectable">{{result}}</label>
|
|
||||||
</div>
|
|
||||||
</app-popin>
|
|
||||||
</div>
|
|
@ -1,21 +0,0 @@
|
|||||||
.expand {
|
|
||||||
width: 100%;
|
|
||||||
input {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
textarea {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-back {
|
|
||||||
color: #000 !important;
|
|
||||||
background-color: #f1f1f1 !important;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar {
|
|
||||||
color: #000000 !important;
|
|
||||||
background-color: #4caf50 !important;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component, OnInit, Input, SimpleChanges } from '@angular/core';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
|
||||||
import { PopInService } from 'common/service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'upload-progress',
|
|
||||||
templateUrl: './upload-progress.html',
|
|
||||||
styleUrls: ['./upload-progress.less'],
|
|
||||||
})
|
|
||||||
export class PopInUploadProgress implements OnInit {
|
|
||||||
@Input() mediaTitle: string = '';
|
|
||||||
@Input() mediaUploaded: number = 0;
|
|
||||||
@Input() mediaSize: number = 999999999999;
|
|
||||||
@Input() result: string = null;
|
|
||||||
@Input() error: string = null;
|
|
||||||
public closeButtonTitle: string = 'Abort';
|
|
||||||
public otherButtonTitle: string = null;
|
|
||||||
public validateButtonTitle: string = null;
|
|
||||||
public uploadDisplay: string = '';
|
|
||||||
public sizeDisplay: string = '';
|
|
||||||
public progress: number = 0;
|
|
||||||
constructor(private router: Router, private popInService: PopInService) {}
|
|
||||||
OnDestroy() {}
|
|
||||||
ngOnInit() {}
|
|
||||||
eventPopUp(_event: string): void {
|
|
||||||
console.log(`GET event: ${_event}`);
|
|
||||||
this.popInService.close('popin-upload-progress');
|
|
||||||
}
|
|
||||||
updateNeedSend(): void {}
|
|
||||||
|
|
||||||
limit3(count: number): string {
|
|
||||||
if (count >= 1000) {
|
|
||||||
return `${count}`;
|
|
||||||
}
|
|
||||||
if (count >= 100) {
|
|
||||||
return ` ${count}`;
|
|
||||||
}
|
|
||||||
if (count >= 10) {
|
|
||||||
return ` ${count}`;
|
|
||||||
}
|
|
||||||
return ` ${count}`;
|
|
||||||
}
|
|
||||||
convertInHuman(countIn: number): string {
|
|
||||||
let count = countIn;
|
|
||||||
let tera = Math.trunc(count / (1024 * 1024 * 1024 * 1024));
|
|
||||||
count = count - tera * 1024 * 1024 * 1024 * 1024;
|
|
||||||
let giga = Math.trunc(count / (1024 * 1024 * 1024));
|
|
||||||
count = count - giga * 1024 * 1024 * 1024;
|
|
||||||
let mega = Math.trunc(count / (1024 * 1024));
|
|
||||||
count = count - mega * 1024 * 1024;
|
|
||||||
let kilo = Math.trunc(count / 1024);
|
|
||||||
count = count - kilo * 1024;
|
|
||||||
let out = '';
|
|
||||||
if (out.length !== 0 || tera !== 0) {
|
|
||||||
out = `${out} ${this.limit3(tera)}T`;
|
|
||||||
}
|
|
||||||
if (out.length !== 0 || giga !== 0) {
|
|
||||||
out = `${out} ${this.limit3(giga)}G`;
|
|
||||||
}
|
|
||||||
if (out.length !== 0 || mega !== 0) {
|
|
||||||
out = `${out} ${this.limit3(mega)}M`;
|
|
||||||
}
|
|
||||||
if (out.length !== 0 || kilo !== 0) {
|
|
||||||
out = `${out} ${this.limit3(kilo)}k`;
|
|
||||||
}
|
|
||||||
if (out.length !== 0 || count !== 0) {
|
|
||||||
out = `${out} ${this.limit3(count)}B`;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
|
||||||
//console.log(`Upload progress event : ${JSON.stringify(changes)}`);
|
|
||||||
this.progress = Math.trunc((this.mediaUploaded * 100) / this.mediaSize);
|
|
||||||
this.uploadDisplay = this.convertInHuman(this.mediaUploaded);
|
|
||||||
this.sizeDisplay = this.convertInHuman(this.mediaSize);
|
|
||||||
if (this.error === null && this.result === null) {
|
|
||||||
this.closeButtonTitle = 'Abort';
|
|
||||||
this.otherButtonTitle = null;
|
|
||||||
this.validateButtonTitle = null;
|
|
||||||
} else if (this.result === null) {
|
|
||||||
this.closeButtonTitle = null;
|
|
||||||
this.otherButtonTitle = 'Close';
|
|
||||||
this.validateButtonTitle = null;
|
|
||||||
} else {
|
|
||||||
this.closeButtonTitle = null;
|
|
||||||
this.otherButtonTitle = null;
|
|
||||||
this.validateButtonTitle = 'Ok';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class UploadProgress {
|
|
||||||
labelMediaTitle: string = '';
|
|
||||||
mediaSendSize: number = 0;
|
|
||||||
mediaSize: number = 99999999999999;
|
|
||||||
result: string = null;
|
|
||||||
error: string = null;
|
|
||||||
clear() {
|
|
||||||
this.labelMediaTitle = '';
|
|
||||||
this.mediaSendSize = 0;
|
|
||||||
this.mediaSize = 99999999999999;
|
|
||||||
this.result = null;
|
|
||||||
this.error = null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
<div class="full-mode">
|
|
||||||
<div class="centered">
|
|
||||||
<div class="error">
|
|
||||||
<label class="unselectable"><i class="material-icons">report</i> 404 Not Found !</label>
|
|
||||||
</div>
|
|
||||||
<div class="comment"><label class="unselectable">Unknwn this page.</label></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,49 +0,0 @@
|
|||||||
.full-mode {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
float: left;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.centered {
|
|
||||||
position: relative;
|
|
||||||
max-width: 75%;
|
|
||||||
padding: 16px 32px 16px 32px;
|
|
||||||
|
|
||||||
top: 50%;
|
|
||||||
transform: ~'translate(0, -50%)';
|
|
||||||
font-size: 30px;
|
|
||||||
|
|
||||||
font-weight: 600;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 200%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
font-size: 55px;
|
|
||||||
background-size: 45px;
|
|
||||||
/*background-attachment: fixed;*/
|
|
||||||
background-position: 0% 50%;
|
|
||||||
padding: 0 0 0 58px;
|
|
||||||
margin: 17px 0 17px 0;
|
|
||||||
text-shadow: 0px 0px 4px #000000;
|
|
||||||
color: rgb(160, 44, 44);
|
|
||||||
i {
|
|
||||||
font-size: 55px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.comment {
|
|
||||||
background-size: 45px;
|
|
||||||
/*background-attachment: fixed;*/
|
|
||||||
background-position: 0% 50%;
|
|
||||||
padding: 0 0 0 58px;
|
|
||||||
margin: 17px 0 17px 0;
|
|
||||||
text-shadow: 0px 0px 4px #07213a;
|
|
||||||
color: white;
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-404-not-found',
|
|
||||||
templateUrl: './404.html',
|
|
||||||
styleUrls: ['./404.less'],
|
|
||||||
})
|
|
||||||
export class NotFound404Scene {
|
|
||||||
constructor() {}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
<p>error-viewer works!</p>
|
|
@ -1,19 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { ActivatedRoute } from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-error-viewer',
|
|
||||||
templateUrl: './error-viewer.html',
|
|
||||||
styleUrls: ['./error-viewer.less'],
|
|
||||||
})
|
|
||||||
export class ErrorViewerScene implements OnInit {
|
|
||||||
constructor(private route: ActivatedRoute) {}
|
|
||||||
|
|
||||||
ngOnInit() {}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
<div class="full-mode">
|
|
||||||
<div class="centered">
|
|
||||||
<div class="error">
|
|
||||||
<label class="unselectable"><i class="material-icons">gpp_bad</i> 403 Forbidden</label>
|
|
||||||
</div>
|
|
||||||
<div class="comment">
|
|
||||||
<label class="unselectable">You don't have permission to access this resource.</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,50 +0,0 @@
|
|||||||
.full-mode {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
float: left;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.centered {
|
|
||||||
position: relative;
|
|
||||||
max-width: 500px;
|
|
||||||
padding: 16px 32px 16px 32px;
|
|
||||||
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: ~'translate(-50%, -50%)';
|
|
||||||
font-size: 30px;
|
|
||||||
|
|
||||||
font-weight: 600;
|
|
||||||
text-align: left;
|
|
||||||
line-height: 200%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
font-size: 55px;
|
|
||||||
background-size: 45px;
|
|
||||||
/*background-attachment: fixed;*/
|
|
||||||
background-position: 0% 50%;
|
|
||||||
padding: 0 0 0 58px;
|
|
||||||
margin: 17px 0 17px 0;
|
|
||||||
text-shadow: 0px 0px 4px #000000;
|
|
||||||
color: rgb(160, 44, 44);
|
|
||||||
i {
|
|
||||||
font-size: 55px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.comment {
|
|
||||||
background-size: 45px;
|
|
||||||
/*background-attachment: fixed;*/
|
|
||||||
background-position: 0% 50%;
|
|
||||||
padding: 0 0 0 58px;
|
|
||||||
margin: 17px 0 17px 0;
|
|
||||||
text-shadow: 0px 0px 4px #07213a;
|
|
||||||
color: white;
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-forbidden',
|
|
||||||
templateUrl: './forbidden.html',
|
|
||||||
styleUrls: ['./forbidden.less'],
|
|
||||||
})
|
|
||||||
export class ForbiddenScene {
|
|
||||||
constructor() {}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
<div class="full-mode">
|
|
||||||
<div class="centered">
|
|
||||||
<div class="error">
|
|
||||||
<label class="unselectable"><i class="material-icons">login</i> Not registered!</label>
|
|
||||||
</div>
|
|
||||||
<div class="comment"><label class="unselectable">you must login to access to this website.</label></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,49 +0,0 @@
|
|||||||
.full-mode {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
float: left;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.centered {
|
|
||||||
position: relative;
|
|
||||||
max-width: 75%;
|
|
||||||
padding: 16px 32px 16px 32px;
|
|
||||||
|
|
||||||
top: 50%;
|
|
||||||
transform: ~'translate(0, -50%)';
|
|
||||||
font-size: 30px;
|
|
||||||
|
|
||||||
font-weight: 600;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 200%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
font-size: 55px;
|
|
||||||
background-size: 45px;
|
|
||||||
/*background-attachment: fixed;*/
|
|
||||||
background-position: 0% 50%;
|
|
||||||
padding: 0 0 0 58px;
|
|
||||||
margin: 17px 0 17px 0;
|
|
||||||
text-shadow: 0px 0px 4px #000000;
|
|
||||||
color: rgb(160, 44, 44);
|
|
||||||
i {
|
|
||||||
font-size: 55px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.comment {
|
|
||||||
background-size: 45px;
|
|
||||||
/*background-attachment: fixed;*/
|
|
||||||
background-position: 0% 50%;
|
|
||||||
padding: 0 0 0 58px;
|
|
||||||
margin: 17px 0 17px 0;
|
|
||||||
text-shadow: 0px 0px 4px #07213a;
|
|
||||||
color: white;
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-home-out',
|
|
||||||
templateUrl: './home-out.html',
|
|
||||||
styleUrls: ['./home-out.less'],
|
|
||||||
})
|
|
||||||
export class HomeOutScene {
|
|
||||||
constructor() {}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
//import { ErrorViewerScene } from "./error-viewer/error-viewer";
|
|
||||||
import { ErrorViewerScene } from './error-viewer/error-viewer';
|
|
||||||
import { ForbiddenScene } from './forbidden/forbidden';
|
|
||||||
import { SsoScene } from './sso/sso';
|
|
||||||
import { HomeOutScene } from './home-out/home-out';
|
|
||||||
import { NotFound404Scene } from './404/404';
|
|
||||||
|
|
||||||
export { ErrorViewerScene, SsoScene, ForbiddenScene, HomeOutScene, NotFound404Scene };
|
|
@ -1,32 +0,0 @@
|
|||||||
<div class="full">
|
|
||||||
<div class="color-background-vignette container-global">
|
|
||||||
<div class="containerCenter">
|
|
||||||
<label for="login_field"><b>LOGIN (after SSO)</b></label>
|
|
||||||
</div>
|
|
||||||
<div class="imgContainer">
|
|
||||||
<img src="assets/images/avatar_generic.svg" alt="Avatar" class="avatar" />
|
|
||||||
</div>
|
|
||||||
<div class="container" *ngIf="token === '__CANCEL__'">
|
|
||||||
<label for="login_field"><b>ERROR: </b> Request cancel of connection !</label>
|
|
||||||
</div>
|
|
||||||
<div class="container" *ngIf="token === '__FAIL__'">
|
|
||||||
<label for="login_field"><b>ERROR: </b> Connection FAIL !</label>
|
|
||||||
</div>
|
|
||||||
<div class="container" *ngIf="token === '__LOGOUT__'">
|
|
||||||
<label for="login_field"><b>Dis-connected: </b> Redirect soon! </label>
|
|
||||||
</div>
|
|
||||||
<div class="container" *ngIf="token === 'ERROR_ME'">
|
|
||||||
<label for="login_field"><b>ERROR: </b> can not retreive user local informations!</label>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="container"
|
|
||||||
*ngIf="token !== 'ERROR_ME' and token !== '__FAIL__' and token !== '__CANCEL__' and token === '__LOGOUT__'">
|
|
||||||
<label for="login_field"><b>Connected: </b> Redirect soon!</label>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="container"
|
|
||||||
*ngIf="token !== 'ERROR_ME' and token !== '__FAIL__' and token !== '__CANCEL__' and token === '__LOGOUT__'">
|
|
||||||
<label for="login_field"><b>Welcome back: </b> {{userName}}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,108 +0,0 @@
|
|||||||
.full {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
right: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
float: right;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type='text'],
|
|
||||||
input[type='password'] {
|
|
||||||
width: 100%;
|
|
||||||
padding: 12px 20px;
|
|
||||||
margin: 8px 0;
|
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login {
|
|
||||||
margin: 2% 2%;
|
|
||||||
width: 45%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cancel {
|
|
||||||
margin: 2% 2%;
|
|
||||||
width: 45%;
|
|
||||||
}
|
|
||||||
.containerCenter {
|
|
||||||
text-align: center;
|
|
||||||
margin: 15px 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.imgContainer {
|
|
||||||
text-align: center;
|
|
||||||
margin: 15px 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.avatar {
|
|
||||||
width: 150px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container-global {
|
|
||||||
padding: 16px 32px 16px 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
padding: 16px 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.psw {
|
|
||||||
float: right;
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.forgot {
|
|
||||||
color: #00b;
|
|
||||||
font-size: 14px;
|
|
||||||
float: right;
|
|
||||||
buttum: 0;
|
|
||||||
line-height: 24px;
|
|
||||||
}
|
|
||||||
.error {
|
|
||||||
background-color: #f44336;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 10;
|
|
||||||
display: block;
|
|
||||||
max-width: 450px;
|
|
||||||
padding: 5px 8px;
|
|
||||||
margin: 2px 0 0;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 400;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 0px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&:after,
|
|
||||||
&:before {
|
|
||||||
bottom: 100%;
|
|
||||||
left: 25px;
|
|
||||||
border: solid transparent;
|
|
||||||
content: ' ';
|
|
||||||
height: 0;
|
|
||||||
width: 0;
|
|
||||||
position: absolute;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
border-bottom-color: #f44336;
|
|
||||||
border-width: 10px;
|
|
||||||
margin-left: -10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.container-global {
|
|
||||||
position: relative;
|
|
||||||
max-width: 400px;
|
|
||||||
padding: 16px 32px 16px 32px;
|
|
||||||
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: ~'translate(-50%, -50%)';
|
|
||||||
box-shadow: 0px 8px 20px 0 rgba(0, 0, 0, 0.9);
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
|
||||||
import { SSOService, UserService } from 'common/service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-sso',
|
|
||||||
templateUrl: './sso.html',
|
|
||||||
styleUrls: ['./sso.less'],
|
|
||||||
})
|
|
||||||
export class SsoScene implements OnInit {
|
|
||||||
ssoData: string;
|
|
||||||
token: string;
|
|
||||||
keepConnected: boolean;
|
|
||||||
userName: string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private router: Router,
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private ssoService: SSOService,
|
|
||||||
private userService: UserService
|
|
||||||
) {
|
|
||||||
console.error('retreive data after SSO');
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
let self = this;
|
|
||||||
console.log(`call after SSO back: ${window.location.href}`);
|
|
||||||
const ssoData = this.route.snapshot.paramMap.get('data');
|
|
||||||
if (ssoData == null) {
|
|
||||||
this.ssoData = undefined;
|
|
||||||
} else {
|
|
||||||
this.ssoData = ssoData;
|
|
||||||
}
|
|
||||||
const token = this.route.snapshot.paramMap.get('token');
|
|
||||||
if (token == null) {
|
|
||||||
this.token = undefined;
|
|
||||||
} else {
|
|
||||||
this.token = token;
|
|
||||||
}
|
|
||||||
const keepConnected = this.route.snapshot.paramMap.get('keepConnected');
|
|
||||||
if (keepConnected == null) {
|
|
||||||
this.keepConnected = undefined;
|
|
||||||
} else {
|
|
||||||
this.keepConnected = keepConnected === 'true';
|
|
||||||
}
|
|
||||||
console.log(`ssoData: '${ssoData}'`);
|
|
||||||
console.log(`token: '${token}'`);
|
|
||||||
console.log(`keepConnected: '${keepConnected}'`);
|
|
||||||
if (this.token !== '__CANCEL__' && this.token !== '__FAIL__' && this.token !== '__LOGOUT__') {
|
|
||||||
const destination = this.ssoData;
|
|
||||||
console.log(`ssoData (decoded): '${destination}'`);
|
|
||||||
const realDst = this.ssoService.unHashLocalData(destination);
|
|
||||||
console.log(`realDst: '${realDst}'`);
|
|
||||||
this.userService
|
|
||||||
.startSession(this.token, this.keepConnected)
|
|
||||||
.then((userName: string) => {
|
|
||||||
self.userName = userName;
|
|
||||||
setTimeout(function () {
|
|
||||||
self.router.navigate([realDst], { replaceUrl: true });
|
|
||||||
}, 500); // 2 seconds
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
this.token = 'ERROR_ME';
|
|
||||||
});
|
|
||||||
} else if (this.token === '__LOGOUT__') {
|
|
||||||
this.userService.removeSession();
|
|
||||||
const destination = this.ssoData;
|
|
||||||
console.error(`ssoData (decoded): '${destination}'`);
|
|
||||||
// sample : ZZ**DST:home
|
|
||||||
const realDst = this.ssoService.unHashLocalData(destination);
|
|
||||||
console.error(`realDst: '${realDst}'`);
|
|
||||||
setTimeout(function () {
|
|
||||||
self.router.navigate([realDst], { replaceUrl: true });
|
|
||||||
}, 500); // 2 seconds
|
|
||||||
} else {
|
|
||||||
this.userService.removeSession();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,165 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpWrapperService } from 'common/service/http-wrapper';
|
|
||||||
import { isNullOrUndefined } from 'common/utils';
|
|
||||||
import { DataInterface } from 'common/utils/dataInterface';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class BddService {
|
|
||||||
private bdd = {};
|
|
||||||
private bddPomise = {};
|
|
||||||
private baseLocalStorageName = 'bdd_';
|
|
||||||
private useLocalStorage = false; // we exceed the limit of 5MB
|
|
||||||
|
|
||||||
constructor(private http: HttpWrapperService) {
|
|
||||||
console.log('Start BddService');
|
|
||||||
}
|
|
||||||
|
|
||||||
addAfterPost(name: string, ret: any) {
|
|
||||||
let self = this;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
self.get(name)
|
|
||||||
.then((response: DataInterface) => {
|
|
||||||
let responseTmp = response;
|
|
||||||
ret.then(response2 => {
|
|
||||||
responseTmp.add(response2);
|
|
||||||
resolve(response2);
|
|
||||||
}).catch(response2 => {
|
|
||||||
reject(response2);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(response => {
|
|
||||||
reject(response);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setAfterPut(name: string, id: number, ret: any) {
|
|
||||||
let self = this;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
self.get(name)
|
|
||||||
.then((response: DataInterface) => {
|
|
||||||
let responseTmp = response;
|
|
||||||
ret.then(response2 => {
|
|
||||||
responseTmp.set(id, response2);
|
|
||||||
resolve(response2);
|
|
||||||
}).catch(response2 => {
|
|
||||||
reject(response2);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(response => {
|
|
||||||
reject(response);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
asyncSetInDB(name: string, id: number, data: any) {
|
|
||||||
let self = this;
|
|
||||||
self.get(name)
|
|
||||||
.then((response: DataInterface) => {
|
|
||||||
response.set(id, data);
|
|
||||||
})
|
|
||||||
.catch(response => {
|
|
||||||
// nothing to do ...
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(name: string, id: number, ret: any) {
|
|
||||||
let self = this;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
self.get(name)
|
|
||||||
.then((response: DataInterface) => {
|
|
||||||
let responseTmp = response;
|
|
||||||
ret.then(response2 => {
|
|
||||||
responseTmp.delete(id);
|
|
||||||
resolve(response2);
|
|
||||||
}).catch(response2 => {
|
|
||||||
reject(response2);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(response => {
|
|
||||||
reject(response);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get(name: string): Promise<DataInterface> {
|
|
||||||
let self = this;
|
|
||||||
//console.log(`Try to get DB '${ name }'`);
|
|
||||||
if (!isNullOrUndefined(this.bdd[name])) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
resolve(self.bdd[name]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//console.log(`get DB: ?? ${ name } ??`);
|
|
||||||
if (isNullOrUndefined(this.bddPomise[name])) {
|
|
||||||
this.bddPomise[name] = [];
|
|
||||||
// Try to load Local Data (storage)
|
|
||||||
let retriveBDDString = null;
|
|
||||||
if (this.useLocalStorage === true) {
|
|
||||||
localStorage.getItem(this.baseLocalStorageName + name);
|
|
||||||
}
|
|
||||||
if (retriveBDDString !== null) {
|
|
||||||
//console.log(`retrive local bdd string (${ name })= ${ retriveBDDString}`);
|
|
||||||
let retriveBDD = JSON.parse(retriveBDDString);
|
|
||||||
//console.log(`retrive local bdd (${ name })= ${ retriveBDD}`);
|
|
||||||
let retriveBDDTmp = new DataInterface(name, retriveBDD);
|
|
||||||
self.bdd[name] = retriveBDDTmp;
|
|
||||||
for (let iii = 0; iii < self.bddPomise[name].length; iii++) {
|
|
||||||
self.bddPomise[name][iii].resolve(self.bdd[name]);
|
|
||||||
}
|
|
||||||
// brut force update of the BDD : TODO optimise it later ...
|
|
||||||
//console.log(`Update BDD (${ name })`);
|
|
||||||
|
|
||||||
self.http
|
|
||||||
.getSpecific(name)
|
|
||||||
.then(response => {
|
|
||||||
//console.log(`end download DB: ==> ${ name } ${ response.length}`);
|
|
||||||
self.bdd[name] = new DataInterface(name, response);
|
|
||||||
localStorage.setItem(self.baseLocalStorageName + name, JSON.stringify(self.bdd[name].bdd));
|
|
||||||
})
|
|
||||||
.catch(response => {
|
|
||||||
console.log(`[E] ${self.constructor.name}: cant not get data from remote server: ${name}`);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
//console.log(`Download BDD (${ name })`);
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
self.http
|
|
||||||
.getSpecific(name)
|
|
||||||
.then(response => {
|
|
||||||
//console.log(`end download DB: ==> ${ name } ${ response.length}`);// + " " + JSON.stringify(response).length);
|
|
||||||
self.bdd[name] = new DataInterface(name, response);
|
|
||||||
if (self.useLocalStorage === true) {
|
|
||||||
localStorage.setItem(
|
|
||||||
self.baseLocalStorageName + name,
|
|
||||||
JSON.stringify(self.bdd[name].bdd)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for (let iii = 0; iii < self.bddPomise[name].length; iii++) {
|
|
||||||
self.bddPomise[name][iii].resolve(self.bdd[name]);
|
|
||||||
}
|
|
||||||
resolve(self.bdd[name]);
|
|
||||||
})
|
|
||||||
.catch(response => {
|
|
||||||
console.log(`[E] ${self.constructor.name}: can not get data from remote server: ${name}`);
|
|
||||||
for (let iii = 0; iii < self.bddPomise[name].length; iii++) {
|
|
||||||
self.bddPomise[name][iii].reject(response);
|
|
||||||
}
|
|
||||||
reject(response);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (!isNullOrUndefined(self.bdd[name])) {
|
|
||||||
resolve(self.bdd[name]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
self.bddPomise[name].push({ resolve: resolve, reject: reject });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class CookiesService {
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
set(cname: string, cvalue: string, exdays: number): void {
|
|
||||||
if (this.get(cname) !== '') {
|
|
||||||
// reset previous cookies...
|
|
||||||
document.cookie = `${cname}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`;
|
|
||||||
}
|
|
||||||
let ddd = new Date();
|
|
||||||
ddd.setTime(ddd.getTime() + exdays * 24 * 60 * 60 * 1000);
|
|
||||||
let expires = `expires=${ddd.toUTCString()}`;
|
|
||||||
document.cookie = `${cname}=${cvalue};${expires};path=/`;
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(cname: string): void {
|
|
||||||
this.set(cname, '', 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
get(cname: string): string | undefined {
|
|
||||||
let name = `${cname}=`;
|
|
||||||
let coolies = document.cookie.split(';');
|
|
||||||
for (let iii = 0; iii < coolies.length; iii++) {
|
|
||||||
let ccc = coolies[iii];
|
|
||||||
while (ccc.charAt(0) === ' ') {
|
|
||||||
ccc = ccc.substring(1);
|
|
||||||
}
|
|
||||||
if (ccc.indexOf(name) === 0) {
|
|
||||||
return ccc.substring(name.length, ccc.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,491 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpClient, HttpHeaders, HttpEventType } from '@angular/common/http';
|
|
||||||
|
|
||||||
import { environment } from 'environments/environment';
|
|
||||||
|
|
||||||
import { SessionService } from './session';
|
|
||||||
import { isArrayOfs, isBoolean, isNullOrUndefined, isNumber, isString } from 'common/utils';
|
|
||||||
|
|
||||||
export enum HTTPRequestModel {
|
|
||||||
POST = 'POST',
|
|
||||||
GET = 'GET',
|
|
||||||
PUT = 'PUT',
|
|
||||||
DELETE = 'DELETE',
|
|
||||||
PATCH = 'PATCH',
|
|
||||||
}
|
|
||||||
export enum HTTPMimeType {
|
|
||||||
ALL = '*/*',
|
|
||||||
JSON = 'application/json',
|
|
||||||
OCTET_STREAM = 'application/octet-stream',
|
|
||||||
IMAGE = 'image/*',
|
|
||||||
IMAGE_JPEG = 'image/jpeg',
|
|
||||||
IMAGE_PNG = 'image/png',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type UrlPath = string | boolean | number | (string | boolean | number)[];
|
|
||||||
export type ProgressCallback = (count: number, total: number) => void;
|
|
||||||
|
|
||||||
export interface HTTPRequest {
|
|
||||||
server?: string;
|
|
||||||
endPoint: UrlPath;
|
|
||||||
requestType: HTTPRequestModel;
|
|
||||||
accept: HTTPMimeType;
|
|
||||||
contentType: HTTPMimeType;
|
|
||||||
params?: object;
|
|
||||||
body?: any;
|
|
||||||
authorization?: string; // c'est un hook de merde ...
|
|
||||||
disableTocken?: boolean;
|
|
||||||
// progress interface to notify progression of the streaming.
|
|
||||||
progress?: ProgressCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ModelResponseHttp {
|
|
||||||
status: number;
|
|
||||||
data: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This service permit to add some data like tocken and authorisation.. ir automatically get the token if needed and retake it if expired...
|
|
||||||
*/
|
|
||||||
@Injectable()
|
|
||||||
export class HttpWrapperService {
|
|
||||||
private displayReturn: boolean = false;
|
|
||||||
constructor(private http: HttpClient, private session: SessionService) { }
|
|
||||||
|
|
||||||
addTokenIfNeeded(headerOption: any): any {
|
|
||||||
const token = this.session.getToken();
|
|
||||||
if (!isNullOrUndefined(token)) {
|
|
||||||
if (headerOption.Authorization === undefined) {
|
|
||||||
headerOption.Authorization = `Yota ${token}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return headerOption;
|
|
||||||
}
|
|
||||||
|
|
||||||
request(properties: HTTPRequest): Promise<Response> {
|
|
||||||
let connectionAddresses = this.createRESTCall2({
|
|
||||||
server: properties.server,
|
|
||||||
api: properties.endPoint,
|
|
||||||
inputOptions: properties.params,
|
|
||||||
});
|
|
||||||
let headers: any = {
|
|
||||||
Accept: properties.accept,
|
|
||||||
//'Content-Type': properties.contentType,
|
|
||||||
};
|
|
||||||
if (properties.authorization !== undefined && properties.authorization !== null) {
|
|
||||||
headers['Authorization'] = properties.authorization;
|
|
||||||
}
|
|
||||||
if (properties.requestType !== HTTPRequestModel.GET) {
|
|
||||||
headers['Content-Type'] = properties.contentType;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
properties.disableTocken === undefined ||
|
|
||||||
properties.disableTocken === null ||
|
|
||||||
properties.disableTocken === false
|
|
||||||
) {
|
|
||||||
headers = this.addTokenIfNeeded(headers);
|
|
||||||
}
|
|
||||||
//console.log(`header: ${JSON.stringify(headers)}`);
|
|
||||||
let body = properties.body;
|
|
||||||
if (properties.contentType === HTTPMimeType.JSON) {
|
|
||||||
body = JSON.stringify(properties.body);
|
|
||||||
}
|
|
||||||
console.log(`Call ${connectionAddresses}`)
|
|
||||||
const result = fetch(connectionAddresses, {
|
|
||||||
method: properties.requestType,
|
|
||||||
headers,
|
|
||||||
body,
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestJson(properties: HTTPRequest): Promise<ModelResponseHttp> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.request(properties)
|
|
||||||
.then((response: Response) => {
|
|
||||||
if (response.status >= 200 && response.status <= 299) {
|
|
||||||
const contentType = response.headers.get('Content-Type');
|
|
||||||
if (contentType === HTTPMimeType.JSON) {
|
|
||||||
response
|
|
||||||
.json()
|
|
||||||
.then((value: any) => {
|
|
||||||
//console.log(`RECEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`);
|
|
||||||
resolve({ status: response.status, data: value });
|
|
||||||
})
|
|
||||||
.catch((reason: any) => {
|
|
||||||
reject({ status: 999, data: reason });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error(`content Type is not Json: ${contentType}`);
|
|
||||||
reject({ status: 999, data: `content Type is not Json: ${contentType}` });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error(`wring correct status: ${response.status}`);
|
|
||||||
reject({ status: 900, data: response });
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
reject({
|
|
||||||
time: Date(),
|
|
||||||
status: 999,
|
|
||||||
error: error,
|
|
||||||
statusMessage: "Fetch error",
|
|
||||||
message: "http-wrapper.ts detect an error in the fetch request"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
requestImage(properties: HTTPRequest): Promise<ModelResponseHttp> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.request(properties)
|
|
||||||
.then((response: Response) => {
|
|
||||||
if (response.status >= 200 && response.status <= 299) {
|
|
||||||
const contentType = response.headers.get('Content-Type');
|
|
||||||
//console.log(`REICEIVE ==> ${response.status}`);
|
|
||||||
resolve({ status: 900, data: response });
|
|
||||||
/*
|
|
||||||
resolve({ status:response.status, data:value });
|
|
||||||
}).catch((reason:any)=> {
|
|
||||||
reject({ status:999, data:reason });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error(`content Type is not Json: ${contentType}`)
|
|
||||||
reject({ status:999, data:`content Type is not Json: ${contentType}` });
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
console.error(`wring correct status: ${response.status}`);
|
|
||||||
resolve({ status: 900, data: response });
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
reject({
|
|
||||||
time: Date(),
|
|
||||||
status: 999,
|
|
||||||
error: error,
|
|
||||||
statusMessage: "Fetch image error",
|
|
||||||
message: "http-wrapper.ts detect an error in the fetch request"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
createRESTCall2({
|
|
||||||
api,
|
|
||||||
server,
|
|
||||||
inputOptions,
|
|
||||||
addURLToken,
|
|
||||||
}: {
|
|
||||||
server?: string;
|
|
||||||
api: UrlPath;
|
|
||||||
inputOptions?: object;
|
|
||||||
addURLToken?: boolean;
|
|
||||||
}) {
|
|
||||||
if (isNullOrUndefined(server)) {
|
|
||||||
server = environment.defaultServer;
|
|
||||||
}
|
|
||||||
const basePage = environment.server[server];
|
|
||||||
let addressServerRest = basePage;
|
|
||||||
if (!basePage.endsWith('/')) {
|
|
||||||
addressServerRest = `${basePage}/`;
|
|
||||||
}
|
|
||||||
let options = inputOptions;
|
|
||||||
if (isNullOrUndefined(options)) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
let out = addressServerRest;
|
|
||||||
if (isArrayOfs(api, isString, isNumber, isBoolean)) {
|
|
||||||
for (let iii = 0; iii < api.length; iii++) {
|
|
||||||
let elem = api[iii];
|
|
||||||
if (out.endsWith('/')) {
|
|
||||||
out += elem;
|
|
||||||
} else {
|
|
||||||
out += `/${elem}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out += api;
|
|
||||||
}
|
|
||||||
let first = true;
|
|
||||||
let keys = Object.keys(options);
|
|
||||||
for (let iii = 0; iii < keys.length; iii++) {
|
|
||||||
if (first === false) {
|
|
||||||
out = `${out}&`;
|
|
||||||
} else {
|
|
||||||
out = `${out}?`;
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
out = out + keys[iii];
|
|
||||||
if (options[keys[iii]] != null) {
|
|
||||||
out = out + '=' + options[keys[iii]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//console.log(`try to get session : ${this.session.getToken()}`);
|
|
||||||
if (!isNullOrUndefined(this.session.getToken())) {
|
|
||||||
if (addURLToken !== undefined && addURLToken === true) {
|
|
||||||
if (first === false) {
|
|
||||||
out = `${out}&`;
|
|
||||||
} else {
|
|
||||||
out = `${out}?`;
|
|
||||||
}
|
|
||||||
out = out + `Authorization=Yota ${this.session.getToken()}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated ...
|
|
||||||
createRESTCall(api: string, inputOptions?: any) {
|
|
||||||
let basePage = environment.server[environment.defaultServer];
|
|
||||||
let addressServerRest = `${basePage}/`;
|
|
||||||
let options = inputOptions;
|
|
||||||
if (options === undefined) {
|
|
||||||
options = [];
|
|
||||||
}
|
|
||||||
let out = addressServerRest + api;
|
|
||||||
let first = true;
|
|
||||||
for (let iii = 0; iii < options.length; iii++) {
|
|
||||||
if (first === false) {
|
|
||||||
out = `${out}&`;
|
|
||||||
} else {
|
|
||||||
out = `${out}?`;
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
out = out + options[iii];
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
// Deprecated ... old model stream
|
|
||||||
post(uriRest: string, headerOption: any, data: any, progress: ProgressCallback = null) {
|
|
||||||
//console.log(`-------------------------------------------------------\nHTTP-wrapper POST '${ uriRest }'\n\t\theaderOption=${ JSON.stringify(headerOption, null, 2)}\n\t\tdata=${ JSON.stringify(data, null, 2)}`);
|
|
||||||
this.addTokenIfNeeded(headerOption);
|
|
||||||
let connectionAddresses = this.createRESTCall(uriRest, {});
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (this.displayReturn === true) {
|
|
||||||
console.log(`call POST ${connectionAddresses} data=${JSON.stringify(data, null, 2)}`);
|
|
||||||
}
|
|
||||||
let request = this.http.post(connectionAddresses, data, {
|
|
||||||
headers: new HttpHeaders(headerOption),
|
|
||||||
reportProgress: true,
|
|
||||||
observe: 'events',
|
|
||||||
});
|
|
||||||
let self = this;
|
|
||||||
request.subscribe(
|
|
||||||
(res: any) => {
|
|
||||||
if (self.displayReturn === true) {
|
|
||||||
console.log(`!! data ${JSON.stringify(res, null, 2)}`);
|
|
||||||
}
|
|
||||||
if (res.type === HttpEventType.Sent) {
|
|
||||||
/* res.type === 0 */
|
|
||||||
//console.log('post : Sent');
|
|
||||||
} else if (res.type === HttpEventType.UploadProgress) {
|
|
||||||
/* res.type === 1 */
|
|
||||||
// console.log("post : " + res.loaded + " / " + res.total);
|
|
||||||
progress(res.loaded, res.total);
|
|
||||||
} else if (res.type === HttpEventType.ResponseHeader) {
|
|
||||||
/* res.type === 2 */
|
|
||||||
//console.log('post : get header');
|
|
||||||
} else if (res.type === HttpEventType.DownloadProgress) {
|
|
||||||
/* res.type === 3 */
|
|
||||||
//console.log(`post : get DownloadProgress ${ res.loaded}`);
|
|
||||||
} else if (res.type === HttpEventType.Response) {
|
|
||||||
/* res.type === 4 */
|
|
||||||
//console.log('post : get response');
|
|
||||||
if (res.httpCode) {
|
|
||||||
resolve({ status: res.httpCode, data: res });
|
|
||||||
} else {
|
|
||||||
resolve({ status: 200, data: res });
|
|
||||||
}
|
|
||||||
} else if (res.type === HttpEventType.User) {
|
|
||||||
/* res.type === 5 */
|
|
||||||
//console.log('post : get User');
|
|
||||||
} else {
|
|
||||||
console.log(`post : get unknown ... ${res.type}`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
if (self.displayReturn === true) {
|
|
||||||
console.log(`an error occured status: ${error.status}`);
|
|
||||||
console.log(`answer: ${JSON.stringify(error, null, 2)}`);
|
|
||||||
}
|
|
||||||
reject({ status: error.status, data: error.error });
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Deprecated ... old model stream
|
|
||||||
uploadMultipart(base: string, multipart: FormData, progress: ProgressCallback): any {
|
|
||||||
//console.log(`Upload multipart to ${ base}`);
|
|
||||||
|
|
||||||
let url = base;
|
|
||||||
let self = this;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let headers = {
|
|
||||||
// 'Content-Type': 'multipart/form-data',
|
|
||||||
}; // new Headers();
|
|
||||||
|
|
||||||
self.post(url, headers, multipart, progress).then(
|
|
||||||
(response: any) => {
|
|
||||||
//console.log(`URL: ${ url }\nRespond(${ response.status }): ${ JSON.stringify(response.data, null, 2)}`);
|
|
||||||
if (response.status >= 200 && response.status <= 299) {
|
|
||||||
resolve(response.data.body);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
reject('An error occured');
|
|
||||||
},
|
|
||||||
(response: any) => {
|
|
||||||
if (typeof response.data === 'undefined') {
|
|
||||||
reject('return ERROR undefined');
|
|
||||||
} else {
|
|
||||||
reject('return ERROR ...'); // + JSON.stringify(response, null, 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex wrapper to simplify interaction:
|
|
||||||
getSpecific(urlPath: UrlPath): any {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.requestJson({
|
|
||||||
endPoint: urlPath,
|
|
||||||
requestType: HTTPRequestModel.GET,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
contentType: HTTPMimeType.JSON,
|
|
||||||
}).then(
|
|
||||||
(response: ModelResponseHttp) => {
|
|
||||||
//console.log("URL: " + url + "\nRespond(" + response.status + "): " + JSON.stringify(response.data, null, 2));
|
|
||||||
if (response.status === 200) {
|
|
||||||
resolve(response.data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
reject('An error occured');
|
|
||||||
},
|
|
||||||
(response: ModelResponseHttp) => {
|
|
||||||
if (isNullOrUndefined(response.data)) {
|
|
||||||
reject('return ERROR undefined');
|
|
||||||
} else {
|
|
||||||
reject(`return ERROR ${JSON.stringify(response.data, null, 2)}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex wrapper to simplify interaction:s
|
|
||||||
putSpecific(urlPath: UrlPath, data: object): Promise<ModelResponseHttp> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.request({
|
|
||||||
endPoint: urlPath,
|
|
||||||
requestType: HTTPRequestModel.PUT,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
contentType: HTTPMimeType.JSON,
|
|
||||||
body: data,
|
|
||||||
})
|
|
||||||
.then((response: Response) => {
|
|
||||||
if (response.status >= 200 && response.status <= 201) {
|
|
||||||
const contentType = response.headers.get('Content-Type');
|
|
||||||
if (contentType === HTTPMimeType.JSON) {
|
|
||||||
response
|
|
||||||
.json()
|
|
||||||
.then((value: any) => {
|
|
||||||
//console.log(`REICEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`);
|
|
||||||
resolve({ status: response.status, data: value });
|
|
||||||
})
|
|
||||||
.catch((reason: any) => {
|
|
||||||
reject({ status: 999, data: reason });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error(`content Type is not Json: ${contentType}`);
|
|
||||||
reject({ status: 998, data: `content Type is not Json: ${contentType}` });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error(`wrong correct status: ${response.status}`);
|
|
||||||
reject({ status: 900, data: response });
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
reject({ status: error.status, data: error.error });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
postSpecific(urlPath: UrlPath, data: object): Promise<ModelResponseHttp> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.request({
|
|
||||||
endPoint: urlPath,
|
|
||||||
requestType: HTTPRequestModel.POST,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
contentType: HTTPMimeType.JSON,
|
|
||||||
body: data,
|
|
||||||
})
|
|
||||||
.then((response: Response) => {
|
|
||||||
if (response.status >= 200 && response.status <= 201) {
|
|
||||||
const contentType = response.headers.get('Content-Type');
|
|
||||||
if (contentType === HTTPMimeType.JSON) {
|
|
||||||
response
|
|
||||||
.json()
|
|
||||||
.then((value: any) => {
|
|
||||||
//console.log(`REICEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`);
|
|
||||||
resolve({ status: response.status, data: value });
|
|
||||||
})
|
|
||||||
.catch((reason: any) => {
|
|
||||||
reject({ status: 999, data: reason });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error(`content Type is not Json: ${contentType}`);
|
|
||||||
reject({ status: 998, data: `content Type is not Json: ${contentType}` });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error(`wrong correct status: ${response.status}`);
|
|
||||||
reject({ status: 900, data: response });
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
reject({ status: error.status, data: error.error });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
deleteSpecific(urlPath: UrlPath): Promise<ModelResponseHttp> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.request({
|
|
||||||
endPoint: urlPath,
|
|
||||||
requestType: HTTPRequestModel.DELETE,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
contentType: HTTPMimeType.JSON,
|
|
||||||
})
|
|
||||||
.then((response: Response) => {
|
|
||||||
if (response.status >= 200 && response.status <= 201) {
|
|
||||||
const contentType = response.headers.get('Content-Type');
|
|
||||||
if (contentType === HTTPMimeType.JSON) {
|
|
||||||
response
|
|
||||||
.json()
|
|
||||||
.then((value: any) => {
|
|
||||||
//console.log(`REICEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`);
|
|
||||||
resolve({ status: response.status, data: value });
|
|
||||||
})
|
|
||||||
.catch((reason: any) => {
|
|
||||||
reject({ status: 999, data: reason });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error(`content Type is not Json: ${contentType}`);
|
|
||||||
reject({ status: 998, data: `content Type is not Json: ${contentType}` });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error(`wrong correct status: ${response.status}`);
|
|
||||||
reject({ status: 900, data: response });
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
reject({ status: error.status, data: error.error });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
import { BddService } from './bdd';
|
|
||||||
import { CookiesService } from './cookies';
|
|
||||||
import { HttpWrapperService, ModelResponseHttp, HTTPRequest, HTTPMimeType, HTTPRequestModel } from './http-wrapper';
|
|
||||||
import { StorageService } from './local-storage';
|
|
||||||
import { NotificationService } from './notification';
|
|
||||||
import { PopInService } from './popin';
|
|
||||||
import {
|
|
||||||
OnlyAdminGuard,
|
|
||||||
OnlyUnregisteredGuardHome,
|
|
||||||
OnlyUsersGuard,
|
|
||||||
OnlyUsersGuardHome,
|
|
||||||
SessionService,
|
|
||||||
} from './session';
|
|
||||||
import { SSOService } from './sso';
|
|
||||||
import { UserService } from './user';
|
|
||||||
|
|
||||||
export {
|
|
||||||
BddService,
|
|
||||||
CookiesService,
|
|
||||||
StorageService,
|
|
||||||
HttpWrapperService,
|
|
||||||
ModelResponseHttp,
|
|
||||||
HTTPRequest,
|
|
||||||
HTTPMimeType,
|
|
||||||
HTTPRequestModel,
|
|
||||||
PopInService,
|
|
||||||
SessionService,
|
|
||||||
UserService,
|
|
||||||
SSOService,
|
|
||||||
OnlyUsersGuard,
|
|
||||||
OnlyUsersGuardHome,
|
|
||||||
OnlyUnregisteredGuardHome,
|
|
||||||
OnlyAdminGuard,
|
|
||||||
NotificationService,
|
|
||||||
};
|
|
@ -1,50 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { environment } from 'environments/environment';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class StorageService {
|
|
||||||
private baseLocalStorageName = environment.applName + '_';
|
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
set(cname: string, cvalue: string): void {
|
|
||||||
//console.debug(`storage set: ${cname} : ${cvalue}`);
|
|
||||||
localStorage.setItem(this.baseLocalStorageName + cname, cvalue);
|
|
||||||
}
|
|
||||||
// limit at the current session ...
|
|
||||||
setSession(cname: string, cvalue: string): void {
|
|
||||||
sessionStorage.setItem(this.baseLocalStorageName + cname, cvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(cname: string): void {
|
|
||||||
//console.debug(`storage remove: ${cname}`);
|
|
||||||
localStorage.removeItem(this.baseLocalStorageName + cname);
|
|
||||||
}
|
|
||||||
removeSession(cname: string): void {
|
|
||||||
sessionStorage.removeItem(this.baseLocalStorageName + cname);
|
|
||||||
}
|
|
||||||
|
|
||||||
get(cname: string): string | undefined {
|
|
||||||
//console.debug(`storage get: ${cname}`);
|
|
||||||
// TODO check expire day...
|
|
||||||
const data = localStorage.getItem(this.baseLocalStorageName + cname);
|
|
||||||
//console.debug(`get value form the storage (1): ${data}`)
|
|
||||||
if (data === null || data === undefined) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
getSession(cname: string): string | undefined {
|
|
||||||
const data = sessionStorage.getItem(this.baseLocalStorageName + cname);
|
|
||||||
if (data === null || data === undefined) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class NotificationService {
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
console.log('Start Notification Service');
|
|
||||||
}
|
|
||||||
|
|
||||||
errorRaw(data: any) {
|
|
||||||
console.error(`get notification error: ${data}`)
|
|
||||||
}
|
|
||||||
warningRaw(data: any) {
|
|
||||||
console.info(`get notification warning: ${data}`)
|
|
||||||
}
|
|
||||||
infoRaw(data: any) {
|
|
||||||
console.info(`get notification info: ${data}`)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class PopInService {
|
|
||||||
private popins: any[] = [];
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
console.log('Start PopIn Service');
|
|
||||||
}
|
|
||||||
|
|
||||||
add(_popin: any) {
|
|
||||||
// add popin to array of active popins
|
|
||||||
this.popins.push(_popin);
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(_id: string) {
|
|
||||||
// remove popin from array of active popins
|
|
||||||
for (let iii = 0; iii < this.popins.length; iii++) {
|
|
||||||
if (this.popins[iii].id === _id) {
|
|
||||||
this.popins.splice(iii, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open(_id: string) {
|
|
||||||
console.log("Try to open pop-in: '" + _id + "'");
|
|
||||||
// open popin specified by id
|
|
||||||
for (let iii = 0; iii < this.popins.length; iii++) {
|
|
||||||
console.log(` check: ${this.popins[iii].id}`);
|
|
||||||
if (this.popins[iii].id === _id) {
|
|
||||||
console.log(" ==>find it ...");
|
|
||||||
this.popins[iii].open();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(" ==> NOT found !!!!!");
|
|
||||||
}
|
|
||||||
|
|
||||||
close(_id: string) {
|
|
||||||
// close popin specified by id
|
|
||||||
for (let iii = 0; iii < this.popins.length; iii++) {
|
|
||||||
if (this.popins[iii].id === _id) {
|
|
||||||
this.popins[iii].close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,178 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable, Output, EventEmitter } from '@angular/core';
|
|
||||||
import { CanActivate, Router } from '@angular/router';
|
|
||||||
import { isNullOrUndefined } from 'common/utils';
|
|
||||||
import { environment } from 'environments/environment';
|
|
||||||
|
|
||||||
export enum UserRoles222 {
|
|
||||||
admin = 'admin',
|
|
||||||
user = 'user',
|
|
||||||
guest = 'guest',
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class SessionService {
|
|
||||||
private tokenJwt = null;
|
|
||||||
public userLogin = null;
|
|
||||||
public userId = null;
|
|
||||||
public right: any = {};
|
|
||||||
|
|
||||||
@Output() change: EventEmitter<boolean> = new EventEmitter();
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create a new session.
|
|
||||||
*
|
|
||||||
* @param userId -
|
|
||||||
* @param userLogin -
|
|
||||||
* @param tokenJwt -
|
|
||||||
*/
|
|
||||||
create({
|
|
||||||
userId,
|
|
||||||
userLogin,
|
|
||||||
tokenJwt,
|
|
||||||
}: {
|
|
||||||
userId: string;
|
|
||||||
userLogin: string;
|
|
||||||
tokenJwt: string;
|
|
||||||
}) {
|
|
||||||
console.log(
|
|
||||||
`Session Create: userId=${userId} userLogin=${userLogin} tokenJwt = ${tokenJwt}`
|
|
||||||
);
|
|
||||||
this.tokenJwt = tokenJwt;
|
|
||||||
this.userId = userId;
|
|
||||||
this.userLogin = userLogin;
|
|
||||||
this.right = this.parseToken(tokenJwt);
|
|
||||||
console.log(`Retrieve right: ${JSON.stringify(this.right, null, 4)}`);
|
|
||||||
this.change.emit(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
b64_to_utf8(str: string): string {
|
|
||||||
return decodeURIComponent(window.atob(str));
|
|
||||||
}
|
|
||||||
parseToken(token: string): any {
|
|
||||||
const cut = token.split('.');
|
|
||||||
const decoded = this.b64_to_utf8(cut[1]);
|
|
||||||
const jsonModel = JSON.parse(decoded);
|
|
||||||
if (isNullOrUndefined(jsonModel.right)) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (isNullOrUndefined(jsonModel.right[environment.applName])) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return jsonModel.right[environment.applName];
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @brief destroy the current session.
|
|
||||||
*/
|
|
||||||
destroy() {
|
|
||||||
console.log('Session REMOVE');
|
|
||||||
this.tokenJwt = undefined;
|
|
||||||
this.userId = null;
|
|
||||||
this.userLogin = null;
|
|
||||||
this.right = {};
|
|
||||||
this.change.emit(false);
|
|
||||||
}
|
|
||||||
getToken(): string | undefined {
|
|
||||||
return this.tokenJwt;
|
|
||||||
}
|
|
||||||
islogged() {
|
|
||||||
return this.userId !== null;
|
|
||||||
}
|
|
||||||
hasRight(type: UserRoles222): boolean {
|
|
||||||
if (type === UserRoles222.admin) {
|
|
||||||
if (isNullOrUndefined(this.right.ADMIN)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return this.right.ADMIN;
|
|
||||||
}
|
|
||||||
if (type === UserRoles222.user) {
|
|
||||||
if (isNullOrUndefined(this.right.USER)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return this.right.USER;
|
|
||||||
}
|
|
||||||
if (type === UserRoles222.guest) {
|
|
||||||
// all the other ... maybe unneeded
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
hasNotRight(type) {
|
|
||||||
return !this.hasRight(type);
|
|
||||||
}
|
|
||||||
getLogin() {
|
|
||||||
return this.userLogin;
|
|
||||||
}
|
|
||||||
getAvatar() {
|
|
||||||
return 'assets/images/avatar_generic.svg';
|
|
||||||
/* This is not ready:
|
|
||||||
if(this.userAvatar === false) {
|
|
||||||
return 'assets/images/avatar_generic.svg';
|
|
||||||
}
|
|
||||||
return this.userId;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class OnlyUsersGuard implements CanActivate {
|
|
||||||
constructor(private sessionService: SessionService, private router: Router) { }
|
|
||||||
|
|
||||||
canActivate() {
|
|
||||||
console.log('OnlyLoggedInUsers');
|
|
||||||
if (this.sessionService.hasRight(UserRoles222.user) || this.sessionService.hasRight(UserRoles222.admin)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
this.router.navigateByUrl('/forbidden');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class OnlyUsersGuardHome implements CanActivate {
|
|
||||||
constructor(private sessionService: SessionService, private router: Router) { }
|
|
||||||
|
|
||||||
canActivate() {
|
|
||||||
if (this.sessionService.hasRight(UserRoles222.user) || this.sessionService.hasRight(UserRoles222.admin)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
this.router.navigateByUrl('/unregistered');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Injectable()
|
|
||||||
export class OnlyUnregisteredGuardHome implements CanActivate {
|
|
||||||
constructor(private sessionService: SessionService, private router: Router) { }
|
|
||||||
|
|
||||||
canActivate() {
|
|
||||||
if (!this.sessionService.islogged()) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
this.router.navigateByUrl('/home');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class OnlyAdminGuard implements CanActivate {
|
|
||||||
constructor(private sessionService: SessionService, private router: Router) { }
|
|
||||||
|
|
||||||
canActivate() {
|
|
||||||
if (this.sessionService.hasRight(UserRoles222.user)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
this.router.navigateByUrl('/forbidden');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { environment } from 'environments/environment';
|
|
||||||
import { getApplicationLocation, isInArray, isNullOrUndefined } from 'common/utils';
|
|
||||||
import { HTTPMimeType, HTTPRequestModel, HttpWrapperService, ModelResponseHttp } from 'common/service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class SSOService {
|
|
||||||
signUpEnable: boolean = undefined;
|
|
||||||
|
|
||||||
constructor(private http: HttpWrapperService) {
|
|
||||||
console.log('Start SSOService');
|
|
||||||
}
|
|
||||||
utf8_to_b64(str: string): string {
|
|
||||||
// remove unneeded "=" padding
|
|
||||||
return window.btoa(encodeURIComponent(str)).replace('=', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
b64_to_utf8(str: string): string {
|
|
||||||
return decodeURIComponent(window.atob(str));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Request SSO connection
|
|
||||||
*/
|
|
||||||
hashLocalData(data?: string): string {
|
|
||||||
if (
|
|
||||||
!isNullOrUndefined(data) &&
|
|
||||||
!isInArray(data, [
|
|
||||||
'',
|
|
||||||
'null',
|
|
||||||
'NULL',
|
|
||||||
'undefined',
|
|
||||||
'---',
|
|
||||||
'unregistered',
|
|
||||||
'unregistered/',
|
|
||||||
'forbidden',
|
|
||||||
'forbidden/',
|
|
||||||
])
|
|
||||||
) {
|
|
||||||
return this.utf8_to_b64(data);
|
|
||||||
}
|
|
||||||
const pathName = getApplicationLocation();
|
|
||||||
if (isInArray(pathName, ['sso', '/sso', '/sso/'])) {
|
|
||||||
return this.utf8_to_b64('home');
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
!isNullOrUndefined(pathName) &&
|
|
||||||
!isInArray(pathName, [
|
|
||||||
'',
|
|
||||||
'null',
|
|
||||||
'NULL',
|
|
||||||
'undefined',
|
|
||||||
'---',
|
|
||||||
'unregistered',
|
|
||||||
'unregistered/',
|
|
||||||
'forbidden',
|
|
||||||
'forbidden/',
|
|
||||||
])
|
|
||||||
) {
|
|
||||||
return this.utf8_to_b64(pathName);
|
|
||||||
}
|
|
||||||
return this.utf8_to_b64('home');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Request SSO connection
|
|
||||||
*/
|
|
||||||
unHashLocalData(data: string): string | undefined {
|
|
||||||
if (isNullOrUndefined(data) || isInArray(data, ['', 'null', 'NULL', 'undefined', '---'])) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return this.b64_to_utf8(data);
|
|
||||||
} catch (ex) {
|
|
||||||
console.error(`Can not convert the data: ${data}`);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Request Open SSO Global website
|
|
||||||
*/
|
|
||||||
requestOpenSite(): void {
|
|
||||||
window.location.href = environment.ssoSite;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Request SSO connection
|
|
||||||
*/
|
|
||||||
requestSignIn(name?: string): void {
|
|
||||||
window.location.href = environment.ssoSignIn + this.hashLocalData(name);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Request SSO Disconnect
|
|
||||||
*/
|
|
||||||
requestSignOut(name?: string): void {
|
|
||||||
window.location.href = environment.ssoSignOut + this.hashLocalData(name);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Request SSO signUp
|
|
||||||
*/
|
|
||||||
requestSignUp(name?: string): void {
|
|
||||||
window.location.href = environment.ssoSignUp + this.hashLocalData(name);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Checo if the signUp is authorized (generate by te SSO)
|
|
||||||
* @returns a promise of the State for sign-up
|
|
||||||
*/
|
|
||||||
checkSignUpEnable(): Promise<boolean> {
|
|
||||||
let self = this;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (isNullOrUndefined(self.signUpEnable)) {
|
|
||||||
this.http
|
|
||||||
.requestJson({
|
|
||||||
server: 'karso',
|
|
||||||
endPoint: 'system_config/is_sign_up_availlable',
|
|
||||||
requestType: HTTPRequestModel.GET,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
contentType: HTTPMimeType.JSON,
|
|
||||||
})
|
|
||||||
.then((response: ModelResponseHttp) => {
|
|
||||||
self.signUpEnable = response.data.signup;
|
|
||||||
resolve(self.signUpEnable);
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
reject(`return ERROR ${JSON.stringify(error, null, 2)}`);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve(self.signUpEnable);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,266 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
import { environment } from 'environments/environment';
|
|
||||||
|
|
||||||
import { HTTPMimeType, HTTPRequestModel, HttpWrapperService, ModelResponseHttp } from './http-wrapper';
|
|
||||||
import { StorageService } from 'common/service/local-storage';
|
|
||||||
import { SessionService } from './session';
|
|
||||||
import { SSOService } from './sso';
|
|
||||||
import { getApplicationLocation, isNullOrUndefined, sha512 } from 'common/utils';
|
|
||||||
|
|
||||||
/*
|
|
||||||
interface MessageLogIn {
|
|
||||||
login: string;
|
|
||||||
method: string;
|
|
||||||
time: number;
|
|
||||||
password: string;
|
|
||||||
}
|
|
||||||
interface MessageAnswer_USER_CONNECT {
|
|
||||||
sessionId: string;
|
|
||||||
login: string;
|
|
||||||
eMail: string;
|
|
||||||
role: string;
|
|
||||||
avatar: string;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@Injectable()
|
|
||||||
export class UserService {
|
|
||||||
// 0: Not hide password; 1 hide password;
|
|
||||||
private identificationVersion: number = 1;
|
|
||||||
private cookiesRememberMe = 'remember-me';
|
|
||||||
private cookiesToken = 'token';
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private router: Router,
|
|
||||||
private storageService: StorageService,
|
|
||||||
private http: HttpWrapperService,
|
|
||||||
private sessionService: SessionService,
|
|
||||||
private ssoService: SSOService
|
|
||||||
) {
|
|
||||||
console.log('Start UserService');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disconnect the user from the current session ==> this remove the curreent Token
|
|
||||||
*/
|
|
||||||
logOut(): void {
|
|
||||||
this.removeSession();
|
|
||||||
this.ssoService.requestSignOut('home');
|
|
||||||
}
|
|
||||||
removeSession(): void {
|
|
||||||
this.storageService.remove(this.cookiesRememberMe);
|
|
||||||
this.storageService.removeSession(this.cookiesToken);
|
|
||||||
this.storageService.remove(this.cookiesToken);
|
|
||||||
this.sessionService.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private isTokenUpToDate(token: string): boolean {
|
|
||||||
if (token === null || token === undefined || token.length < 25) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Separate the Data:
|
|
||||||
const elems = token.split('.');
|
|
||||||
if (elems.length !== 3) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// const tokenHeader = decodeURIComponent(window.atob( elems[0] ));
|
|
||||||
const tokenData = decodeURIComponent(window.atob(elems[1]));
|
|
||||||
// console.error(`Retreive local token: \nheader=${tokenHeader} \ndata=${tokenData}`);
|
|
||||||
const parsedData = JSON.parse(tokenData);
|
|
||||||
console.debug(
|
|
||||||
`Retreive token exp data=${new Date(parsedData.exp * 1000).toISOString()} < ${new Date().toISOString()}`
|
|
||||||
);
|
|
||||||
const expireIn = new Date(parsedData.exp * 1000);
|
|
||||||
const nowTime = new Date();
|
|
||||||
// TODO: set a marging of 2 hours...
|
|
||||||
return expireIn > nowTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
getRememberMe(): boolean {
|
|
||||||
return this.storageService.get(this.cookiesRememberMe) === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the system can be connected
|
|
||||||
*/
|
|
||||||
checkAutoConnect(): Promise<void> {
|
|
||||||
let locationOrigin = getApplicationLocation();
|
|
||||||
const self = this;
|
|
||||||
return new Promise<void>((resolve, reject) => {
|
|
||||||
// Need to use the windows global route to prevent the log in cycle ...
|
|
||||||
// And in the mlain application position, the route does not have curently root the page
|
|
||||||
let pathName = window.location.pathname;
|
|
||||||
// console.log("start Path-name: '" + pathName + "'");
|
|
||||||
// console.log("check with: '" + environment.applName + "/sso/" + "'");
|
|
||||||
if (pathName.startsWith('/sso/') || pathName.startsWith(environment.applName + '/sso/')) {
|
|
||||||
console.log(' ==> SSo section');
|
|
||||||
reject();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(' ==> Check if need reconnect?');
|
|
||||||
let rememberMe = self.getRememberMe();
|
|
||||||
// TODO: in case of jest reload ==> no need to manage the SSO ==> just keep the token ... it in enought...
|
|
||||||
let token = null;
|
|
||||||
if (
|
|
||||||
isNullOrUndefined(environment.tokenStoredInPermanentStorage) ||
|
|
||||||
environment.tokenStoredInPermanentStorage !== true
|
|
||||||
) {
|
|
||||||
token = self.storageService.getSession(self.cookiesToken);
|
|
||||||
} else {
|
|
||||||
token = self.storageService.get(self.cookiesToken);
|
|
||||||
}
|
|
||||||
// TODO: check validity of the Token:
|
|
||||||
if (self.isTokenUpToDate(token)) {
|
|
||||||
// remove in case of fail !!!
|
|
||||||
this.storageService.removeSession(this.cookiesToken);
|
|
||||||
this.storageService.remove(this.cookiesToken);
|
|
||||||
self.startSession(token, rememberMe)
|
|
||||||
.then(() => {
|
|
||||||
self.router.navigateByUrl(locationOrigin);
|
|
||||||
console.log(`update global URL = ${locationOrigin}`);
|
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
// jump in the sign-in page (automatically of request remember-me)
|
|
||||||
if (rememberMe) {
|
|
||||||
// jump to the sso !!! (remove local data to prevent login loop)
|
|
||||||
this.storageService.remove(this.cookiesRememberMe);
|
|
||||||
this.storageService.remove(this.cookiesToken);
|
|
||||||
this.storageService.removeSession(this.cookiesToken);
|
|
||||||
self.ssoService.requestSignIn(locationOrigin);
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log(`Get previous connection ... `);
|
|
||||||
if (rememberMe) {
|
|
||||||
// jump to the sso !!! (remove local data to prevent login loop)
|
|
||||||
this.storageService.remove(this.cookiesRememberMe);
|
|
||||||
this.storageService.remove(this.cookiesToken);
|
|
||||||
this.storageService.removeSession(this.cookiesToken);
|
|
||||||
self.ssoService.requestSignIn(locationOrigin);
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
startSession(token: string, rememberMe: boolean): Promise<string> {
|
|
||||||
const self = this;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
self.retreiveMe(token)
|
|
||||||
.then((value2: boolean) => {
|
|
||||||
if (rememberMe === true) {
|
|
||||||
self.storageService.set(self.cookiesRememberMe, rememberMe ? 'true' : 'false');
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
isNullOrUndefined(environment.tokenStoredInPermanentStorage) ||
|
|
||||||
environment.tokenStoredInPermanentStorage !== true
|
|
||||||
) {
|
|
||||||
self.storageService.setSession(self.cookiesToken, token);
|
|
||||||
} else {
|
|
||||||
self.storageService.set(self.cookiesToken, token);
|
|
||||||
}
|
|
||||||
resolve(self.sessionService.getLogin());
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
reject('sdfsdfsdf');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
retreiveMe(token: string): Promise<boolean> {
|
|
||||||
console.log(`AuthService.loginWithToken ... '${token}'`);
|
|
||||||
const self = this;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.http
|
|
||||||
.requestJson({
|
|
||||||
// server: 'karso',
|
|
||||||
endPoint: 'users/me',
|
|
||||||
requestType: HTTPRequestModel.GET,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
contentType: HTTPMimeType.JSON,
|
|
||||||
authorization: `Yota ${token}`, // special case, the token is set after this request...
|
|
||||||
})
|
|
||||||
.then((response: ModelResponseHttp) => {
|
|
||||||
// TODO: check type ...
|
|
||||||
console.log(`loginWithToken : get some data to check: ${JSON.stringify(response.data)}`);
|
|
||||||
self.sessionService.create({
|
|
||||||
//sessionId: response.data.sessionId,
|
|
||||||
userId: response.data.id,
|
|
||||||
userLogin: response.data.login,
|
|
||||||
//userEMail: response.data.email,
|
|
||||||
//userAdmin: response.data.admin,
|
|
||||||
//userBlocked: response.data.blocked,
|
|
||||||
//userRemoved: response.data.removed,
|
|
||||||
//userAvatar: response.data.avatar,
|
|
||||||
tokenJwt: token,
|
|
||||||
});
|
|
||||||
resolve(true);
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
reject(`return ERROR ${JSON.stringify(error, null, 2)}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
create(login: string, email: string, password: string) {
|
|
||||||
return this.createSha(login, email, sha512(password));
|
|
||||||
}
|
|
||||||
createSha(login: string, email: string, password: string) {
|
|
||||||
let data = {
|
|
||||||
method: 'v?',
|
|
||||||
login: login,
|
|
||||||
email: email,
|
|
||||||
password: password,
|
|
||||||
};
|
|
||||||
console.log(`call users data=${JSON.stringify(data, null, 2)}`);
|
|
||||||
|
|
||||||
if (this.identificationVersion === 1) {
|
|
||||||
data.method = 'v1';
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.http
|
|
||||||
.requestJson({
|
|
||||||
server: 'karso',
|
|
||||||
endPoint: 'users',
|
|
||||||
requestType: HTTPRequestModel.POST,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
contentType: HTTPMimeType.JSON,
|
|
||||||
body: data,
|
|
||||||
})
|
|
||||||
.then((response: ModelResponseHttp) => {
|
|
||||||
// TODO: check type ...
|
|
||||||
console.log(`createSha : get some data to check: ${JSON.stringify(response.data)}`);
|
|
||||||
resolve(response.data);
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
reject(`return ERROR ${JSON.stringify(error, null, 2)}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
isAuthenticated(): boolean {
|
|
||||||
// return !!Session.userId;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
isAuthorized(authorizedRoles: string): boolean {
|
|
||||||
/*
|
|
||||||
if (!angular.isArray(_authorizedRoles)) {
|
|
||||||
authorizedRoles = [_authorizedRoles];
|
|
||||||
}
|
|
||||||
return ( authService.isAuthenticated()
|
|
||||||
&& _authorizedRoles.indexOf(Session.userRole) !== -1
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
import { environment } from 'environments/environment';
|
|
||||||
|
|
||||||
export function getApplicationLocation(): string {
|
|
||||||
let pathName = location.pathname;
|
|
||||||
//console.log("start Path-name: '" + pathName + "'");
|
|
||||||
//console.log("check with: '" + environment.applName + "/sso/" + "'");
|
|
||||||
if (pathName.startsWith('/' + environment.applName + '/')) {
|
|
||||||
pathName = pathName.substring(environment.applName.length + 2);
|
|
||||||
} else if (pathName.startsWith('/' + environment.applName)) {
|
|
||||||
pathName = pathName.substring(environment.applName.length + 1);
|
|
||||||
} else if (pathName.startsWith(environment.applName + '/')) {
|
|
||||||
pathName = pathName.substring(environment.applName.length + 1);
|
|
||||||
} else if (pathName.startsWith(environment.applName)) {
|
|
||||||
pathName = pathName.substring(environment.applName.length);
|
|
||||||
}
|
|
||||||
return pathName;
|
|
||||||
}
|
|
@ -1,330 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license PROPRIETARY (see license file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { NodeData } from '../model';
|
|
||||||
import { isArray, isNullOrUndefined } from './validator';
|
|
||||||
|
|
||||||
export enum TypeCheck {
|
|
||||||
CONTAINS = 'C',
|
|
||||||
EQUAL = '==',
|
|
||||||
NOT_EQUAL = '!=',
|
|
||||||
LESS = '<',
|
|
||||||
LESS_EQUAL = '<=',
|
|
||||||
GREATER = '>',
|
|
||||||
GREATER_EQUAL = '>=',
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SelectModel {
|
|
||||||
check: TypeCheck;
|
|
||||||
key: string;
|
|
||||||
value?: number | string | boolean | number[] | string[];
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
{ check: TypeCheck.EQUAL, key: sss, value: null}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @breif Generic interface to access to the BDD (no BDD, direct file IO)
|
|
||||||
*/
|
|
||||||
export class DataInterface {
|
|
||||||
static extractLimitOne(data: NodeData[], key: string): any[] {
|
|
||||||
const out = [];
|
|
||||||
for (let iii = 0; iii < data.length; iii++) {
|
|
||||||
const value = data[iii][key];
|
|
||||||
if (DataInterface.existIn(value, out) === false) {
|
|
||||||
out.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
static extractLimitOneList(data: NodeData[], key: string): any[] {
|
|
||||||
const out = [];
|
|
||||||
for (let iii = 0; iii < data.length; iii++) {
|
|
||||||
const value = data[iii][key];
|
|
||||||
for (let jjj = 0; jjj < value.length; jjj++)
|
|
||||||
if (DataInterface.existIn(value[jjj], out) === false) {
|
|
||||||
out.push(value[jjj]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
constructor(private name: string, private bdd: NodeData[]) {}
|
|
||||||
|
|
||||||
public getTableIndex(id: number) {
|
|
||||||
for (let iii = 0; iii < this.bdd.length; iii++) {
|
|
||||||
if (this.bdd[iii].id === id) {
|
|
||||||
return iii;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
public gets(): NodeData[] {
|
|
||||||
console.log(`[I] gets ${this.name}`);
|
|
||||||
return this.bdd;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getsWhere(select: SelectModel[], orderBy?: string[]): NodeData[] {
|
|
||||||
// console.log("[I] gets_where " + this.name + " select " + _select);
|
|
||||||
let tmpList = this.getSubList(this.bdd, select);
|
|
||||||
tmpList = this.orderBy(tmpList, orderBy);
|
|
||||||
return tmpList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get(id: number): NodeData {
|
|
||||||
// console.log("[I] get " + this.name + " " + _id);
|
|
||||||
for (let iii = 0; iii < this.bdd.length; iii++) {
|
|
||||||
if (this.bdd[iii].id === id) {
|
|
||||||
return this.bdd[iii];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(`[W] not found element{ ${this.bdd.length}`);
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getNameLikeAll(name: string): NodeData[] {
|
|
||||||
let out = undefined;
|
|
||||||
let nameLower = name.toLowerCase();
|
|
||||||
for (let iii = 0; iii < this.bdd.length; iii++) {
|
|
||||||
if (this.bdd[iii].name.toLowerCase() === nameLower) {
|
|
||||||
out.push(this.bdd[iii]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (out.length === 0) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
public getNameLike(name: string): NodeData[] {
|
|
||||||
let out = [];
|
|
||||||
let nameLower = name.toLowerCase();
|
|
||||||
for (let iii = 0; iii < this.bdd.length; iii++) {
|
|
||||||
// console.log("compare '" + _name + "' ??? '" + this.bdd[iii]['name'] + "'");
|
|
||||||
if (this.bdd[iii].name.toLowerCase() === nameLower) {
|
|
||||||
out.push(this.bdd[iii]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public set(id: number, value: NodeData): void {
|
|
||||||
console.log(`[I] Set ${this.name} ${id}`);
|
|
||||||
for (let iii = 0; iii < this.bdd.length; iii++) {
|
|
||||||
console.log(` check: ${this.bdd[iii].id}`);
|
|
||||||
if (this.bdd[iii].id === id) {
|
|
||||||
console.log(` *** Set specific values: ${id} ${JSON.stringify(value, null, 2)}`);
|
|
||||||
this.bdd[iii] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public add(value: NodeData): void {
|
|
||||||
console.log(`[I] Set ${this.name}`);
|
|
||||||
this.bdd.push(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public delete(id: number): void {
|
|
||||||
console.log(`[I] delete ${this.name} ${id}`);
|
|
||||||
for (let iii = 0; iii < this.bdd.length; iii++) {
|
|
||||||
if (this.bdd[iii].id === id) {
|
|
||||||
this.bdd.splice(iii, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public find(listToken, values): NodeData[] {
|
|
||||||
let out = [];
|
|
||||||
for (let iii = 0; iii < this.bdd.length; iii++) {
|
|
||||||
let find = true;
|
|
||||||
for (let jjj = 0; jjj < listToken.length; jjj++) {
|
|
||||||
if (this.bdd[iii][listToken[jjj]] !== values[listToken[jjj]]) {
|
|
||||||
find = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (find === true) {
|
|
||||||
out.push(this.bdd[iii]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public count(select?: SelectModel[]) {
|
|
||||||
if (isNullOrUndefined(select)) {
|
|
||||||
return this.bdd.length;
|
|
||||||
}
|
|
||||||
let tmp = this.getSubList(this.bdd, select);
|
|
||||||
return tmp.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static existIn(value, listValues: number | string | boolean | number[] | string[]): boolean {
|
|
||||||
if (isArray(listValues)) {
|
|
||||||
for (let iii = 0; iii < listValues.length; iii++) {
|
|
||||||
if (value === listValues[iii]) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return value === listValues;
|
|
||||||
}
|
|
||||||
public static containsOneIn(
|
|
||||||
value: number | string | boolean | number[] | string[],
|
|
||||||
listValues: number | string | boolean | number[] | string[]
|
|
||||||
): boolean {
|
|
||||||
if (isArray(value)) {
|
|
||||||
for (let iii = 0; iii < value.length; iii++) {
|
|
||||||
if (this.existIn(value[iii], listValues) === true) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return this.existIn(value, listValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getSubList(values: NodeData[], select?: SelectModel[]): NodeData[] {
|
|
||||||
let out = [] as NodeData[];
|
|
||||||
for (let iiiElem = 0; iiiElem < values.length; iiiElem++) {
|
|
||||||
let find = true;
|
|
||||||
if (select.length === 0) {
|
|
||||||
find = false;
|
|
||||||
}
|
|
||||||
//console.log("Check : " + JSON.stringify(values[iiiElem], null, 2));
|
|
||||||
for (let iiiSelect = 0; iiiSelect < select.length; iiiSelect++) {
|
|
||||||
let control = select[iiiSelect];
|
|
||||||
let valueElement = values[iiiElem][control.key];
|
|
||||||
//console.log(" valueElement : " + JSON.stringify(valueElement, null, 2));
|
|
||||||
if (isArray(control.value)) {
|
|
||||||
if (control.check === TypeCheck.CONTAINS) {
|
|
||||||
//console.log("check contains ... " + valueElement + " contains one element in " + control.value);
|
|
||||||
if (DataInterface.containsOneIn(valueElement, control.value) === false) {
|
|
||||||
find = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (control.check === TypeCheck.EQUAL) {
|
|
||||||
//console.log("check Equals ... " + valueElement + " === " + control.value);
|
|
||||||
if (DataInterface.existIn(valueElement, control.value) === false) {
|
|
||||||
find = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (control.check === TypeCheck.NOT_EQUAL) {
|
|
||||||
if (DataInterface.existIn(valueElement, control.value) === false) {
|
|
||||||
find = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('[ERROR] Internal Server Error{ unknow comparing type ...');
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//console.log(" [" + control.key + "] = " + valueElement);
|
|
||||||
if (control.check === TypeCheck.CONTAINS) {
|
|
||||||
//console.log("check Equals ... " + valueElement + " === " + control.value + " #2");
|
|
||||||
if (DataInterface.containsOneIn(valueElement, control.value) === false) {
|
|
||||||
find = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (control.check === TypeCheck.EQUAL) {
|
|
||||||
if (valueElement !== control.value) {
|
|
||||||
find = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (control.check === TypeCheck.NOT_EQUAL) {
|
|
||||||
if (valueElement === control.value) {
|
|
||||||
find = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (control.check === TypeCheck.LESS) {
|
|
||||||
if (valueElement >= control.value) {
|
|
||||||
find = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (control.check === TypeCheck.LESS_EQUAL) {
|
|
||||||
if (valueElement > control.value) {
|
|
||||||
find = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (control.check === TypeCheck.GREATER) {
|
|
||||||
if (valueElement <= control.value) {
|
|
||||||
find = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (control.check === TypeCheck.GREATER_EQUAL) {
|
|
||||||
if (valueElement < control.value) {
|
|
||||||
find = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('[ERROR] Internal Server Error{ unknow comparing type ...');
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (find === true) {
|
|
||||||
// console.log(" ==> SELECTED");
|
|
||||||
out.push(values[iiiElem]);
|
|
||||||
} else {
|
|
||||||
// console.log(" ==> NOT SELECTED");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public orderBy(values: NodeData[], order: string[]): NodeData[] {
|
|
||||||
if (isNullOrUndefined(order)) {
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
if (order.length === 0) {
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
let valueOrder = order[0];
|
|
||||||
let out = [];
|
|
||||||
let outUnclassable = [];
|
|
||||||
for (let iii = 0; iii < values.length; iii++) {
|
|
||||||
if (values[iii][valueOrder] === undefined) {
|
|
||||||
outUnclassable.push(values[iii]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (values[iii][valueOrder] === null) {
|
|
||||||
outUnclassable.push(values[iii]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
out.push(values[iii]);
|
|
||||||
}
|
|
||||||
// console.log("order in list by : " + value_order);
|
|
||||||
// out = sorted(out, key=lambda x{ x[value_order])
|
|
||||||
if (valueOrder === 'name') {
|
|
||||||
out.sort((aaa, bbb) => {
|
|
||||||
const name1 = aaa[valueOrder].toLowerCase();
|
|
||||||
const name2 = bbb[valueOrder].toLowerCase();
|
|
||||||
if (name1 > name2) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (name1 < name2) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
out.sort((aaa, bbb) => {
|
|
||||||
if (aaa[valueOrder] > bbb[valueOrder]) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (aaa[valueOrder] < bbb[valueOrder]) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (order.length > 1) {
|
|
||||||
outUnclassable = this.orderBy(outUnclassable, order.slice(1));
|
|
||||||
}
|
|
||||||
for (let jjj = 0; jjj < outUnclassable.length; jjj++) {
|
|
||||||
out.push(outUnclassable[jjj]);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
import { getApplicationLocation } from './applPath';
|
|
||||||
import { DataInterface, TypeCheck } from './dataInterface';
|
|
||||||
import { sha512 } from './sha512';
|
|
||||||
import {
|
|
||||||
isArray,
|
|
||||||
isArrayOf,
|
|
||||||
isBoolean,
|
|
||||||
isNull,
|
|
||||||
isNullOrUndefined,
|
|
||||||
isNumber,
|
|
||||||
isNumberFinite,
|
|
||||||
isObject,
|
|
||||||
isOptionalOf,
|
|
||||||
isOptionalArrayOf,
|
|
||||||
isString,
|
|
||||||
isUndefined,
|
|
||||||
isArrayOfs,
|
|
||||||
isInArray,
|
|
||||||
isStringNullOrUndefined,
|
|
||||||
isNumeric,
|
|
||||||
} from './validator';
|
|
||||||
import { checkEmailValidity, checkLoginValidity, checkPasswordValidity, createLoginState, createPasswordState, getLoginType } from './validatorPasswordEmail';
|
|
||||||
|
|
||||||
export {
|
|
||||||
isNumber,
|
|
||||||
isNumberFinite,
|
|
||||||
isBoolean,
|
|
||||||
isString,
|
|
||||||
isArray,
|
|
||||||
isNull,
|
|
||||||
isUndefined,
|
|
||||||
isNullOrUndefined,
|
|
||||||
isObject,
|
|
||||||
isArrayOf,
|
|
||||||
isArrayOfs,
|
|
||||||
isOptionalOf,
|
|
||||||
isOptionalArrayOf,
|
|
||||||
isInArray,
|
|
||||||
isStringNullOrUndefined,
|
|
||||||
DataInterface,
|
|
||||||
TypeCheck,
|
|
||||||
getApplicationLocation,
|
|
||||||
sha512,
|
|
||||||
createPasswordState,
|
|
||||||
checkEmailValidity,
|
|
||||||
checkPasswordValidity,
|
|
||||||
checkLoginValidity,
|
|
||||||
getLoginType,
|
|
||||||
createLoginState,
|
|
||||||
isNumeric,
|
|
||||||
};
|
|
@ -1,3 +0,0 @@
|
|||||||
export function isMobileAgent() {
|
|
||||||
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
||||||
}
|
|
@ -1,342 +0,0 @@
|
|||||||
/*
|
|
||||||
* Secure Hash Algorithm (SHA512)
|
|
||||||
*/
|
|
||||||
|
|
||||||
export function sha512(str) {
|
|
||||||
function int64(msint_32, lsint_32) {
|
|
||||||
this.highOrder = msint_32;
|
|
||||||
this.lowOrder = lsint_32;
|
|
||||||
}
|
|
||||||
|
|
||||||
let H = [
|
|
||||||
new int64(0x6a09e667, 0xf3bcc908),
|
|
||||||
new int64(0xbb67ae85, 0x84caa73b),
|
|
||||||
new int64(0x3c6ef372, 0xfe94f82b),
|
|
||||||
new int64(0xa54ff53a, 0x5f1d36f1),
|
|
||||||
new int64(0x510e527f, 0xade682d1),
|
|
||||||
new int64(0x9b05688c, 0x2b3e6c1f),
|
|
||||||
new int64(0x1f83d9ab, 0xfb41bd6b),
|
|
||||||
new int64(0x5be0cd19, 0x137e2179),
|
|
||||||
];
|
|
||||||
|
|
||||||
let K = [
|
|
||||||
new int64(0x428a2f98, 0xd728ae22),
|
|
||||||
new int64(0x71374491, 0x23ef65cd),
|
|
||||||
new int64(0xb5c0fbcf, 0xec4d3b2f),
|
|
||||||
new int64(0xe9b5dba5, 0x8189dbbc),
|
|
||||||
new int64(0x3956c25b, 0xf348b538),
|
|
||||||
new int64(0x59f111f1, 0xb605d019),
|
|
||||||
new int64(0x923f82a4, 0xaf194f9b),
|
|
||||||
new int64(0xab1c5ed5, 0xda6d8118),
|
|
||||||
new int64(0xd807aa98, 0xa3030242),
|
|
||||||
new int64(0x12835b01, 0x45706fbe),
|
|
||||||
new int64(0x243185be, 0x4ee4b28c),
|
|
||||||
new int64(0x550c7dc3, 0xd5ffb4e2),
|
|
||||||
new int64(0x72be5d74, 0xf27b896f),
|
|
||||||
new int64(0x80deb1fe, 0x3b1696b1),
|
|
||||||
new int64(0x9bdc06a7, 0x25c71235),
|
|
||||||
new int64(0xc19bf174, 0xcf692694),
|
|
||||||
new int64(0xe49b69c1, 0x9ef14ad2),
|
|
||||||
new int64(0xefbe4786, 0x384f25e3),
|
|
||||||
new int64(0x0fc19dc6, 0x8b8cd5b5),
|
|
||||||
new int64(0x240ca1cc, 0x77ac9c65),
|
|
||||||
new int64(0x2de92c6f, 0x592b0275),
|
|
||||||
new int64(0x4a7484aa, 0x6ea6e483),
|
|
||||||
new int64(0x5cb0a9dc, 0xbd41fbd4),
|
|
||||||
new int64(0x76f988da, 0x831153b5),
|
|
||||||
new int64(0x983e5152, 0xee66dfab),
|
|
||||||
new int64(0xa831c66d, 0x2db43210),
|
|
||||||
new int64(0xb00327c8, 0x98fb213f),
|
|
||||||
new int64(0xbf597fc7, 0xbeef0ee4),
|
|
||||||
new int64(0xc6e00bf3, 0x3da88fc2),
|
|
||||||
new int64(0xd5a79147, 0x930aa725),
|
|
||||||
new int64(0x06ca6351, 0xe003826f),
|
|
||||||
new int64(0x14292967, 0x0a0e6e70),
|
|
||||||
new int64(0x27b70a85, 0x46d22ffc),
|
|
||||||
new int64(0x2e1b2138, 0x5c26c926),
|
|
||||||
new int64(0x4d2c6dfc, 0x5ac42aed),
|
|
||||||
new int64(0x53380d13, 0x9d95b3df),
|
|
||||||
new int64(0x650a7354, 0x8baf63de),
|
|
||||||
new int64(0x766a0abb, 0x3c77b2a8),
|
|
||||||
new int64(0x81c2c92e, 0x47edaee6),
|
|
||||||
new int64(0x92722c85, 0x1482353b),
|
|
||||||
new int64(0xa2bfe8a1, 0x4cf10364),
|
|
||||||
new int64(0xa81a664b, 0xbc423001),
|
|
||||||
new int64(0xc24b8b70, 0xd0f89791),
|
|
||||||
new int64(0xc76c51a3, 0x0654be30),
|
|
||||||
new int64(0xd192e819, 0xd6ef5218),
|
|
||||||
new int64(0xd6990624, 0x5565a910),
|
|
||||||
new int64(0xf40e3585, 0x5771202a),
|
|
||||||
new int64(0x106aa070, 0x32bbd1b8),
|
|
||||||
new int64(0x19a4c116, 0xb8d2d0c8),
|
|
||||||
new int64(0x1e376c08, 0x5141ab53),
|
|
||||||
new int64(0x2748774c, 0xdf8eeb99),
|
|
||||||
new int64(0x34b0bcb5, 0xe19b48a8),
|
|
||||||
new int64(0x391c0cb3, 0xc5c95a63),
|
|
||||||
new int64(0x4ed8aa4a, 0xe3418acb),
|
|
||||||
new int64(0x5b9cca4f, 0x7763e373),
|
|
||||||
new int64(0x682e6ff3, 0xd6b2b8a3),
|
|
||||||
new int64(0x748f82ee, 0x5defb2fc),
|
|
||||||
new int64(0x78a5636f, 0x43172f60),
|
|
||||||
new int64(0x84c87814, 0xa1f0ab72),
|
|
||||||
new int64(0x8cc70208, 0x1a6439ec),
|
|
||||||
new int64(0x90befffa, 0x23631e28),
|
|
||||||
new int64(0xa4506ceb, 0xde82bde9),
|
|
||||||
new int64(0xbef9a3f7, 0xb2c67915),
|
|
||||||
new int64(0xc67178f2, 0xe372532b),
|
|
||||||
new int64(0xca273ece, 0xea26619c),
|
|
||||||
new int64(0xd186b8c7, 0x21c0c207),
|
|
||||||
new int64(0xeada7dd6, 0xcde0eb1e),
|
|
||||||
new int64(0xf57d4f7f, 0xee6ed178),
|
|
||||||
new int64(0x06f067aa, 0x72176fba),
|
|
||||||
new int64(0x0a637dc5, 0xa2c898a6),
|
|
||||||
new int64(0x113f9804, 0xbef90dae),
|
|
||||||
new int64(0x1b710b35, 0x131c471b),
|
|
||||||
new int64(0x28db77f5, 0x23047d84),
|
|
||||||
new int64(0x32caab7b, 0x40c72493),
|
|
||||||
new int64(0x3c9ebe0a, 0x15c9bebc),
|
|
||||||
new int64(0x431d67c4, 0x9c100d4c),
|
|
||||||
new int64(0x4cc5d4be, 0xcb3e42b6),
|
|
||||||
new int64(0x597f299c, 0xfc657e2a),
|
|
||||||
new int64(0x5fcb6fab, 0x3ad6faec),
|
|
||||||
new int64(0x6c44198c, 0x4a475817),
|
|
||||||
];
|
|
||||||
|
|
||||||
let W = new Array(64);
|
|
||||||
let a, b, c, d, e, f, g, h, i, j;
|
|
||||||
let T1, T2;
|
|
||||||
let charsize = 8;
|
|
||||||
|
|
||||||
function utf8_encode(str) {
|
|
||||||
return unescape(encodeURIComponent(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
function str2binb(str) {
|
|
||||||
let bin = [];
|
|
||||||
let mask = (1 << charsize) - 1;
|
|
||||||
let len = str.length * charsize;
|
|
||||||
|
|
||||||
for (let i = 0; i < len; i += charsize) {
|
|
||||||
bin[i >> 5] |= (str.charCodeAt(i / charsize) & mask) << (32 - charsize - (i % 32));
|
|
||||||
}
|
|
||||||
|
|
||||||
return bin;
|
|
||||||
}
|
|
||||||
|
|
||||||
function binb2hex(binarray) {
|
|
||||||
let hex_tab = '0123456789abcdef';
|
|
||||||
let str = '';
|
|
||||||
let length = binarray.length * 4;
|
|
||||||
let srcByte;
|
|
||||||
|
|
||||||
for (let i = 0; i < length; i += 1) {
|
|
||||||
srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8);
|
|
||||||
str += hex_tab.charAt((srcByte >> 4) & 0xf) + hex_tab.charAt(srcByte & 0xf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
function safe_add_2(x, y) {
|
|
||||||
let lsw, msw, lowOrder, highOrder;
|
|
||||||
|
|
||||||
lsw = (x.lowOrder & 0xffff) + (y.lowOrder & 0xffff);
|
|
||||||
msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16);
|
|
||||||
lowOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
|
||||||
|
|
||||||
lsw = (x.highOrder & 0xffff) + (y.highOrder & 0xffff) + (msw >>> 16);
|
|
||||||
msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16);
|
|
||||||
highOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
|
||||||
|
|
||||||
return new int64(highOrder, lowOrder);
|
|
||||||
}
|
|
||||||
|
|
||||||
function safe_add_4(a, b, c, d) {
|
|
||||||
let lsw, msw, lowOrder, highOrder;
|
|
||||||
|
|
||||||
lsw = (a.lowOrder & 0xffff) + (b.lowOrder & 0xffff) + (c.lowOrder & 0xffff) + (d.lowOrder & 0xffff);
|
|
||||||
msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (lsw >>> 16);
|
|
||||||
lowOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
|
||||||
|
|
||||||
lsw =
|
|
||||||
(a.highOrder & 0xffff) +
|
|
||||||
(b.highOrder & 0xffff) +
|
|
||||||
(c.highOrder & 0xffff) +
|
|
||||||
(d.highOrder & 0xffff) +
|
|
||||||
(msw >>> 16);
|
|
||||||
msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + (c.highOrder >>> 16) + (d.highOrder >>> 16) + (lsw >>> 16);
|
|
||||||
highOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
|
||||||
|
|
||||||
return new int64(highOrder, lowOrder);
|
|
||||||
}
|
|
||||||
|
|
||||||
function safe_add_5(a, b, c, d, e) {
|
|
||||||
let lsw, msw, lowOrder, highOrder;
|
|
||||||
|
|
||||||
lsw =
|
|
||||||
(a.lowOrder & 0xffff) +
|
|
||||||
(b.lowOrder & 0xffff) +
|
|
||||||
(c.lowOrder & 0xffff) +
|
|
||||||
(d.lowOrder & 0xffff) +
|
|
||||||
(e.lowOrder & 0xffff);
|
|
||||||
msw =
|
|
||||||
(a.lowOrder >>> 16) +
|
|
||||||
(b.lowOrder >>> 16) +
|
|
||||||
(c.lowOrder >>> 16) +
|
|
||||||
(d.lowOrder >>> 16) +
|
|
||||||
(e.lowOrder >>> 16) +
|
|
||||||
(lsw >>> 16);
|
|
||||||
lowOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
|
||||||
|
|
||||||
lsw =
|
|
||||||
(a.highOrder & 0xffff) +
|
|
||||||
(b.highOrder & 0xffff) +
|
|
||||||
(c.highOrder & 0xffff) +
|
|
||||||
(d.highOrder & 0xffff) +
|
|
||||||
(e.highOrder & 0xffff) +
|
|
||||||
(msw >>> 16);
|
|
||||||
msw =
|
|
||||||
(a.highOrder >>> 16) +
|
|
||||||
(b.highOrder >>> 16) +
|
|
||||||
(c.highOrder >>> 16) +
|
|
||||||
(d.highOrder >>> 16) +
|
|
||||||
(e.highOrder >>> 16) +
|
|
||||||
(lsw >>> 16);
|
|
||||||
highOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
|
||||||
|
|
||||||
return new int64(highOrder, lowOrder);
|
|
||||||
}
|
|
||||||
|
|
||||||
function maj(x, y, z) {
|
|
||||||
return new int64(
|
|
||||||
(x.highOrder & y.highOrder) ^ (x.highOrder & z.highOrder) ^ (y.highOrder & z.highOrder),
|
|
||||||
(x.lowOrder & y.lowOrder) ^ (x.lowOrder & z.lowOrder) ^ (y.lowOrder & z.lowOrder)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ch(x, y, z) {
|
|
||||||
return new int64(
|
|
||||||
(x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder),
|
|
||||||
(x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function rotr(x, n) {
|
|
||||||
if (n <= 32) {
|
|
||||||
return new int64(
|
|
||||||
(x.highOrder >>> n) | (x.lowOrder << (32 - n)),
|
|
||||||
(x.lowOrder >>> n) | (x.highOrder << (32 - n))
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return new int64(
|
|
||||||
(x.lowOrder >>> n) | (x.highOrder << (32 - n)),
|
|
||||||
(x.highOrder >>> n) | (x.lowOrder << (32 - n))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sigma0(x) {
|
|
||||||
let rotr28 = rotr(x, 28);
|
|
||||||
let rotr34 = rotr(x, 34);
|
|
||||||
let rotr39 = rotr(x, 39);
|
|
||||||
|
|
||||||
return new int64(
|
|
||||||
rotr28.highOrder ^ rotr34.highOrder ^ rotr39.highOrder,
|
|
||||||
rotr28.lowOrder ^ rotr34.lowOrder ^ rotr39.lowOrder
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sigma1(x) {
|
|
||||||
let rotr14 = rotr(x, 14);
|
|
||||||
let rotr18 = rotr(x, 18);
|
|
||||||
let rotr41 = rotr(x, 41);
|
|
||||||
|
|
||||||
return new int64(
|
|
||||||
rotr14.highOrder ^ rotr18.highOrder ^ rotr41.highOrder,
|
|
||||||
rotr14.lowOrder ^ rotr18.lowOrder ^ rotr41.lowOrder
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gamma0(x) {
|
|
||||||
let rotr1 = rotr(x, 1),
|
|
||||||
rotr8 = rotr(x, 8),
|
|
||||||
shr7 = shr(x, 7);
|
|
||||||
|
|
||||||
return new int64(
|
|
||||||
rotr1.highOrder ^ rotr8.highOrder ^ shr7.highOrder,
|
|
||||||
rotr1.lowOrder ^ rotr8.lowOrder ^ shr7.lowOrder
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gamma1(x) {
|
|
||||||
let rotr19 = rotr(x, 19);
|
|
||||||
let rotr61 = rotr(x, 61);
|
|
||||||
let shr6 = shr(x, 6);
|
|
||||||
|
|
||||||
return new int64(
|
|
||||||
rotr19.highOrder ^ rotr61.highOrder ^ shr6.highOrder,
|
|
||||||
rotr19.lowOrder ^ rotr61.lowOrder ^ shr6.lowOrder
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function shr(x, n) {
|
|
||||||
if (n <= 32) {
|
|
||||||
return new int64(x.highOrder >>> n, (x.lowOrder >>> n) | (x.highOrder << (32 - n)));
|
|
||||||
} else {
|
|
||||||
return new int64(0, x.highOrder << (32 - n));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
str = utf8_encode(str);
|
|
||||||
let strlen = str.length * charsize;
|
|
||||||
str = str2binb(str);
|
|
||||||
|
|
||||||
str[strlen >> 5] |= 0x80 << (24 - (strlen % 32));
|
|
||||||
str[(((strlen + 128) >> 10) << 5) + 31] = strlen;
|
|
||||||
|
|
||||||
for (let i = 0; i < str.length; i += 32) {
|
|
||||||
a = H[0];
|
|
||||||
b = H[1];
|
|
||||||
c = H[2];
|
|
||||||
d = H[3];
|
|
||||||
e = H[4];
|
|
||||||
f = H[5];
|
|
||||||
g = H[6];
|
|
||||||
h = H[7];
|
|
||||||
|
|
||||||
for (let j = 0; j < 80; j++) {
|
|
||||||
if (j < 16) {
|
|
||||||
W[j] = new int64(str[j * 2 + i], str[j * 2 + i + 1]);
|
|
||||||
} else {
|
|
||||||
W[j] = safe_add_4(gamma1(W[j - 2]), W[j - 7], gamma0(W[j - 15]), W[j - 16]);
|
|
||||||
}
|
|
||||||
|
|
||||||
T1 = safe_add_5(h, sigma1(e), ch(e, f, g), K[j], W[j]);
|
|
||||||
T2 = safe_add_2(sigma0(a), maj(a, b, c));
|
|
||||||
h = g;
|
|
||||||
g = f;
|
|
||||||
f = e;
|
|
||||||
e = safe_add_2(d, T1);
|
|
||||||
d = c;
|
|
||||||
c = b;
|
|
||||||
b = a;
|
|
||||||
a = safe_add_2(T1, T2);
|
|
||||||
}
|
|
||||||
|
|
||||||
H[0] = safe_add_2(a, H[0]);
|
|
||||||
H[1] = safe_add_2(b, H[1]);
|
|
||||||
H[2] = safe_add_2(c, H[2]);
|
|
||||||
H[3] = safe_add_2(d, H[3]);
|
|
||||||
H[4] = safe_add_2(e, H[4]);
|
|
||||||
H[5] = safe_add_2(f, H[5]);
|
|
||||||
H[6] = safe_add_2(g, H[6]);
|
|
||||||
H[7] = safe_add_2(h, H[7]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let binarray = [];
|
|
||||||
for (let i = 0; i < H.length; i++) {
|
|
||||||
binarray.push(H[i].highOrder);
|
|
||||||
binarray.push(H[i].lowOrder);
|
|
||||||
}
|
|
||||||
return binb2hex(binarray);
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
|
|
||||||
export function isNumeric(val: string): boolean {
|
|
||||||
return !isNaN(Number(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isNumber(data: any): data is number {
|
|
||||||
return typeof data === 'number';
|
|
||||||
}
|
|
||||||
export function isNumberFinite(data: any): data is number {
|
|
||||||
return isNumber(data) && isFinite(data);
|
|
||||||
}
|
|
||||||
export function isBoolean(data: any): data is boolean {
|
|
||||||
return typeof data === 'boolean';
|
|
||||||
}
|
|
||||||
export function isString(data: any): data is string {
|
|
||||||
return typeof data === 'string';
|
|
||||||
}
|
|
||||||
export function isArray(data: any): data is any[] {
|
|
||||||
return Array.isArray(data);
|
|
||||||
}
|
|
||||||
export function isNull(data: any): data is null {
|
|
||||||
return data === null;
|
|
||||||
}
|
|
||||||
export function isUndefined(data: any): data is undefined {
|
|
||||||
return data === undefined;
|
|
||||||
}
|
|
||||||
export function isNullOrUndefined(data: any): data is undefined | null {
|
|
||||||
return data === undefined || data === null;
|
|
||||||
}
|
|
||||||
export function isStringNullOrUndefined(data: any): data is undefined | null {
|
|
||||||
return data === 'undefined' || data === 'null' || data === '';
|
|
||||||
}
|
|
||||||
export function isObject(data: any): data is any {
|
|
||||||
return !isNullOrUndefined(data) && typeof data === 'object' && !isArray(data);
|
|
||||||
}
|
|
||||||
export function isInArray(data: any, listElment: any[]): boolean {
|
|
||||||
for (let iii = 0; iii < listElment.length; iii++) {
|
|
||||||
if (listElment[iii] === data) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isArrayOf<TYPE>(
|
|
||||||
data: any,
|
|
||||||
typeChecker: (subData: any) => subData is TYPE,
|
|
||||||
length?: number
|
|
||||||
): data is TYPE[] {
|
|
||||||
if (!isArray(data)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!data.every(typeChecker)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isUndefined(length) && data.length != length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
export function isArrayOfs<TYPE, TYPE2, TYPE3>(
|
|
||||||
data: any,
|
|
||||||
typeChecker: (subData: any) => subData is TYPE,
|
|
||||||
typeChecker2?: (subData: any) => subData is TYPE2,
|
|
||||||
typeChecker3?: (subData: any) => subData is TYPE3
|
|
||||||
): data is (TYPE | TYPE2 | TYPE3)[] {
|
|
||||||
if (!isArray(data)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (let iii = 0; iii < data.length; iii++) {
|
|
||||||
let elem = data[iii];
|
|
||||||
if (typeChecker(elem)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (typeChecker2 != undefined && typeChecker2(elem)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (typeChecker3 != undefined && typeChecker3(elem)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isOptionalOf<TYPE>(
|
|
||||||
data: any,
|
|
||||||
typeChecker: (subData: any) => subData is TYPE
|
|
||||||
): data is TYPE | undefined {
|
|
||||||
return isUndefined(data) || typeChecker(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isOptionalArrayOf<TYPE>(
|
|
||||||
data: any,
|
|
||||||
typeChecker: (subData: any) => subData is TYPE
|
|
||||||
): data is TYPE[] | undefined {
|
|
||||||
return isUndefined(data) || isArrayOf(data, typeChecker);
|
|
||||||
}
|
|
@ -1,146 +0,0 @@
|
|||||||
import { isNullOrUndefined } from "./validator";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the specific regexp on a value
|
|
||||||
* @param value Value to test.
|
|
||||||
* @param expression Regexp epression to test on the value
|
|
||||||
* @returns true if the regexp is validate, false otherwise
|
|
||||||
*/
|
|
||||||
export function testRegExp(value: string, expression: string): boolean {
|
|
||||||
let regexCheck = new RegExp(expression);
|
|
||||||
if (regexCheck.test(value)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Check the value is well formated to be a login.
|
|
||||||
* @param value login value to check.
|
|
||||||
* @returns true if it is compatible with a login, false otherwise.
|
|
||||||
*/
|
|
||||||
export function checkLoginValidity(value: string): boolean {
|
|
||||||
return testRegExp(value, '^[a-zA-Z0-9_\\.-]+$');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Check the value is well formated to be an e-mail.
|
|
||||||
* @param value email value to check.
|
|
||||||
* @returns true if it is an email, false otherwise.
|
|
||||||
*/
|
|
||||||
export function checkEmailValidity(value: string): boolean {
|
|
||||||
return testRegExp(value, '^[a-zA-Z0-9_\\.@-]+@[a-zA-Z0-9_\\.-]+\\.[a-zA-Z]+$');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Check the value is well formated to be an Password.
|
|
||||||
* @param value password value to check.
|
|
||||||
* @returns true if it is compatible with a password, false otherwise.
|
|
||||||
*/
|
|
||||||
export function checkPasswordValidity(value: string): boolean {
|
|
||||||
return testRegExp(value, '^[a-zA-Z0-9_\\.@ %:;,=}{\\?\\!\\*\\+\\(\\)\\[\\]\\|&#%~/\\\\\\<\\>\\-£€]+$');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Check if the value contains one alphabetical lower case character
|
|
||||||
* @param value String value to check.
|
|
||||||
* @returns true if it contains one lower case character, false otherwise.
|
|
||||||
*/
|
|
||||||
export function check1LowerChar(value: string): boolean {
|
|
||||||
return testRegExp(value, '(.*[a-z].*)');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Check if the value contains one alphabetical upper case character
|
|
||||||
* @param value String value to check.
|
|
||||||
* @returns true if it contains one upper case character, false otherwise.
|
|
||||||
*/
|
|
||||||
export function check1UpperChar(value: string): boolean {
|
|
||||||
return testRegExp(value, '(.*[A-Z].*)');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Check if the value contains one numerical character
|
|
||||||
* @param value String value to check.
|
|
||||||
* @returns true if it contains minimum of one digit character, false otherwise.
|
|
||||||
*/
|
|
||||||
export function check1DigitChar(value: string): boolean {
|
|
||||||
return testRegExp(value, '(.*[0-9].*)');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Check if the value contains one special character
|
|
||||||
* @param value String value to check.
|
|
||||||
* @returns true if it contains minimum of one special character, false otherwise.
|
|
||||||
*/
|
|
||||||
export function check1SpecialChar(value: string): boolean {
|
|
||||||
return testRegExp(value, '(.*[_\\.@ %:;,=}{\\?\\!\\*\\+\\(\\)\\[\\]\\|&#%~/\\\\\\<\\>\\-£€].*)');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Creata a pasword state of a password. it return a readable string that explain why the password is wrong.
|
|
||||||
* if check minimum size, at lease one digit, one upper case, one lower case and one special character.
|
|
||||||
* @param value Pasword value to check.
|
|
||||||
* @returns true if it is compatcable, false if the value is undefined or empty,or the descriptive error string (English).
|
|
||||||
*/
|
|
||||||
export function createPasswordState(value: string): boolean|string {
|
|
||||||
let ret = createPasswordStateSimple(value);
|
|
||||||
if (ret === true) {
|
|
||||||
if (check1LowerChar(value) === false) {
|
|
||||||
return 'Not valid: missing 1 lower case character [a-z]';
|
|
||||||
}
|
|
||||||
if (check1UpperChar(value) === false) {
|
|
||||||
return 'Not valid: missing 1 upper case character [A-Z]';
|
|
||||||
}
|
|
||||||
if (check1DigitChar(value) === false) {
|
|
||||||
return 'Not valid: missing 1 digit character [0-9]';
|
|
||||||
}
|
|
||||||
if (check1SpecialChar(value) === false) {
|
|
||||||
return 'Not valid: missing 1 special character: _-:;.,?!*+=}{([|)]% @&~#/\\<>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}/**
|
|
||||||
* Creata a pasword state of a password. it return a readable string that explain why the password is wrong.
|
|
||||||
* It does not check if the email have specific less one char, it is dangerous for login interface.
|
|
||||||
* @param value Pasword value to check.
|
|
||||||
* @returns true if it is compatcable, false if the value is undefined or empty,or the descriptive error string (English).
|
|
||||||
*/
|
|
||||||
export function createPasswordStateSimple(value: string): boolean|string {
|
|
||||||
if (isNullOrUndefined(value) || value === '') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (value.length < 6) {
|
|
||||||
return 'Need 6 characters';
|
|
||||||
}
|
|
||||||
if (checkPasswordValidity(value) === false) {
|
|
||||||
return 'Not valid: characters, numbers and "_-:;.,?!*+=}{([|)]% @&~#/\\<>"';
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creata a login/email state. It return a readable string that explain why the login/email is wrong.
|
|
||||||
* if check minimum size, or not an email.
|
|
||||||
* @param value email/login value to check.
|
|
||||||
* @returns true if it is compatcable, false if the value is undefined or empty,or the descriptive error string (English).
|
|
||||||
*/
|
|
||||||
export function createLoginState(value: string): boolean|string {
|
|
||||||
if (isNullOrUndefined(value) || value === '') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (value.length < 6) {
|
|
||||||
return 'Need 6 characters';
|
|
||||||
}
|
|
||||||
if (checkLoginValidity(value) === true) {
|
|
||||||
return true;
|
|
||||||
} else if (checkEmailValidity(value) === true) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return 'Not valid: characters, numbers, "_-." and email format: you@example.com';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getLoginType(value: string): string {
|
|
||||||
if (isNullOrUndefined(value) || value.length <6 ) {
|
|
||||||
return 'Username/E-mail';
|
|
||||||
}
|
|
||||||
if (checkLoginValidity(value) === true) {
|
|
||||||
return 'Username';
|
|
||||||
} else if (checkEmailValidity(value) === true) {
|
|
||||||
return 'E-mail';
|
|
||||||
}
|
|
||||||
return 'Username/E-mail';
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user