[DEV] continue integration Setting does not work...

This commit is contained in:
Edouard DUPIN 2023-02-06 00:40:31 +01:00
parent a2e1f5b24d
commit 1e5f3541bf
15 changed files with 456 additions and 151 deletions

View File

@ -42,7 +42,7 @@ import {
UserService,
} from 'common/service';
import { CommonModule } from '@angular/common';
import { ErrorComponent, PopInComponent, SpinerComponent, TopMenuComponent, UploadFileComponent, PasswordEntryComponent, EntryComponent, AsyncActionStatusComponent, ErrorMessageStateComponent, CheckboxComponent, BurgerPropertyComponent } from 'common/component';
import { ErrorComponent, PopInComponent, SpinerComponent, TopMenuComponent, UploadFileComponent, PasswordEntryComponent, EntryComponent, AsyncActionStatusComponent, ErrorMessageStateComponent, CheckboxComponent, BurgerPropertyComponent, EntryValidatorComponent, RenderSettingsComponent } from 'common/component';
import { ForbiddenScene } from 'common/scene';
import { AdminUserService, ApplicationService, ApplicationTokenService, SettingsService } from 'app/service';
import { PopInUploadProgress, PopInDeleteConfirm } from 'common/popin';
@ -55,11 +55,13 @@ import { PopInUploadProgress, PopInDeleteConfirm } from 'common/popin';
ErrorComponent,
PasswordEntryComponent,
EntryComponent,
EntryValidatorComponent,
SpinerComponent,
AsyncActionStatusComponent,
ErrorMessageStateComponent,
CheckboxComponent,
BurgerPropertyComponent,
RenderSettingsComponent,
PopInComponent,
PopInUploadProgress,

View File

@ -109,21 +109,40 @@
</table>
</body>
<footer>
<app-entry
[value]="tokenName"
placeholder="Enter the token name / decription"
(changeValue)="checkTokenName($event)"></app-entry>
<app-entry
[value]="tokenTTL"
placeholder="Enter the Time To Lead"
(changeValue)="checkTokenTTL($event)"></app-entry>
<button
class="button login color-button-validate color-shadow-black"
id="create-button"
(click)="createToken()"
type="submit">
+ Create new Token
</button>
<table>
<tr>
<td width="25%">Name/Descriptiion token:</td>
<td>
<app-entry-validator
[value]="tokenName"
placeholder="Enter the token name / decription"
(checker)="checkTokenName($event)"
(changeValue)="newTokenName($event)"></app-entry-validator>
</td>
</tr>
<tr>
<td>Validity time (in day)</td>
<td>
<app-entry-validator
[value]="tokenTTL"
placeholder="Enter the Time To Lead (in day)"
(checker)="checkTokenTTL($event)"
(changeValue)="newTokenTTL($event)"></app-entry-validator>
</td>
</tr>
<tr>
<td></td>
<td>
<button
class="button login color-button-validate color-shadow-black"
id="create-button"
(click)="createToken()"
type="submit">
+ Create new Token
</button>
</td>
</tr>
</table>
</footer>
</burger-property>
</div>

View File

@ -4,11 +4,12 @@
* @license PROPRIETARY (see license file)
*/
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ApplicationService, ApplicationModel, ApplicationTokenService } from 'app/service';
import { ApplicationTokenModel } from 'app/service/application-token';
import { AsyncActionState } from 'common/component';
import { CheckerParameter } from 'common/component/entry-validator/entry-validator';
import { NotificationService, PopInService } from 'common/service';
import { isNumeric } from 'common/utils';
@ -185,6 +186,7 @@ export class ApplicationEditScene implements OnInit {
.then((response: ApplicationTokenModel) => {
console.log(`??? get fullllllll response: ${JSON.stringify(response, null, 4)}`);
self.tokens.push(response);
response.token = `"${response.id}:${response.token}"`
self.cdr.detectChanges();
})
.catch((error: any) => {
@ -225,15 +227,65 @@ export class ApplicationEditScene implements OnInit {
this.confirmDeleteApplicationToken = undefined;
}
}
createFrom = [
{
title: "Name/Description token",
placeholder: "Enter the token name / decription",
value: "",
type: "INPUT",
checker: this.checkTokenName,
},
{
title: "Validity time (in day)",
placeholder: "Enter the Time To Lead (in day)",
value: "",
checker: this.checkTokenName,
},
];
tokenName: string = undefined;
tokenTTL: number = undefined;
checkTokenName(newValue: string) {
tokenCreateErrorCount: number = 2;
newTokenName(newValue: string) {
this.tokenName = newValue;
}
checkTokenTTL(newValue: string) {
checkTokenName(chekParam: CheckerParameter): void {
if (chekParam.value.length < 3) {
chekParam.result("Must have 3 chars");
return;
}
chekParam.result(true);
}
newTokenTTL(newValue: string) {
if (isNumeric(newValue)) {
this.tokenTTL = Number(newValue);
}
}
checkTokenTTL(chekParam: CheckerParameter): void {
if (!isNumeric(chekParam.value)) {
chekParam.result("Must be a number");
return;
}
if (chekParam.value.length<1) {
chekParam.result("Minimum one day");
return;
}
let value = Number(chekParam.value);
if (value<0) {
chekParam.result("Value must be > 0");
return;
}
if (value===0) {
chekParam.result("This have no need to create token");
return;
}
chekParam.result(true);
}
}

View File

@ -23,7 +23,7 @@
placeholder="Enter new password"
[hasError]="password1State !== true"
(changeValue)="checkPassword($event)"></app-password-entry>
<app-error-message-state [value]="password1State"></app-error-message-state>
<app-error-message-state [value]="password1State"></app-error-message-state>
<!-- New password section (verify) -->
<label for="password2"><b>New password (2<sup>nd</sup> time)</b></label>
@ -32,7 +32,7 @@
placeholder="Enter new password (verify)"
[hasError]="password2State !== true"
(changeValue)="checkPassword2($event)"></app-password-entry>
<app-error-message-state [value]="password2State"></app-error-message-state>
<app-error-message-state [value]="password2State"></app-error-message-state>
</div>
<div class="container" *ngIf="updateState==='filling'">
<button class="button cancel color-button-cancel color-shadow-black" (click)="onCancel()">Cancel</button>

View File

@ -1,47 +1,20 @@
<div class="generic-page">
<div class="title">{{menu.title}}</div>
<div class="title">Global SSO Management</div>
<div class="fill-all">
<burger-property *ngFor="let data of menu.value">
<burger-property *ngFor="let data of menu">
<name>{{data.title}}</name>
<description>{{data.description}}</description>
<body>
<div *ngFor="let elem of data.value" class="settings-elements">
<div *ngIf="elem.type === 'LINE'">
<div class="elem-hr"></div>
</div>
<div *ngIf="elem.type === 'BOOLEAN'">
<div class="elem-checkbox">
<input
type="checkbox"
[checked]="elem.value"
(change)="changeValueElement($event.target.checked, elem, data)" />
{{elem.title}}
</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">
<input
type="text"
[value]="elem.value"
(input)="changeValueElement($event.target.value, elem, data)" />
</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" />
</div>
</div>
</div>
<app-render-settings
[values]="data.values"
(deltaValues)="onDeltaValues($event, data)"
(changeState)="onState($event, data)"
></app-render-settings>
</body>
<footer>
<button
class="button login color-button-validate color-shadow-black"
[disabled]="!data.newValue"
[disabled]="data.state !== 0"
(click)="onUpdate(data)"
type="submit">
Update ...

View File

@ -1,36 +1,4 @@
.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%;
}
}
}
.title {
//background-color: green;
font-size: 45px;

View File

@ -4,9 +4,10 @@
* @license PROPRIETARY (see license file)
*/
import { Component, OnInit } from '@angular/core';
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SettingsService } from 'app/service';
import { isSettingsItem, SettingsItem, SettingType } from 'common/component/render-settings/render-settings';
import {
isArrayOf,
isBoolean,
@ -19,75 +20,40 @@ import {
isString,
isUndefined,
} from 'common/utils';
export enum SettingType {
TITLE = 'TITLE',
GROUP = 'GROUP',
LINE = 'LINE',
BOOLEAN = 'BOOLEAN',
STRING = 'STRING',
PASSWORD = 'PASSWORD',
}
export function isSettingType(data: any): data is SettingType {
return isInArray(data, ['TITLE', 'GROUP', 'LINE', 'BOOLEAN', 'STRING', 'PASSWORD']);
}
export interface SettingsItem {
// Type of the menu Node
type: SettingType;
export interface SettingsItem222 {
// Displayed Title
title?: string;
// Description of the parameter
description?: string;
// Image to dsplay that describe the parameter
image?: string;
// If true the parameter is applied directly to the backend
directApply?: boolean;
// Parameter key to SET/GET
key?: string;
// Parameter key to SET/GET or the sub-menu
value?: SettingsItem[] | boolean | string | Number;
// whendata is change the value is set here:
newValue?: boolean | string | Number;
values?: SettingsItem[];
// Local new Parameters:
newValues?: object;
// local state: if undefined => no change, otherwise the number of wrong values.
state?: number;
}
export function isSettingsItem(data: any): data is SettingsItem {
export function isSettingsItem222(data: any): data is SettingsItem222 {
if (isNullOrUndefined(data)) {
return false;
}
if (!isObject(data)) {
return false;
}
if (!isSettingType(data.type)) {
return false;
}
if (!isOptionalOf(data.title, isString)) {
return false;
}
if (!isOptionalOf(data.description, isString)) {
return false;
}
if (!isOptionalOf(data.image, isString)) {
return false;
}
if (!isOptionalOf(data.directApply, isBoolean)) {
return false;
}
if (!isOptionalOf(data.key, isString)) {
return false;
}
if (
!isOptionalOf(data.value, isBoolean) &&
!isOptionalOf(data.value, isString) &&
!isOptionalOf(data.value, isNumber) &&
!isOptionalArrayOf(data.value, isSettingsItem)
) {
return false;
}
if (
!isOptionalOf(data.newValue, isBoolean) &&
!isOptionalOf(data.newValue, isString) &&
!isOptionalOf(data.newValue, isNumber)
) {
if (!isOptionalArrayOf(data.values, isSettingsItem)) {
return false;
}
return true;
@ -101,17 +67,15 @@ export function isSettingsItem(data: any): data is SettingsItem {
export class SettingsScene implements OnInit {
page = '';
constructor(private settingService: SettingsService) {}
menu: SettingsItem = {
type: SettingType.TITLE,
title: 'Global SSO Management',
value: [
constructor(
private settingService: SettingsService,
private cdr: ChangeDetectorRef,
) {}
menu: SettingsItem222[] = [
{
type: SettingType.GROUP,
title: 'Authentication:',
description: 'Manage the right of access to the web-services',
newValue: false,
value: [
values: [
{
type: SettingType.BOOLEAN,
title: 'Enable Sign-in',
@ -145,8 +109,8 @@ export class SettingsScene implements OnInit {
},
],
},
],
};
];
ngOnInit() {
this.settingService
.gets(['SIGN_IN_ENABLE', 'SIGN_UP_ENABLE', 'SIGN_UP_FILTER', 'EMAIL_VALIDATION_REQUIRED'])
@ -157,9 +121,20 @@ export class SettingsScene implements OnInit {
console.log(`??? get ERROR response: ${JSON.stringify(error, null, 4)}`);
});
}
onSelectType(_event: any, _idSelected: number): void {}
changeValueElement(newValue: string, elem: SettingsItem, parent: SettingsItem): void {
onState(value: number, elem: SettingsItem222) {
console.log(`changeState : ${JSON.stringify(value, null, 2)}`);
elem.state = value;
// we do not change the main ref ==> notify angular that something have change and need to be re-render???
this.cdr.detectChanges();
}
onDeltaValues(value: any, elem: SettingsItem222) {
console.log(`onDeltaValues : ${JSON.stringify(value, null, 2)}`);
elem.newValues = value;
// we do not change the main ref ==> notify angular that something have change and need to be re-render???
this.cdr.detectChanges();
}
/*
changeValueElement(newValue: string, elem: SettingsItem222, parent: SettingsItem222): void {
if (elem.value === newValue) {
elem.newValue = undefined;
this.updateSendNeeded(parent);
@ -168,11 +143,11 @@ export class SettingsScene implements OnInit {
elem.newValue = newValue;
this.updateSendNeeded(parent);
}
updateSendNeeded(parent: SettingsItem) {
updateSendNeeded(parent: SettingsItem222) {
if (isNullOrUndefined(parent.value)) {
return;
}
if (!isArrayOf(parent.value, isSettingsItem)) {
if (!isArrayOf(parent.value, isSettingsItem222)) {
console.log('Error Can not convert type setting menu');
return;
}
@ -185,5 +160,15 @@ export class SettingsScene implements OnInit {
}
parent.newValue = needUpdate;
}
onUpdate(parent: SettingsItem) {}
onUpdate(parent: SettingsItem222) {}
*/
onUpdate(elem: SettingsItem222) {
this.settingService.sets(elem.newValues)
.then((result: object) => {
//multipleResponse.add(key, result);
})
.catch((error: any) => {
//multipleResponse.fail(key, error);
});
}
}

View File

@ -0,0 +1,8 @@
<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>

View File

@ -0,0 +1,9 @@
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;
}

View File

@ -0,0 +1,59 @@
/** @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,
});
}
}

View File

@ -1 +1 @@
<div class="error color-shadow-black" *ngIf="value !== true && value !== false">{{value}}</div>
<div class="error color-shadow-black" *ngIf="value !== true && value !== false && value !== undefined">{{value}}</div>

View File

@ -1,13 +1,15 @@
import { AsyncActionState, AsyncActionStatusComponent } from './async-action-status/async-status-component';
import { BurgerPropertyComponent } from './burger-property/burger-property';
import { CheckboxComponent } from './checkbox/checkbox';
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 { 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, CheckboxComponent, ErrorMessageStateComponent, AsyncActionState, AsyncActionStatusComponent, PopInComponent, TopMenuComponent, UploadFileComponent, ErrorComponent, SpinerComponent, PasswordEntryComponent, EntryComponent };
export { BurgerPropertyComponent, CheckboxComponent, RenderSettingsComponent, ErrorMessageStateComponent, AsyncActionState, AsyncActionStatusComponent, EntryValidatorComponent, PopInComponent, TopMenuComponent, UploadFileComponent, ErrorComponent, SpinerComponent, PasswordEntryComponent, EntryComponent };

View File

@ -0,0 +1,39 @@
<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>

View File

@ -0,0 +1,32 @@
.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%;
}
}
}

View File

@ -0,0 +1,157 @@
/** @file
* @author Edouard DUPIN
* @copyright 2018, Edouard DUPIN, all right reserved
* @license PROPRIETARY (see license file)
*/
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { isBoolean, isInArray, isNullOrUndefined, isNumber, isObject, isOptionalArrayOf, isOptionalOf, isString, isUndefined } from 'common/utils';
export type ReturnFunction = (a: boolean|string) => void;
// if string ==> the error, if undefined, it is OK
export type CheckerParameter = (value: string) => string | undefined;
export enum SettingType {
LINE = 'LINE',
BOOLEAN = 'BOOLEAN',
STRING = 'STRING',
PASSWORD = 'PASSWORD',
}
export function isSettingType(data: any): data is SettingType {
return isInArray(data, ['LINE', '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;
}
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 (!isUndefined(data.state)) {
return false;
}
return true;
}
@Component({
selector: 'app-render-settings',
templateUrl: 'render-settings.html',
styleUrls: ['render-settings.less'],
})
export class RenderSettingsComponent implements OnInit {
/// 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();
constructor(
) {
}
ngOnInit(): void {
//if (value)
}
createOutputValues(): any {
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 (value.state !== undefined) {
out++;
}
});
return out;
}
checkParameter(newValue: string, item: SettingsItem): void {
if (!isNullOrUndefined(item.checker)) {
item.state = item.checker(newValue);
}
if (item.value === newValue) {
item.newValue = undefined;
} else {
item.newValue = newValue;
}
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);
} else {
this.changeState.emit(nbError);
}
if (nbError === 0 && nbValuesChanges !== 0) {
this.deltaValues.emit(outValue);
}
}
}