Compare commits

..

No commits in common. "main" and "v0.2.0" have entirely different histories.
main ... v0.2.0

18 changed files with 1192 additions and 2044 deletions

View File

@ -1,16 +0,0 @@
#!/bin/bash
version_file="version.txt"
new_version=$(cat $version_file)
sed -i "s|\"version\":.*\".*\"|\"version\":\"$new_version\"|" package.json
if grep -q "dev" "$version_file"; then
# update all dependency
pnpm install
pnpm run update_packages
else
# in case of release ==> can not do it automatically ...
echo not implemented
fi

View File

@ -1,6 +1,6 @@
{ {
"name": "@kangaroo-and-rabbit/kar-cw", "name": "@kangaroo-and-rabbit/kar-cw",
"version": "0.4.1", "version": "0.2.0",
"sideEffects": false, "sideEffects": false,
"scripts": { "scripts": {
"dev": "ng build kar-cw --watch --configuration development", "dev": "ng build kar-cw --watch --configuration development",
@ -10,26 +10,26 @@
"lint": "ng lint", "lint": "ng lint",
"style": "prettier --write .", "style": "prettier --write .",
"update_packages": "ncu --upgrade", "update_packages": "ncu --upgrade",
"install_dependency": "pnpm install --force" "install_dependency": "pnpm install"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/common": "^18.0.0", "@angular/common": "^17.3.3",
"@angular/compiler": "^18.0.0", "@angular/compiler": "^17.3.3",
"@angular/core": "^18.0.0", "@angular/core": "^17.3.3",
"@angular/forms": "^18.0.0", "@angular/forms": "^17.3.3",
"@angular/platform-browser": "^18.0.0", "@angular/platform-browser": "^17.3.3",
"@angular/platform-browser-dynamic": "^18.0.0", "@angular/platform-browser-dynamic": "^17.3.3",
"@angular/router": "^18.0.0", "@angular/router": "^17.3.3",
"rxjs": "~7.8.1", "rxjs": "~7.8.0",
"zone.js": "~0.14.5" "zone.js": "~0.14.3"
}, },
"dependencies": { "dependencies": {
"tslib": "^2.6.2" "tslib": "^2.6.2"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^18.0.1", "@angular-devkit/build-angular": "^17.3.3",
"@angular/cli": "^18.0.1", "@angular/cli": "^17.3.3",
"@angular/compiler-cli": "^18.0.0", "@angular/compiler-cli": "^17.3.3",
"@types/jasmine": "~5.1.4", "@types/jasmine": "~5.1.4",
"jasmine-core": "~5.1.2", "jasmine-core": "~5.1.2",
"karma": "~6.4.3", "karma": "~6.4.3",
@ -37,9 +37,9 @@
"karma-coverage": "~2.2.1", "karma-coverage": "~2.2.1",
"karma-jasmine": "~5.1.0", "karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0", "karma-jasmine-html-reporter": "~2.1.0",
"ng-packagr": "^18.0.0", "ng-packagr": "^17.3.3",
"typescript": "~5.4.5", "typescript": "~5.4.4",
"npm-check-updates": "^16.14.20" "npm-check-updates": "^16.14.18"
}, },
"maintainers": [ "maintainers": [
{ {

2922
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@ export class AsyncActionStatusComponent {
@Input() value: AsyncActionState = AsyncActionState.IDLE; @Input() value: AsyncActionState = AsyncActionState.IDLE;
public getImage(): string { public getImage(): string {
switch (this.value) { switch(this.value) {
case AsyncActionState.IDLE: case AsyncActionState.IDLE:
return ''; return '';
case AsyncActionState.LOADING: case AsyncActionState.LOADING:

View File

@ -1,7 +1,6 @@
<div class="elem-checkbox"> <div class="elem-checkbox">
<input <input
type="checkbox" type="checkbox"
[disabled]="isDisable"
[checked]="value" [checked]="value"
(change)="onChange($event.target.checked)" /> (change)="onChange($event.target.checked)" />
{{comment}} {{comment}}

View File

@ -11,20 +11,18 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
styleUrls: ['checkbox.less'], styleUrls: ['checkbox.less'],
}) })
export class CheckboxComponent { export class CheckboxComponent {
/// Checkbox value
@Input() isDisable: boolean = false;
/// Checkbox value /// Checkbox value
@Input() value: boolean = false; @Input() value: boolean = false;
/// Description of the checkbox /// Description of the checkbox
@Input() comment: string = ""; @Input() comment: string = "";
/// event when change the value of the password /// event when change the value of the password
@Output() changeValue: EventEmitter<boolean> = new EventEmitter(); @Output() changeValue: EventEmitter<boolean> = new EventEmitter();
/** /**
* When input value change, need update the display and change the internal value. * When input value change, need update the display and change the internal value.
* @param newValue New value set on the password * @param newValue New value set on the password
*/ */
onChange(newValue: boolean): void { onChange(newValue: boolean): void {
this.value = newValue; this.value = newValue;
this.changeValue.emit(this.value); this.changeValue.emit(this.value);
} }

View File

@ -1,24 +1,17 @@
export { AsyncActionState, AsyncActionStatusComponent } from './async-action-status/async-status-component'; import { AsyncActionState, AsyncActionStatusComponent } from './async-action-status/async-status-component';
export { BurgerPropertyComponent } from './burger-property/burger-property'; import { BurgerPropertyComponent } from './burger-property/burger-property';
export { CheckboxComponent } from './checkbox/checkbox'; import { CheckboxComponent } from './checkbox/checkbox';
export { EntryNumberComponent } from './entry-number/entry-number'; import { EntryNumberComponent } from './entry-number/entry-number';
export { EntryValidatorComponent } from './entry-validator/entry-validator'; import { EntryValidatorComponent } from './entry-validator/entry-validator';
export { EntryComponent } from './entry/entry'; import { EntryComponent } from './entry/entry';
export { ErrorMessageStateComponent } from './error-message-state/error-message-state'; import { ErrorMessageStateComponent } from './error-message-state/error-message-state';
export { ErrorComponent } from './error/error'; import { ErrorComponent } from './error/error';
export { PasswordEntryComponent } from './password-entry/password-entry'; import { PasswordEntryComponent } from './password-entry/password-entry';
export { PopInComponent } from './popin/popin'; import { PopInComponent } from './popin/popin';
export { RenderFormComponent } from './render-settings/render-form'; import { RenderFormComponent } from './render-settings/render-form';
export { import { RenderSettingsComponent } from './render-settings/render-settings';
RenderSettingsComponent, import { SpinnerComponent } from './spinner/spinner';
SettingsItem, import { EventOnMenu, TopMenuComponent } from './top-menu/top-menu';
isSettingsItem, import { UploadFileComponent } from './upload-file/upload-file';
SettingType,
isSettingType, export { EventOnMenu, BurgerPropertyComponent, EntryNumberComponent, CheckboxComponent, RenderFormComponent, RenderSettingsComponent, ErrorMessageStateComponent, AsyncActionState, AsyncActionStatusComponent, EntryValidatorComponent, PopInComponent, TopMenuComponent, UploadFileComponent, ErrorComponent, SpinnerComponent, PasswordEntryComponent, EntryComponent };
CheckerParameter,
CheckerParameterType,
ReturnFunction,
} from './render-settings/render-settings';
export { SpinnerComponent } from './spinner/spinner';
export { EventOnMenu, TopMenuComponent } from './top-menu/top-menu';
export { UploadFileComponent } from './upload-file/upload-file';

View File

@ -3,7 +3,7 @@
<div class="element {{popSize}}"> <div class="element {{popSize}}">
<div class="header"> <div class="header">
<label class="unselectable">{{popTitle}}</label> <label class="unselectable">{{popTitle}}</label>
@if(closeTopRight) { @if(closeTopRight === true) {
<div class="close"> <div class="close">
<button class="button-close color-shadow-black" (click)="onCloseTop()" type="submit"> <button class="button-close color-shadow-black" (click)="onCloseTop()" type="submit">
<label class="unselectable"><i class="material-icons">close</i></label> <label class="unselectable"><i class="material-icons">close</i></label>
@ -15,28 +15,28 @@
<ng-content></ng-content> <ng-content></ng-content>
</div> </div>
<div class="footer"> <div class="footer">
@if(validateTitle) { @if(validateTitle !== null) {
<div class="action"> <div class="action">
<button class="button color-shadow-black" (click)="onValidate()" type="submit"> <button class="button color-shadow-black" (click)="onValidate()" type="submit">
<label class="unselectable"><i class="material-icons">done</i> {{validateTitle}}</label> <label class="unselectable"><i class="material-icons">done</i> {{validateTitle}}</label>
</button> </button>
</div> </div>
} }
@if(saveTitle) { @if(saveTitle != null) {
<div class="action"> <div class="action">
<button class="button color-shadow-black" (click)="onSave()" type="submit"> <button class="button color-shadow-black" (click)="onSave()" type="submit">
<label class="unselectable"><i class="material-icons">save_alt</i> {{saveTitle}}</label> <label class="unselectable"><i class="material-icons">save_alt</i> {{saveTitle}}</label>
</button> </button>
</div> </div>
} }
@if(otherTitle) { @if(otherTitle != null) {
<div class="action"> <div class="action">
<button class="button color-shadow-black" (click)="onOther()" type="submit"> <button class="button color-shadow-black" (click)="onOther()" type="submit">
<label class="unselectable"><i class="material-icons">star</i> {{otherTitle}}</label> <label class="unselectable"><i class="material-icons">star</i> {{otherTitle}}</label>
</button> </button>
</div> </div>
} }
@if(closeTitle) { @if(closeTitle != null) {
<div class="action"> <div class="action">
<button class="button color-shadow-black" (click)="onClose()" type="submit"> <button class="button color-shadow-black" (click)="onClose()" type="submit">
<label class="unselectable"><i class="material-icons">close</i> {{closeTitle}}</label> <label class="unselectable"><i class="material-icons">close</i> {{closeTitle}}</label>

View File

@ -21,10 +21,10 @@ export class PopInComponent implements OnInit, OnDestroy {
@Input() popSize: string = 'medium'; @Input() popSize: string = 'medium';
@Output() callback: EventEmitter<any> = new EventEmitter(); @Output() callback: EventEmitter<any> = new EventEmitter();
@Input() closeTitle?: string; @Input() closeTitle: any = null;
@Input() validateTitle?: string; @Input() validateTitle: any = null;
@Input() saveTitle?: string; @Input() saveTitle: any = null;
@Input() otherTitle?: string; @Input() otherTitle: any = null;
public displayPopIn: boolean = false; public displayPopIn: boolean = false;

View File

@ -1,79 +0,0 @@
import { CheckerParameter } from "../component/entry-validator/entry-validator";
import { isInArray, isNullOrUndefined, isObject, isString, isOptionalOf, isBoolean, isNumber, isUndefined } from "../utils";
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;
}

View File

@ -10,33 +10,35 @@
<p class="expand"> <p class="expand">
<label class="unselectable"><b>{{mediaTitle}}</b></label> <label class="unselectable"><b>{{mediaTitle}}</b></label>
</p> </p>
@if(error) { @if(progress != 100) {
<div>
<label class="unselectable"><b>Get an error From the server:</b></label
><br />
<label class="unselectable">{{error}}</label>
</div>
}
@else if(progress != 100) {
<div class="progress-back"> <div class="progress-back">
<div class="progress-bar" style="width:{{progress??0}}%">&nbsp;&nbsp;&nbsp;{{progress}}%</div> <div class="progress-bar" style="width:{{progress}}%">&nbsp;&nbsp;&nbsp;{{progress}}%</div>
</div> </div>
<div> <div>
<label class="unselectable">Upload:</label><label style="text-align: right">{{uploadDisplay}}</label><br /> <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> <label class="unselectable">Size:</label><label style="text-align: right">{{sizeDisplay}}</label>
</div> </div>
} }
@else if(result) { @else if (error == null && result == null) {
<div>
<label class="unselectable"><b>Upload finished:</b></label
><br />
<label class="unselectable">{{result}}</label>
</div>
}
@else {
<div> <div>
<label class="unselectable">Upload done ... waiting server answer</label> <label class="unselectable">Upload done ... waiting server answer</label>
</div> </div>
} }
@else {
@if(error != null) {
<div>
<label class="unselectable"><b>Get an error From the server:</b></label
><br />
<label class="unselectable">{{error}}</label>
</div>
}
@if(result != null) {
<div>
<label class="unselectable"><b>Upload finished:</b></label
><br />
<label class="unselectable">{{result}}</label>
</div>
}
}
</app-popin> </app-popin>
</div> </div>

View File

@ -4,28 +4,9 @@
* @license PROPRIETARY (see license file) * @license PROPRIETARY (see license file)
*/ */
import { Component, OnInit, Input, SimpleChanges, EventEmitter, Output } from '@angular/core'; import { Component, OnInit, Input, SimpleChanges } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { PopInService } from '../../service'; import { PopInService } from '../../service';
import { isNullOrUndefined } from '../../utils';
export class UploadProgress {
labelMediaTitle: string = '';
mediaSendSize: number = 0;
mediaSize: number = 99999999999999;
result?: string;
error?: string;
clear() {
this.labelMediaTitle = '';
this.mediaSendSize = 0;
this.mediaSize = 99999999999999;
this.result = undefined;
this.error = undefined;
}
}
@Component({ @Component({
selector: 'upload-progress', selector: 'upload-progress',
@ -38,7 +19,6 @@ export class PopInUploadProgress implements OnInit {
@Input() mediaSize: number = 999999999999; @Input() mediaSize: number = 999999999999;
@Input() result?: string; @Input() result?: string;
@Input() error?: string; @Input() error?: string;
@Output() abort: EventEmitter<void> = new EventEmitter();
public closeButtonTitle?: string = 'Abort'; public closeButtonTitle?: string = 'Abort';
public otherButtonTitle?: string; public otherButtonTitle?: string;
public validateButtonTitle?: string; public validateButtonTitle?: string;
@ -49,14 +29,8 @@ export class PopInUploadProgress implements OnInit {
OnDestroy() { } OnDestroy() { }
ngOnInit() { } ngOnInit() { }
eventPopUp(_event: string): void { eventPopUp(_event: string): void {
if (_event == "close") { console.log(`GET event: ${_event}`);
if (this.abort) { this.popInService.close('popin-upload-progress');
this.abort.emit();
}
} else {
console.log(`GET event: ${_event}`);
this.popInService.close('popin-upload-progress');
}
} }
updateNeedSend(): void { } updateNeedSend(): void { }
@ -106,11 +80,11 @@ export class PopInUploadProgress implements OnInit {
this.progress = Math.trunc((this.mediaUploaded * 100) / this.mediaSize); this.progress = Math.trunc((this.mediaUploaded * 100) / this.mediaSize);
this.uploadDisplay = this.convertInHuman(this.mediaUploaded); this.uploadDisplay = this.convertInHuman(this.mediaUploaded);
this.sizeDisplay = this.convertInHuman(this.mediaSize); this.sizeDisplay = this.convertInHuman(this.mediaSize);
if (isNullOrUndefined(this.error) && isNullOrUndefined(this.result)) { if (this.error === null && this.result === null) {
this.closeButtonTitle = 'Abort'; this.closeButtonTitle = 'Abort';
this.otherButtonTitle = undefined; this.otherButtonTitle = undefined;
this.validateButtonTitle = undefined; this.validateButtonTitle = undefined;
} else if (isNullOrUndefined(this.result)) { } else if (this.result === null) {
this.closeButtonTitle = undefined; this.closeButtonTitle = undefined;
this.otherButtonTitle = 'Close'; this.otherButtonTitle = 'Close';
this.validateButtonTitle = undefined; this.validateButtonTitle = undefined;
@ -121,3 +95,18 @@ export class PopInUploadProgress implements OnInit {
} }
} }
} }
export class UploadProgress {
labelMediaTitle: string = '';
mediaSendSize: number = 0;
mediaSize: number = 99999999999999;
result?: string;
error?: string;
clear() {
this.labelMediaTitle = '';
this.mediaSendSize = 0;
this.mediaSize = 99999999999999;
this.result = undefined;
this.error = undefined;
}
}

View File

@ -47,7 +47,7 @@ export class SSOService {
) { ) {
return this.utf8_to_b64(data); return this.utf8_to_b64(data);
} }
const pathName = getApplicationLocation(this.environment); const pathName = getApplicationLocation();
if (isInArray(pathName, ['sso', '/sso', '/sso/'])) { if (isInArray(pathName, ['sso', '/sso', '/sso/'])) {
return this.utf8_to_b64('home'); return this.utf8_to_b64('home');
} }

View File

@ -13,7 +13,6 @@ import { SSOService } from './sso';
import { getApplicationLocation, isNullOrUndefined, sha512 } from '../utils'; import { getApplicationLocation, isNullOrUndefined, sha512 } from '../utils';
import { HttpWrapperService, HTTPRequestModel, HTTPMimeType, ModelResponseHttp } from './http-wrapper_kjdhqslkjf'; import { HttpWrapperService, HTTPRequestModel, HTTPMimeType, ModelResponseHttp } from './http-wrapper_kjdhqslkjf';
import { Environment } from '../model/environment'; import { Environment } from '../model/environment';
import { APP_BASE_HREF } from '@angular/common';
@Injectable() @Injectable()
@ -77,7 +76,7 @@ export class UserService {
* Check if the system can be connected * Check if the system can be connected
*/ */
checkAutoConnect(): Promise<void> { checkAutoConnect(): Promise<void> {
let locationOrigin = getApplicationLocation(this.environment); let locationOrigin = getApplicationLocation();
const self = this; const self = this;
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
// Need to use the windows global route to prevent the log in cycle ... // Need to use the windows global route to prevent the log in cycle ...
@ -92,7 +91,7 @@ export class UserService {
} }
console.log(' ==> Check if need reconnect?'); console.log(' ==> Check if need reconnect?');
let rememberMe = self.getRememberMe(); let rememberMe = self.getRememberMe();
// TODO: in case of jest reload ==> no need to manage the SSO ==> just keep the token ... it in enough... // TODO: in case of jest reload ==> no need to manage the SSO ==> just keep the token ... it in enought...
let token: undefined | string = undefined; let token: undefined | string = undefined;
if ( if (
isNullOrUndefined(this.environment.tokenStoredInPermanentStorage) || isNullOrUndefined(this.environment.tokenStoredInPermanentStorage) ||
@ -110,7 +109,7 @@ export class UserService {
self.startSession(token ?? '', rememberMe) self.startSession(token ?? '', rememberMe)
.then(() => { .then(() => {
self.router.navigateByUrl(locationOrigin); self.router.navigateByUrl(locationOrigin);
console.log(`update global URL = ${locationOrigin} APP_BASE_HREF=${APP_BASE_HREF}`); console.log(`update global URL = ${locationOrigin}`);
resolve(); resolve();
}) })
.catch(() => { .catch(() => {

View File

@ -1,11 +1,12 @@
//import { environment } from 'environments/environment'; //import { environment } from 'environments/environment';
import { Environment } from "../model"; export function getApplicationLocation(): string {
export function getApplicationLocation(environment: Environment): string {
let pathName = location.pathname; let pathName = location.pathname;
return pathName;
//console.log("start Path-name: '" + pathName + "'"); //console.log("start Path-name: '" + pathName + "'");
//console.log("check with: '" + environment.applName + "/sso/" + "'"); //console.log("check with: '" + environment.applName + "/sso/" + "'");
/*
if (pathName.startsWith('/' + environment.applName + '/')) { if (pathName.startsWith('/' + environment.applName + '/')) {
pathName = pathName.substring(environment.applName.length + 2); pathName = pathName.substring(environment.applName.length + 2);
} else if (pathName.startsWith('/' + environment.applName)) { } else if (pathName.startsWith('/' + environment.applName)) {
@ -16,4 +17,5 @@ export function getApplicationLocation(environment: Environment): string {
pathName = pathName.substring(environment.applName.length); pathName = pathName.substring(environment.applName.length);
} }
return pathName; return pathName;
*/
} }

View File

@ -34,7 +34,7 @@ export class DataStore<TYPE> {
} }
resolve(self.data); resolve(self.data);
}).catch(error => { }).catch(error => {
console.log(`[E] ${self.constructor.name}: can not get data from remote server: ${JSON.stringify(error, null, 2)}`); console.log(`[E] ${self.constructor.name}: can not get data from remote server:`);
if (self.dataPromise) { if (self.dataPromise) {
for (let iii = 0; iii < self.dataPromise.length; iii++) { for (let iii = 0; iii < self.dataPromise.length; iii++) {
self.dataPromise[iii].reject(error); self.dataPromise[iii].reject(error);

View File

@ -23,11 +23,11 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"moduleResolution": "node", "moduleResolution": "node",
"importHelpers": true, "importHelpers": true,
"target": "ES2018", "target": "ES2022",
"module": "ES2015", "module": "ES2022",
"useDefineForClassFields": false, "useDefineForClassFields": false,
"lib": [ "lib": [
"ES2018", "ES2022",
"dom" "dom"
], ],
"emitDecoratorMetadata": true, "emitDecoratorMetadata": true,

View File

@ -1 +0,0 @@
0.4.1