turbogui-angular 20.8.0 → 20.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/turbogui-angular.mjs +230 -3
- package/fesm2022/turbogui-angular.mjs.map +1 -1
- package/main/controller/dialog.service.d.ts +80 -1
- package/main/controller/dialog.service.d.ts.map +1 -1
- package/main/controller/router-base.service.d.ts +16 -0
- package/main/controller/router-base.service.d.ts.map +1 -1
- package/main/view/components/dialog-image/dialog-image.component.d.ts +26 -0
- package/main/view/components/dialog-image/dialog-image.component.d.ts.map +1 -0
- package/package.json +1 -1
- package/public_api.d.ts +1 -0
- package/public_api.d.ts.map +1 -1
|
@@ -620,6 +620,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
|
|
|
620
620
|
args: [MAT_DIALOG_DATA]
|
|
621
621
|
}] }] });
|
|
622
622
|
|
|
623
|
+
/**
|
|
624
|
+
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
|
|
625
|
+
*
|
|
626
|
+
* Website : -> http://www.turbogui.org
|
|
627
|
+
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
|
|
628
|
+
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
|
|
629
|
+
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
|
|
630
|
+
*/
|
|
631
|
+
/**
|
|
632
|
+
* A dialog component with an image that can be used to display any picture url
|
|
633
|
+
*
|
|
634
|
+
* We must specify the url in the data parameter when opening the dialog, and we can also specify the title
|
|
635
|
+
* by placing it at the first position of the texts array.
|
|
636
|
+
*/
|
|
637
|
+
class DialogImageComponent extends DialogBaseComponent {
|
|
638
|
+
static { this.DIALOG_CLASS_NAME = 'DialogImageComponent'; }
|
|
639
|
+
constructor(elementRef, dialogRef, sanitizer, data) {
|
|
640
|
+
super(elementRef, dialogRef);
|
|
641
|
+
this.elementRef = elementRef;
|
|
642
|
+
this.dialogRef = dialogRef;
|
|
643
|
+
this.sanitizer = sanitizer;
|
|
644
|
+
this.data = data;
|
|
645
|
+
this.title = '';
|
|
646
|
+
if (data.texts.length > 0) {
|
|
647
|
+
this.title = data.texts[0];
|
|
648
|
+
}
|
|
649
|
+
this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(data.data);
|
|
650
|
+
}
|
|
651
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DialogImageComponent, deps: [{ token: i0.ElementRef }, { token: i1.MatDialogRef }, { token: i2$1.DomSanitizer }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
652
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: DialogImageComponent, isStandalone: true, selector: "tg-dialog-image", providers: [], usesInheritance: true, ngImport: i0, template: "<h2 *ngIf=\"title !== ''\">{{title}}</h2>\r\n\r\n<img [src]=\"safeUrl\" title=\"title\" alt=\"{{title}}\" />", styles: [":host{display:block;width:100%;height:100%}h2{margin-top:0;margin-bottom:25px;width:82%}iframe{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
|
|
653
|
+
}
|
|
654
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DialogImageComponent, decorators: [{
|
|
655
|
+
type: Component,
|
|
656
|
+
args: [{ selector: 'tg-dialog-image', imports: [CommonModule], providers: [], template: "<h2 *ngIf=\"title !== ''\">{{title}}</h2>\r\n\r\n<img [src]=\"safeUrl\" title=\"title\" alt=\"{{title}}\" />", styles: [":host{display:block;width:100%;height:100%}h2{margin-top:0;margin-bottom:25px;width:82%}iframe{width:100%;height:100%}\n"] }]
|
|
657
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.MatDialogRef }, { type: i2$1.DomSanitizer }, { type: undefined, decorators: [{
|
|
658
|
+
type: Inject,
|
|
659
|
+
args: [MAT_DIALOG_DATA]
|
|
660
|
+
}] }] });
|
|
661
|
+
|
|
623
662
|
/**
|
|
624
663
|
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
|
|
625
664
|
*
|
|
@@ -1003,7 +1042,7 @@ class DialogService extends SingletoneStrictClass {
|
|
|
1003
1042
|
*/
|
|
1004
1043
|
addDialog(dialogComponentClass, properties) {
|
|
1005
1044
|
if (!this._isEnabled) {
|
|
1006
|
-
return Promise.
|
|
1045
|
+
return Promise.resolve({ index: -1 });
|
|
1007
1046
|
}
|
|
1008
1047
|
return new Promise((resolve) => {
|
|
1009
1048
|
// Set the default values for non specified properties
|
|
@@ -1075,6 +1114,130 @@ class DialogService extends SingletoneStrictClass {
|
|
|
1075
1114
|
});
|
|
1076
1115
|
});
|
|
1077
1116
|
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Shows a native OS file browser dialog to let the user select a single file from their local file system.
|
|
1119
|
+
*
|
|
1120
|
+
* @param options An object containing options for the file browser dialog:
|
|
1121
|
+
* - accept: A string that defines the file types the file input should accept. For example: '.csv,.xlsx', 'image/*', '.pdf', 'image/jpeg, image/png'.
|
|
1122
|
+
* - maxFileSize: (Optional) The maximum file size in bytes allowed for the selected file. If the selected file exceeds this size, the promise will be rejected with an error
|
|
1123
|
+
* - loadData: (Optional) Defines how the file content should be read and returned.
|
|
1124
|
+
* 'no' (default): Returns the raw File object without its data.
|
|
1125
|
+
* 'ArrayBuffer': Returns the File object with its content read as a raw binary `ArrayBuffer` in the `data` property.
|
|
1126
|
+
* 'text': Returns the File object with its content read as a text string in the `data` property.
|
|
1127
|
+
* 'base64': Returns the File object with its content read as a Base64 encoded string in the `data` property.
|
|
1128
|
+
*
|
|
1129
|
+
* @returns A Promise that resolves with the selected `File` object (which may have an added `data` property), or `null` if the user cancels the dialog.
|
|
1130
|
+
* The promise will be rejected with an Error if the selected file exceeds the specified size limits.
|
|
1131
|
+
*/
|
|
1132
|
+
async addFileBrowserDialog(options) {
|
|
1133
|
+
const files = await this._addFileBrowserDialogInternal({
|
|
1134
|
+
multiple: false,
|
|
1135
|
+
accept: options.accept,
|
|
1136
|
+
maxFileSize: options.maxFileSize,
|
|
1137
|
+
loadData: options.loadData
|
|
1138
|
+
});
|
|
1139
|
+
return files ? files[0] : null;
|
|
1140
|
+
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Shows a native OS file browser dialog to let the user select one or more files from their local file system.
|
|
1143
|
+
*
|
|
1144
|
+
* @param options An object containing options for the file browser dialog:
|
|
1145
|
+
* - accept: A string that defines the file types the file input should accept. For example: '.csv,.xlsx', 'image/*', '.pdf', 'image/jpeg, image/png'.
|
|
1146
|
+
* - maxFileSize: (Optional) The maximum file size in bytes allowed for any single selected file. If a selected file exceeds this size, the promise will be rejected with an error.
|
|
1147
|
+
* - maxTotalSize: (Optional) The maximum total size in bytes for all selected files combined. If the total size of all files exceeds this limit, the promise will be rejected with an error.
|
|
1148
|
+
* - loadData: (Optional) Defines how the file content should be read and returned.
|
|
1149
|
+
* 'no' (default): Returns an array of `File` objects without their data.
|
|
1150
|
+
* 'ArrayBuffer': Returns an array of `File` objects, each with its content read as a raw binary `ArrayBuffer` in the `data` property.
|
|
1151
|
+
* 'text': Returns an array of `File` objects, each with its content read as a text string in the `data` property.
|
|
1152
|
+
* 'base64': Returns an array of `File` objects, each with its content read as a Base64 encoded string in the `data` property.
|
|
1153
|
+
*
|
|
1154
|
+
* @returns A Promise that resolves with an array of `File` objects (which may have an added `data` property), or `null` if the user cancels the dialog.
|
|
1155
|
+
* The promise will be rejected with an Error if the selected files exceed the specified size limits.
|
|
1156
|
+
*/
|
|
1157
|
+
addFilesBrowserDialog(options) {
|
|
1158
|
+
return this._addFileBrowserDialogInternal({
|
|
1159
|
+
multiple: true,
|
|
1160
|
+
accept: options.accept,
|
|
1161
|
+
maxFileSize: options.maxFileSize,
|
|
1162
|
+
maxTotalSize: options.maxTotalSize,
|
|
1163
|
+
loadData: options.loadData
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Auxiliary method that combines the logic for addFileBrowserDialog and addFilesBrowserDialog
|
|
1168
|
+
*/
|
|
1169
|
+
async _addFileBrowserDialogInternal(options) {
|
|
1170
|
+
if (!this._isEnabled) {
|
|
1171
|
+
return null;
|
|
1172
|
+
}
|
|
1173
|
+
// Create a hidden input element to show the file browser dialog
|
|
1174
|
+
const input = this._renderer.createElement('input');
|
|
1175
|
+
this._renderer.setAttribute(input, 'type', 'file');
|
|
1176
|
+
this._renderer.setAttribute(input, 'accept', options.accept);
|
|
1177
|
+
this._renderer.setAttribute(input, 'id', 'turbogui-file-browser-input-hidden-dialog');
|
|
1178
|
+
if (options.multiple) {
|
|
1179
|
+
this._renderer.setAttribute(input, 'multiple', 'true');
|
|
1180
|
+
}
|
|
1181
|
+
this._renderer.setStyle(input, 'display', 'none');
|
|
1182
|
+
this._renderer.appendChild(document.body, input);
|
|
1183
|
+
try {
|
|
1184
|
+
const files = await new Promise((resolve) => {
|
|
1185
|
+
const onFocus = () => {
|
|
1186
|
+
setTimeout(() => {
|
|
1187
|
+
if (!input.files || input.files.length === 0) {
|
|
1188
|
+
resolve(null);
|
|
1189
|
+
}
|
|
1190
|
+
}, 600);
|
|
1191
|
+
};
|
|
1192
|
+
const onChange = (event) => {
|
|
1193
|
+
const fileList = event.target.files;
|
|
1194
|
+
resolve(fileList ? Array.from(fileList) : null);
|
|
1195
|
+
};
|
|
1196
|
+
input.addEventListener('change', onChange);
|
|
1197
|
+
window.addEventListener('focus', onFocus, { once: true });
|
|
1198
|
+
input.click();
|
|
1199
|
+
});
|
|
1200
|
+
if (!files || files.length === 0) {
|
|
1201
|
+
return null;
|
|
1202
|
+
}
|
|
1203
|
+
let totalSize = 0;
|
|
1204
|
+
for (const file of files) {
|
|
1205
|
+
if (options.maxFileSize !== undefined && file.size > options.maxFileSize) {
|
|
1206
|
+
throw new Error(`Max file size exceeded: "${file.name}" exceeds ${options.maxFileSize} bytes`);
|
|
1207
|
+
}
|
|
1208
|
+
totalSize += file.size;
|
|
1209
|
+
}
|
|
1210
|
+
if (options.maxTotalSize !== undefined && totalSize > options.maxTotalSize) {
|
|
1211
|
+
throw new Error(`Max total size exceeded: ${options.maxTotalSize} bytes`);
|
|
1212
|
+
}
|
|
1213
|
+
if (!options.loadData || options.loadData === 'no') {
|
|
1214
|
+
return files;
|
|
1215
|
+
}
|
|
1216
|
+
const fileReadPromises = files.map(async (file) => {
|
|
1217
|
+
switch (options.loadData) {
|
|
1218
|
+
case 'ArrayBuffer':
|
|
1219
|
+
file.data = await file.arrayBuffer();
|
|
1220
|
+
break;
|
|
1221
|
+
case 'text':
|
|
1222
|
+
file.data = await file.text();
|
|
1223
|
+
break;
|
|
1224
|
+
case 'base64':
|
|
1225
|
+
file.data = await new Promise((resolve, reject) => {
|
|
1226
|
+
const reader = new FileReader();
|
|
1227
|
+
reader.onload = () => resolve(reader.result.split(',')[1]);
|
|
1228
|
+
reader.onerror = () => reject(reader.error ?? new Error('Unknown FileReader error'));
|
|
1229
|
+
reader.readAsDataURL(file);
|
|
1230
|
+
});
|
|
1231
|
+
break;
|
|
1232
|
+
}
|
|
1233
|
+
return file;
|
|
1234
|
+
});
|
|
1235
|
+
return await Promise.all(fileReadPromises);
|
|
1236
|
+
}
|
|
1237
|
+
finally {
|
|
1238
|
+
this._renderer.removeChild(document.body, input);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1078
1241
|
/**
|
|
1079
1242
|
* Show a dialog with an iframe inside it, to show external web pages or web applications.
|
|
1080
1243
|
*
|
|
@@ -1107,6 +1270,38 @@ class DialogService extends SingletoneStrictClass {
|
|
|
1107
1270
|
}
|
|
1108
1271
|
return null;
|
|
1109
1272
|
}
|
|
1273
|
+
/**
|
|
1274
|
+
* Show a dialog with an image inside it, to load image files from a url.
|
|
1275
|
+
*
|
|
1276
|
+
* This method is a shortcut for addDialog() method using DialogImageComponent as the dialog component class
|
|
1277
|
+
*
|
|
1278
|
+
* @param properties An object containing the different visual and textual options that this dialog allows:
|
|
1279
|
+
* - url (mandatory): The url to load in the image
|
|
1280
|
+
* - title: The title to show at the top of the dialog
|
|
1281
|
+
* - id: see addDialog() docs
|
|
1282
|
+
* - width: see addDialog() docs
|
|
1283
|
+
* - maxWidth: see addDialog() docs
|
|
1284
|
+
* - height: see addDialog() docs
|
|
1285
|
+
* - maxHeight: see addDialog() docs
|
|
1286
|
+
* - modal: see addDialog() docs
|
|
1287
|
+
*
|
|
1288
|
+
* @returns A Promise that resolves once the user closes the dialog
|
|
1289
|
+
*/
|
|
1290
|
+
async addImageDialog(properties) {
|
|
1291
|
+
if (this._isEnabled) {
|
|
1292
|
+
await this.addDialog(DialogImageComponent, {
|
|
1293
|
+
id: properties.id ?? undefined,
|
|
1294
|
+
data: properties.url,
|
|
1295
|
+
texts: properties.title ? [properties.title] : undefined,
|
|
1296
|
+
width: properties.width ?? "85vw",
|
|
1297
|
+
maxWidth: properties.maxWidth ?? "1200px",
|
|
1298
|
+
height: properties.height ?? "98vh",
|
|
1299
|
+
maxHeight: properties.maxHeight ?? "3000px",
|
|
1300
|
+
modal: properties.modal ?? false
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
return null;
|
|
1304
|
+
}
|
|
1110
1305
|
/**
|
|
1111
1306
|
* Show a dialog with a pdf from a binary blob data.
|
|
1112
1307
|
*
|
|
@@ -1151,7 +1346,7 @@ class DialogService extends SingletoneStrictClass {
|
|
|
1151
1346
|
* - maxHeight: see addDialog() docs
|
|
1152
1347
|
* - modal: see addDialog() docs
|
|
1153
1348
|
* - title: The title to show at the top of the dialog
|
|
1154
|
-
* - viewContainerRef: see addDialog() docs
|
|
1349
|
+
* - viewContainerRef: MANDATORY! or the component won't render. see addDialog() docs
|
|
1155
1350
|
*
|
|
1156
1351
|
* @returns A Promise that resolves to a Date() object selected by the user or null if no selection was made
|
|
1157
1352
|
*/
|
|
@@ -1972,6 +2167,38 @@ class RouterBaseService {
|
|
|
1972
2167
|
}
|
|
1973
2168
|
return currentRoute.params[key];
|
|
1974
2169
|
}
|
|
2170
|
+
/**
|
|
2171
|
+
* Gets the value of a specific query parameter by its key from the current route.
|
|
2172
|
+
* For example, if the current route is `/search?query=angular`, and you call this method with `key` as `query`, it will return `angular`.
|
|
2173
|
+
*
|
|
2174
|
+
* @param key The key of the query parameter to retrieve.
|
|
2175
|
+
*/
|
|
2176
|
+
getQueryParamValue(key) {
|
|
2177
|
+
let currentRoute = this.router.routerState.snapshot.root;
|
|
2178
|
+
while (currentRoute.firstChild) {
|
|
2179
|
+
currentRoute = currentRoute.firstChild;
|
|
2180
|
+
}
|
|
2181
|
+
return currentRoute.queryParams[key];
|
|
2182
|
+
}
|
|
2183
|
+
/**
|
|
2184
|
+
* Sets or updates the value of a specific query parameter in the current route.
|
|
2185
|
+
* For example, if the current route is `/search?query=angular`, and you call this method with `key` as `page` and `value` as `2`,
|
|
2186
|
+
* it will navigate to `/search?query=angular&page=2`.
|
|
2187
|
+
*
|
|
2188
|
+
* @param key The key of the query parameter to set or update.
|
|
2189
|
+
* @param value The value to set for the specified query parameter.
|
|
2190
|
+
*/
|
|
2191
|
+
setQueryParamValue(key, value) {
|
|
2192
|
+
let currentRoute = this.router.routerState.root;
|
|
2193
|
+
while (currentRoute.firstChild) {
|
|
2194
|
+
currentRoute = currentRoute.firstChild;
|
|
2195
|
+
}
|
|
2196
|
+
this.router.navigate([], {
|
|
2197
|
+
relativeTo: currentRoute,
|
|
2198
|
+
queryParams: { [key]: value },
|
|
2199
|
+
queryParamsHandling: 'merge'
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
1975
2202
|
/**
|
|
1976
2203
|
* Initializes the title management feature to automatically refresh the browser title based on the current
|
|
1977
2204
|
* URL route. It Must be called once, typically at application startup
|
|
@@ -3414,5 +3641,5 @@ class ValidatorsPlus extends Validators {
|
|
|
3414
3641
|
* Generated bundle index. Do not edit.
|
|
3415
3642
|
*/
|
|
3416
3643
|
|
|
3417
|
-
export { AutoFocusOnDisplayDirective, AutoSelectTextOnFocusDirective, BrowserService, BusyStateBaseComponent, ButtonContainerComponent, ButtonImageComponent, DelayedMethodCallManager, DialogBaseComponent, DialogDateSelectionComponent, DialogErrorComponent, DialogIFrameComponent, DialogMultipleOptionComponent, DialogService, DialogSingleInputComponent, DialogSingleOptionComponent, DialogSingleSelectionListComponent, DialogTwoOptionComponent, ElementClickOutsideDirective, ElementCreatedDirective, ElementDestroyedDirective, FadeAnimationClass, GUINotification, GlobalErrorService, HTTPService, HTTPServiceGetRequest, HTTPServicePostRequest, LocalesBaseService, NotificationService, RouterBaseService, SingletoneStrictClass, TurboApiService, TurboGuiAngularModule, ValidatorsPlus, View, ViewService };
|
|
3644
|
+
export { AutoFocusOnDisplayDirective, AutoSelectTextOnFocusDirective, BrowserService, BusyStateBaseComponent, ButtonContainerComponent, ButtonImageComponent, DelayedMethodCallManager, DialogBaseComponent, DialogDateSelectionComponent, DialogErrorComponent, DialogIFrameComponent, DialogImageComponent, DialogMultipleOptionComponent, DialogService, DialogSingleInputComponent, DialogSingleOptionComponent, DialogSingleSelectionListComponent, DialogTwoOptionComponent, ElementClickOutsideDirective, ElementCreatedDirective, ElementDestroyedDirective, FadeAnimationClass, GUINotification, GlobalErrorService, HTTPService, HTTPServiceGetRequest, HTTPServicePostRequest, LocalesBaseService, NotificationService, RouterBaseService, SingletoneStrictClass, TurboApiService, TurboGuiAngularModule, ValidatorsPlus, View, ViewService };
|
|
3418
3645
|
//# sourceMappingURL=turbogui-angular.mjs.map
|