http-request-manager 18.11.23 → 18.12.1
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.
|
@@ -2655,6 +2655,157 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
2655
2655
|
|
|
2656
2656
|
// ChannelType is already exported from request-manager-state-service to avoid conflicts
|
|
2657
2657
|
|
|
2658
|
+
class DatabaseStorage {
|
|
2659
|
+
constructor(table = '', expiresIn) {
|
|
2660
|
+
this.table = table;
|
|
2661
|
+
this.expiresIn = expiresIn;
|
|
2662
|
+
}
|
|
2663
|
+
static adapt(item) {
|
|
2664
|
+
if (!item?.table)
|
|
2665
|
+
return;
|
|
2666
|
+
return new DatabaseStorage(item?.table, item?.expiresIn);
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
|
|
2670
|
+
class RetryOptions {
|
|
2671
|
+
constructor(times = 0, delay = 3) {
|
|
2672
|
+
this.times = times;
|
|
2673
|
+
this.delay = delay;
|
|
2674
|
+
}
|
|
2675
|
+
static adapt(item) {
|
|
2676
|
+
return new RetryOptions(item?.times, item?.delay);
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
|
|
2680
|
+
class BatchOptions {
|
|
2681
|
+
constructor(mode = 'sequential', stopOnError = false, concurrency = 3, ignoreErrors = false, logErrors = true, displaySuccess, displayError) {
|
|
2682
|
+
this.mode = mode;
|
|
2683
|
+
this.stopOnError = stopOnError;
|
|
2684
|
+
this.concurrency = concurrency;
|
|
2685
|
+
this.ignoreErrors = ignoreErrors;
|
|
2686
|
+
this.logErrors = logErrors;
|
|
2687
|
+
this.displaySuccess = displaySuccess;
|
|
2688
|
+
this.displayError = displayError;
|
|
2689
|
+
}
|
|
2690
|
+
static adapt(item) {
|
|
2691
|
+
return new BatchOptions(item?.mode ?? 'sequential', item?.stopOnError ?? false, item?.concurrency ?? 3, item?.ignoreErrors ?? false, item?.logErrors !== false, item?.displaySuccess ?? false, item?.displayError ?? false);
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
|
|
2695
|
+
class BatchResult {
|
|
2696
|
+
constructor(request, success, data, error, index = 0, timestamp = Date.now()) {
|
|
2697
|
+
this.request = request;
|
|
2698
|
+
this.success = success;
|
|
2699
|
+
this.data = data;
|
|
2700
|
+
this.error = error;
|
|
2701
|
+
this.index = index;
|
|
2702
|
+
this.timestamp = timestamp;
|
|
2703
|
+
}
|
|
2704
|
+
static adapt(item) {
|
|
2705
|
+
return new BatchResult(item?.request, item?.success ?? false, item?.data, item?.error, item?.index ?? 0, item?.timestamp ?? Date.now());
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
function isPendingState(state) {
|
|
2710
|
+
return state.isPending === true;
|
|
2711
|
+
}
|
|
2712
|
+
function isSuccessState(state) {
|
|
2713
|
+
return state.isPending === false && state.data !== undefined;
|
|
2714
|
+
}
|
|
2715
|
+
function isErrorState(state) {
|
|
2716
|
+
return state.isPending === false && state.error !== undefined;
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2719
|
+
function calculateBatchProgress(states) {
|
|
2720
|
+
const total = states.length;
|
|
2721
|
+
const pending = states.filter(s => s.isPending).length;
|
|
2722
|
+
const completed = states.filter(s => !s.isPending && s.data !== undefined).length;
|
|
2723
|
+
const failed = states.filter(s => !s.isPending && s.error !== undefined).length;
|
|
2724
|
+
const percent = total > 0 ? Math.round(((completed + failed) / total) * 100) : 0;
|
|
2725
|
+
return { total, pending, completed, failed, percent };
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
var DataType;
|
|
2729
|
+
(function (DataType) {
|
|
2730
|
+
DataType[DataType["ANY"] = 0] = "ANY";
|
|
2731
|
+
DataType[DataType["ARRAY"] = 1] = "ARRAY";
|
|
2732
|
+
DataType[DataType["OBJECT"] = 2] = "OBJECT";
|
|
2733
|
+
})(DataType || (DataType = {}));
|
|
2734
|
+
|
|
2735
|
+
class ConfigHTTPOptions {
|
|
2736
|
+
constructor(server = '', path, headers, polling, retry, stream, displayError, displaySuccess) {
|
|
2737
|
+
this.server = server;
|
|
2738
|
+
this.path = path;
|
|
2739
|
+
this.headers = headers;
|
|
2740
|
+
this.polling = polling;
|
|
2741
|
+
this.retry = retry;
|
|
2742
|
+
this.stream = stream;
|
|
2743
|
+
this.displayError = displayError;
|
|
2744
|
+
this.displaySuccess = displaySuccess;
|
|
2745
|
+
}
|
|
2746
|
+
static adapt(item) {
|
|
2747
|
+
const server = Array.isArray(item?.server) ? item.server.join('/') : item?.server || '';
|
|
2748
|
+
const retryOptions = item?.retry ? RetryOptions.adapt(item.retry) : RetryOptions.adapt();
|
|
2749
|
+
return new ConfigHTTPOptions(server, (item?.path) ? item.path : [], (item?.headers) ? item.headers : {}, item?.polling ? Math.floor(item.polling) : 0, retryOptions, (item?.stream) ? item.stream : false, (item?.displayError) ? item.displayError : false, (item?.displaySuccess) ? item.displaySuccess : false);
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
|
|
2753
|
+
class LocalStorageOptions {
|
|
2754
|
+
constructor(storageName, storageSettingsName, options) {
|
|
2755
|
+
this.storageName = storageName;
|
|
2756
|
+
this.storageSettingsName = storageSettingsName;
|
|
2757
|
+
this.options = options;
|
|
2758
|
+
}
|
|
2759
|
+
static adapt(item) {
|
|
2760
|
+
return new LocalStorageOptions((item?.storageName) ? item.storageName : 'storage', (item?.storageSettingsName) ? item.storageSettingsName : 'global-storage', (item?.options) ? SettingOptions.adapt(item.options) : SettingOptions.adapt());
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
class ConfigOptions {
|
|
2765
|
+
constructor(httpRequestOptions, LocalStorageOptions) {
|
|
2766
|
+
this.httpRequestOptions = httpRequestOptions;
|
|
2767
|
+
this.LocalStorageOptions = LocalStorageOptions;
|
|
2768
|
+
}
|
|
2769
|
+
static adapt(item) {
|
|
2770
|
+
return new ConfigOptions((item?.httpRequestOptions) ? ConfigHTTPOptions.adapt(item.httpRequestOptions) : undefined, (item?.LocalStorageOptions) ? LocalStorageOptions.adapt(item.LocalStorageOptions) : undefined);
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2774
|
+
class InvalidFileInfoModel {
|
|
2775
|
+
constructor(fileName = '', fileSize = 0, fileType = '', errors = []) {
|
|
2776
|
+
this.fileName = fileName;
|
|
2777
|
+
this.fileSize = fileSize;
|
|
2778
|
+
this.fileType = fileType;
|
|
2779
|
+
this.errors = errors;
|
|
2780
|
+
}
|
|
2781
|
+
static adapt(item) {
|
|
2782
|
+
return new InvalidFileInfoModel(item?.fileName, item?.fileSize, item?.fileType, Array.isArray(item?.errors) ? item.errors : []);
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
class UploadValidationErrorModel {
|
|
2786
|
+
constructor(invalidFiles = [], validFilesCount = 0, totalFilesCount = 0) {
|
|
2787
|
+
this.invalidFiles = invalidFiles;
|
|
2788
|
+
this.validFilesCount = validFilesCount;
|
|
2789
|
+
this.totalFilesCount = totalFilesCount;
|
|
2790
|
+
}
|
|
2791
|
+
static adapt(item) {
|
|
2792
|
+
return new UploadValidationErrorModel(Array.isArray(item?.invalidFiles) ? item.invalidFiles.map((f) => InvalidFileInfoModel.adapt(f)) : [], item?.validFilesCount, item?.totalFilesCount);
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2796
|
+
class UserData {
|
|
2797
|
+
constructor(ldap = '', name = '', email = '', color = RandomPaletteColor()) {
|
|
2798
|
+
this.ldap = ldap;
|
|
2799
|
+
this.name = name;
|
|
2800
|
+
this.email = email;
|
|
2801
|
+
this.color = color;
|
|
2802
|
+
}
|
|
2803
|
+
static adapt(item) {
|
|
2804
|
+
const userName = `${item?.first_name} ${item?.last_name}`;
|
|
2805
|
+
return new UserData(item?.ldap, userName, item?.email, item?.color);
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2658
2809
|
class RequestService extends WebsocketService {
|
|
2659
2810
|
constructor() {
|
|
2660
2811
|
super(...arguments);
|
|
@@ -2795,6 +2946,89 @@ class RequestService extends WebsocketService {
|
|
|
2795
2946
|
return throwError(() => err);
|
|
2796
2947
|
}));
|
|
2797
2948
|
}
|
|
2949
|
+
uploadFileRequest(options) {
|
|
2950
|
+
this.isPending.next(true);
|
|
2951
|
+
const files = options.uploadFiles ? (Array.isArray(options.uploadFiles) ? options.uploadFiles : [options.uploadFiles]) : [];
|
|
2952
|
+
const validation = this.validateUploadFiles(files, options);
|
|
2953
|
+
if (validation.validFiles.length === 0) {
|
|
2954
|
+
this.isPending.next(false);
|
|
2955
|
+
return throwError(() => new UploadValidationErrorModel(validation.invalidFiles, 0, files.length));
|
|
2956
|
+
}
|
|
2957
|
+
const fieldName = options.uploadFieldName || (files.length === 1 ? 'file' : 'files');
|
|
2958
|
+
const formData = this.buildFormData(validation.validFiles, fieldName);
|
|
2959
|
+
const urlPath = this.buildUrlPath(options);
|
|
2960
|
+
const method = options.uploadHttpMethod || 'POST';
|
|
2961
|
+
return this.http.request(method, urlPath, {
|
|
2962
|
+
body: formData,
|
|
2963
|
+
observe: 'events',
|
|
2964
|
+
reportProgress: true
|
|
2965
|
+
}).pipe(map((event) => {
|
|
2966
|
+
this.isPending.next(true);
|
|
2967
|
+
switch (event.type) {
|
|
2968
|
+
case HttpEventType.UploadProgress:
|
|
2969
|
+
const status = event.total ? Math.round(event.loaded / (event.total || 1) * 100) : 0;
|
|
2970
|
+
this.progress.next(status);
|
|
2971
|
+
return null;
|
|
2972
|
+
case HttpEventType.Response:
|
|
2973
|
+
this.isPending.next(false);
|
|
2974
|
+
this.progress.next(0);
|
|
2975
|
+
return event.body;
|
|
2976
|
+
default:
|
|
2977
|
+
return null;
|
|
2978
|
+
}
|
|
2979
|
+
}), filter((body) => body !== null), catchError(err => {
|
|
2980
|
+
this.isPending.next(false);
|
|
2981
|
+
this.progress.next(0);
|
|
2982
|
+
return throwError(() => err);
|
|
2983
|
+
}));
|
|
2984
|
+
}
|
|
2985
|
+
validateUploadFiles(files, options) {
|
|
2986
|
+
const validFiles = [];
|
|
2987
|
+
const invalidFiles = [];
|
|
2988
|
+
let totalSize = 0;
|
|
2989
|
+
for (const file of files) {
|
|
2990
|
+
const errors = [];
|
|
2991
|
+
if (options.allowedTypes && options.allowedTypes.length > 0) {
|
|
2992
|
+
const isAllowed = options.allowedTypes.some(type => {
|
|
2993
|
+
if (type.endsWith('/*')) {
|
|
2994
|
+
return file.type.startsWith(type.replace('/*', '/'));
|
|
2995
|
+
}
|
|
2996
|
+
return file.type === type;
|
|
2997
|
+
});
|
|
2998
|
+
if (!isAllowed) {
|
|
2999
|
+
errors.push('type not allowed');
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
const maxFileSize = options.maxFileSize !== undefined ? options.maxFileSize : Infinity;
|
|
3003
|
+
if (file.size > maxFileSize) {
|
|
3004
|
+
errors.push('exceeds maxFileSize');
|
|
3005
|
+
}
|
|
3006
|
+
if (errors.length > 0) {
|
|
3007
|
+
invalidFiles.push(new InvalidFileInfoModel(file.name, file.size, file.type, errors));
|
|
3008
|
+
}
|
|
3009
|
+
else {
|
|
3010
|
+
validFiles.push(file);
|
|
3011
|
+
totalSize += file.size;
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
const maxTotalSize = options.maxTotalSize !== undefined ? options.maxTotalSize : Infinity;
|
|
3015
|
+
if (totalSize > maxTotalSize) {
|
|
3016
|
+
return {
|
|
3017
|
+
validFiles: [],
|
|
3018
|
+
invalidFiles: [
|
|
3019
|
+
new InvalidFileInfoModel('total', totalSize, '', ['exceeds maxTotalSize'])
|
|
3020
|
+
]
|
|
3021
|
+
};
|
|
3022
|
+
}
|
|
3023
|
+
return { validFiles, invalidFiles };
|
|
3024
|
+
}
|
|
3025
|
+
buildFormData(files, fieldName) {
|
|
3026
|
+
const formData = new FormData();
|
|
3027
|
+
files.forEach((file) => {
|
|
3028
|
+
formData.append(fieldName, file);
|
|
3029
|
+
});
|
|
3030
|
+
return formData;
|
|
3031
|
+
}
|
|
2798
3032
|
handleFinalize() {
|
|
2799
3033
|
return finalize(() => this.isPending.next(false));
|
|
2800
3034
|
}
|
|
@@ -2912,135 +3146,6 @@ function requestPolling(pollInterval, stopCondition$, isPending$) {
|
|
|
2912
3146
|
};
|
|
2913
3147
|
}
|
|
2914
3148
|
|
|
2915
|
-
class DatabaseStorage {
|
|
2916
|
-
constructor(table = '', expiresIn) {
|
|
2917
|
-
this.table = table;
|
|
2918
|
-
this.expiresIn = expiresIn;
|
|
2919
|
-
}
|
|
2920
|
-
static adapt(item) {
|
|
2921
|
-
if (!item?.table)
|
|
2922
|
-
return;
|
|
2923
|
-
return new DatabaseStorage(item?.table, item?.expiresIn);
|
|
2924
|
-
}
|
|
2925
|
-
}
|
|
2926
|
-
|
|
2927
|
-
class RetryOptions {
|
|
2928
|
-
constructor(times = 0, delay = 3) {
|
|
2929
|
-
this.times = times;
|
|
2930
|
-
this.delay = delay;
|
|
2931
|
-
}
|
|
2932
|
-
static adapt(item) {
|
|
2933
|
-
return new RetryOptions(item?.times, item?.delay);
|
|
2934
|
-
}
|
|
2935
|
-
}
|
|
2936
|
-
|
|
2937
|
-
class BatchOptions {
|
|
2938
|
-
constructor(mode = 'sequential', stopOnError = false, concurrency = 3, ignoreErrors = false, logErrors = true, displaySuccess, displayError) {
|
|
2939
|
-
this.mode = mode;
|
|
2940
|
-
this.stopOnError = stopOnError;
|
|
2941
|
-
this.concurrency = concurrency;
|
|
2942
|
-
this.ignoreErrors = ignoreErrors;
|
|
2943
|
-
this.logErrors = logErrors;
|
|
2944
|
-
this.displaySuccess = displaySuccess;
|
|
2945
|
-
this.displayError = displayError;
|
|
2946
|
-
}
|
|
2947
|
-
static adapt(item) {
|
|
2948
|
-
return new BatchOptions(item?.mode ?? 'sequential', item?.stopOnError ?? false, item?.concurrency ?? 3, item?.ignoreErrors ?? false, item?.logErrors !== false, item?.displaySuccess ?? false, item?.displayError ?? false);
|
|
2949
|
-
}
|
|
2950
|
-
}
|
|
2951
|
-
|
|
2952
|
-
class BatchResult {
|
|
2953
|
-
constructor(request, success, data, error, index = 0, timestamp = Date.now()) {
|
|
2954
|
-
this.request = request;
|
|
2955
|
-
this.success = success;
|
|
2956
|
-
this.data = data;
|
|
2957
|
-
this.error = error;
|
|
2958
|
-
this.index = index;
|
|
2959
|
-
this.timestamp = timestamp;
|
|
2960
|
-
}
|
|
2961
|
-
static adapt(item) {
|
|
2962
|
-
return new BatchResult(item?.request, item?.success ?? false, item?.data, item?.error, item?.index ?? 0, item?.timestamp ?? Date.now());
|
|
2963
|
-
}
|
|
2964
|
-
}
|
|
2965
|
-
|
|
2966
|
-
function isPendingState(state) {
|
|
2967
|
-
return state.isPending === true;
|
|
2968
|
-
}
|
|
2969
|
-
function isSuccessState(state) {
|
|
2970
|
-
return state.isPending === false && state.data !== undefined;
|
|
2971
|
-
}
|
|
2972
|
-
function isErrorState(state) {
|
|
2973
|
-
return state.isPending === false && state.error !== undefined;
|
|
2974
|
-
}
|
|
2975
|
-
|
|
2976
|
-
function calculateBatchProgress(states) {
|
|
2977
|
-
const total = states.length;
|
|
2978
|
-
const pending = states.filter(s => s.isPending).length;
|
|
2979
|
-
const completed = states.filter(s => !s.isPending && s.data !== undefined).length;
|
|
2980
|
-
const failed = states.filter(s => !s.isPending && s.error !== undefined).length;
|
|
2981
|
-
const percent = total > 0 ? Math.round(((completed + failed) / total) * 100) : 0;
|
|
2982
|
-
return { total, pending, completed, failed, percent };
|
|
2983
|
-
}
|
|
2984
|
-
|
|
2985
|
-
var DataType;
|
|
2986
|
-
(function (DataType) {
|
|
2987
|
-
DataType[DataType["ANY"] = 0] = "ANY";
|
|
2988
|
-
DataType[DataType["ARRAY"] = 1] = "ARRAY";
|
|
2989
|
-
DataType[DataType["OBJECT"] = 2] = "OBJECT";
|
|
2990
|
-
})(DataType || (DataType = {}));
|
|
2991
|
-
|
|
2992
|
-
class ConfigHTTPOptions {
|
|
2993
|
-
constructor(server = '', path, headers, polling, retry, stream, displayError, displaySuccess) {
|
|
2994
|
-
this.server = server;
|
|
2995
|
-
this.path = path;
|
|
2996
|
-
this.headers = headers;
|
|
2997
|
-
this.polling = polling;
|
|
2998
|
-
this.retry = retry;
|
|
2999
|
-
this.stream = stream;
|
|
3000
|
-
this.displayError = displayError;
|
|
3001
|
-
this.displaySuccess = displaySuccess;
|
|
3002
|
-
}
|
|
3003
|
-
static adapt(item) {
|
|
3004
|
-
const server = Array.isArray(item?.server) ? item.server.join('/') : item?.server || '';
|
|
3005
|
-
const retryOptions = item?.retry ? RetryOptions.adapt(item.retry) : RetryOptions.adapt();
|
|
3006
|
-
return new ConfigHTTPOptions(server, (item?.path) ? item.path : [], (item?.headers) ? item.headers : {}, item?.polling ? Math.floor(item.polling) : 0, retryOptions, (item?.stream) ? item.stream : false, (item?.displayError) ? item.displayError : false, (item?.displaySuccess) ? item.displaySuccess : false);
|
|
3007
|
-
}
|
|
3008
|
-
}
|
|
3009
|
-
|
|
3010
|
-
class LocalStorageOptions {
|
|
3011
|
-
constructor(storageName, storageSettingsName, options) {
|
|
3012
|
-
this.storageName = storageName;
|
|
3013
|
-
this.storageSettingsName = storageSettingsName;
|
|
3014
|
-
this.options = options;
|
|
3015
|
-
}
|
|
3016
|
-
static adapt(item) {
|
|
3017
|
-
return new LocalStorageOptions((item?.storageName) ? item.storageName : 'storage', (item?.storageSettingsName) ? item.storageSettingsName : 'global-storage', (item?.options) ? SettingOptions.adapt(item.options) : SettingOptions.adapt());
|
|
3018
|
-
}
|
|
3019
|
-
}
|
|
3020
|
-
|
|
3021
|
-
class ConfigOptions {
|
|
3022
|
-
constructor(httpRequestOptions, LocalStorageOptions) {
|
|
3023
|
-
this.httpRequestOptions = httpRequestOptions;
|
|
3024
|
-
this.LocalStorageOptions = LocalStorageOptions;
|
|
3025
|
-
}
|
|
3026
|
-
static adapt(item) {
|
|
3027
|
-
return new ConfigOptions((item?.httpRequestOptions) ? ConfigHTTPOptions.adapt(item.httpRequestOptions) : undefined, (item?.LocalStorageOptions) ? LocalStorageOptions.adapt(item.LocalStorageOptions) : undefined);
|
|
3028
|
-
}
|
|
3029
|
-
}
|
|
3030
|
-
|
|
3031
|
-
class UserData {
|
|
3032
|
-
constructor(ldap = '', name = '', email = '', color = RandomPaletteColor()) {
|
|
3033
|
-
this.ldap = ldap;
|
|
3034
|
-
this.name = name;
|
|
3035
|
-
this.email = email;
|
|
3036
|
-
this.color = color;
|
|
3037
|
-
}
|
|
3038
|
-
static adapt(item) {
|
|
3039
|
-
const userName = `${item?.first_name} ${item?.last_name}`;
|
|
3040
|
-
return new UserData(item?.ldap, userName, item?.email, item?.color);
|
|
3041
|
-
}
|
|
3042
|
-
}
|
|
3043
|
-
|
|
3044
3149
|
/**
|
|
3045
3150
|
* Message Tracker Service - Guaranteed Message Delivery
|
|
3046
3151
|
*
|
|
@@ -3695,6 +3800,24 @@ class HTTPManagerService extends RequestService {
|
|
|
3695
3800
|
return this.handleError(err);
|
|
3696
3801
|
}));
|
|
3697
3802
|
}
|
|
3803
|
+
uploadRequest(files, options, params) {
|
|
3804
|
+
this.isPending.next(true);
|
|
3805
|
+
this.data.next(null);
|
|
3806
|
+
const updatedOptions = this.defineReqOptions(options, params);
|
|
3807
|
+
updatedOptions.uploadFiles = files;
|
|
3808
|
+
const func = this.uploadFileRequest;
|
|
3809
|
+
const requests = this.createRequest(func, updatedOptions);
|
|
3810
|
+
return this.createObservable(updatedOptions, requests, func.name).pipe(tap(data => {
|
|
3811
|
+
this.data.next(data);
|
|
3812
|
+
if (updatedOptions.displaySuccess)
|
|
3813
|
+
this.handleSuccessWithSnackBar(updatedOptions.successMessage);
|
|
3814
|
+
}), finalize(() => this.isPending.next(false)), catchError((err) => {
|
|
3815
|
+
if (updatedOptions.displayError)
|
|
3816
|
+
this.handleErrorWithSnackBar(err, updatedOptions.errorMessage || err?.message);
|
|
3817
|
+
this.isPending.next(false);
|
|
3818
|
+
return this.handleError(err);
|
|
3819
|
+
}));
|
|
3820
|
+
}
|
|
3698
3821
|
createObservable(options, request$, funcName) {
|
|
3699
3822
|
const polling = options.polling ? (options.polling > 0 ? true : false) : false;
|
|
3700
3823
|
const isPolling = polling &&
|
|
@@ -4084,6 +4207,89 @@ class RequestSignalsService extends WebsocketService {
|
|
|
4084
4207
|
return throwError(() => err);
|
|
4085
4208
|
}));
|
|
4086
4209
|
}
|
|
4210
|
+
uploadFileRequest(options) {
|
|
4211
|
+
this.isPending.set(true);
|
|
4212
|
+
const files = options.uploadFiles ? (Array.isArray(options.uploadFiles) ? options.uploadFiles : [options.uploadFiles]) : [];
|
|
4213
|
+
const validation = this.validateUploadFiles(files, options);
|
|
4214
|
+
if (validation.validFiles.length === 0) {
|
|
4215
|
+
this.isPending.set(false);
|
|
4216
|
+
return throwError(() => new UploadValidationErrorModel(validation.invalidFiles, 0, files.length));
|
|
4217
|
+
}
|
|
4218
|
+
const fieldName = options.uploadFieldName || (files.length === 1 ? 'file' : 'files');
|
|
4219
|
+
const formData = this.buildFormData(validation.validFiles, fieldName);
|
|
4220
|
+
const urlPath = this.buildUrlPath(options);
|
|
4221
|
+
const method = options.uploadHttpMethod || 'POST';
|
|
4222
|
+
return this.http.request(method, urlPath, {
|
|
4223
|
+
body: formData,
|
|
4224
|
+
observe: 'events',
|
|
4225
|
+
reportProgress: true
|
|
4226
|
+
}).pipe(map((event) => {
|
|
4227
|
+
this.isPending.set(true);
|
|
4228
|
+
switch (event.type) {
|
|
4229
|
+
case HttpEventType.UploadProgress:
|
|
4230
|
+
const status = event.total ? Math.round(event.loaded / (event.total || 1) * 100) : 0;
|
|
4231
|
+
this.progress.set(status);
|
|
4232
|
+
return null;
|
|
4233
|
+
case HttpEventType.Response:
|
|
4234
|
+
this.isPending.set(false);
|
|
4235
|
+
this.progress.set(0);
|
|
4236
|
+
return event.body;
|
|
4237
|
+
default:
|
|
4238
|
+
return null;
|
|
4239
|
+
}
|
|
4240
|
+
}), filter((body) => body !== null), catchError(err => {
|
|
4241
|
+
this.isPending.set(false);
|
|
4242
|
+
this.progress.set(0);
|
|
4243
|
+
return throwError(() => err);
|
|
4244
|
+
}));
|
|
4245
|
+
}
|
|
4246
|
+
validateUploadFiles(files, options) {
|
|
4247
|
+
const validFiles = [];
|
|
4248
|
+
const invalidFiles = [];
|
|
4249
|
+
let totalSize = 0;
|
|
4250
|
+
for (const file of files) {
|
|
4251
|
+
const errors = [];
|
|
4252
|
+
if (options.allowedTypes && options.allowedTypes.length > 0) {
|
|
4253
|
+
const isAllowed = options.allowedTypes.some(type => {
|
|
4254
|
+
if (type.endsWith('/*')) {
|
|
4255
|
+
return file.type.startsWith(type.replace('/*', '/'));
|
|
4256
|
+
}
|
|
4257
|
+
return file.type === type;
|
|
4258
|
+
});
|
|
4259
|
+
if (!isAllowed) {
|
|
4260
|
+
errors.push('type not allowed');
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4263
|
+
const maxFileSize = options.maxFileSize !== undefined ? options.maxFileSize : Infinity;
|
|
4264
|
+
if (file.size > maxFileSize) {
|
|
4265
|
+
errors.push('exceeds maxFileSize');
|
|
4266
|
+
}
|
|
4267
|
+
if (errors.length > 0) {
|
|
4268
|
+
invalidFiles.push(new InvalidFileInfoModel(file.name, file.size, file.type, errors));
|
|
4269
|
+
}
|
|
4270
|
+
else {
|
|
4271
|
+
validFiles.push(file);
|
|
4272
|
+
totalSize += file.size;
|
|
4273
|
+
}
|
|
4274
|
+
}
|
|
4275
|
+
const maxTotalSize = options.maxTotalSize !== undefined ? options.maxTotalSize : Infinity;
|
|
4276
|
+
if (totalSize > maxTotalSize) {
|
|
4277
|
+
return {
|
|
4278
|
+
validFiles: [],
|
|
4279
|
+
invalidFiles: [
|
|
4280
|
+
new InvalidFileInfoModel('total', totalSize, '', ['exceeds maxTotalSize'])
|
|
4281
|
+
]
|
|
4282
|
+
};
|
|
4283
|
+
}
|
|
4284
|
+
return { validFiles, invalidFiles };
|
|
4285
|
+
}
|
|
4286
|
+
buildFormData(files, fieldName) {
|
|
4287
|
+
const formData = new FormData();
|
|
4288
|
+
files.forEach((file, index) => {
|
|
4289
|
+
formData.append(`${fieldName}[${index}]`, file);
|
|
4290
|
+
});
|
|
4291
|
+
return formData;
|
|
4292
|
+
}
|
|
4087
4293
|
handleFinalize() {
|
|
4088
4294
|
return finalize(() => this.isPending.set(false));
|
|
4089
4295
|
}
|
|
@@ -4378,6 +4584,24 @@ class HTTPManagerSignalsService extends RequestSignalsService {
|
|
|
4378
4584
|
return this.handleError(err);
|
|
4379
4585
|
}));
|
|
4380
4586
|
}
|
|
4587
|
+
uploadRequest(files, options, params) {
|
|
4588
|
+
this.isPending.set(true);
|
|
4589
|
+
this.data.set(null);
|
|
4590
|
+
const updatedOptions = this.defineReqOptions(options, params);
|
|
4591
|
+
updatedOptions.uploadFiles = files;
|
|
4592
|
+
const func = this.uploadFileRequest;
|
|
4593
|
+
const requests = this.createRequest(func, updatedOptions);
|
|
4594
|
+
return this.createObservable(updatedOptions, requests, func.name).pipe(tap(data => {
|
|
4595
|
+
this.data.set(data);
|
|
4596
|
+
if (updatedOptions.displaySuccess)
|
|
4597
|
+
this.handleSuccessWithSnackBar(updatedOptions.successMessage);
|
|
4598
|
+
}), finalize(() => this.isPending.set(false)), catchError((err) => {
|
|
4599
|
+
if (updatedOptions.displayError)
|
|
4600
|
+
this.handleErrorWithSnackBar(err, updatedOptions.errorMessage || err?.message);
|
|
4601
|
+
this.isPending.set(false);
|
|
4602
|
+
return this.handleError(err);
|
|
4603
|
+
}));
|
|
4604
|
+
}
|
|
4381
4605
|
// --- private helpers ---
|
|
4382
4606
|
createObservable(options, request$, funcName) {
|
|
4383
4607
|
const polling = options.polling ? (options.polling > 0 ? true : false) : false;
|
|
@@ -4635,7 +4859,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4635
4859
|
}] }] });
|
|
4636
4860
|
|
|
4637
4861
|
class ApiRequest {
|
|
4638
|
-
constructor(server = '', path, headers, adapter, mapper, polling, retry, stream, streamType, displayError, displaySuccess, successMessage, errorMessage, saveAs, fileContentHeader, ws, env) {
|
|
4862
|
+
constructor(server = '', path, headers, adapter, mapper, polling, retry, stream, streamType, displayError, displaySuccess, successMessage, errorMessage, saveAs, fileContentHeader, ws, env, uploadFiles, uploadFieldName, uploadHttpMethod, allowedTypes, maxFileSize, maxTotalSize) {
|
|
4639
4863
|
this.server = server;
|
|
4640
4864
|
this.path = path;
|
|
4641
4865
|
this.headers = headers;
|
|
@@ -4653,10 +4877,16 @@ class ApiRequest {
|
|
|
4653
4877
|
this.fileContentHeader = fileContentHeader;
|
|
4654
4878
|
this.ws = ws;
|
|
4655
4879
|
this.env = env;
|
|
4880
|
+
this.uploadFiles = uploadFiles;
|
|
4881
|
+
this.uploadFieldName = uploadFieldName;
|
|
4882
|
+
this.uploadHttpMethod = uploadHttpMethod;
|
|
4883
|
+
this.allowedTypes = allowedTypes;
|
|
4884
|
+
this.maxFileSize = maxFileSize;
|
|
4885
|
+
this.maxTotalSize = maxTotalSize;
|
|
4656
4886
|
}
|
|
4657
4887
|
static adapt(item) {
|
|
4658
4888
|
const server = Array.isArray(item?.server) ? item.server.join('/') : item?.server || '';
|
|
4659
|
-
return new ApiRequest(server, item?.path ? item.path : [], item?.headers ? item.headers : {}, item?.adapter, item?.mapper, item?.polling ? Math.floor(item.polling) : 0, item?.retry ? RetryOptions.adapt(item.retry) : RetryOptions.adapt(), item?.stream ? item.stream : false, item?.streamType || StreamType.AI_STREAMING, item?.displayError ? item.displayError : false, item?.displaySuccess ? item.displaySuccess : false, item?.successMessage, item?.errorMessage, item?.saveAs, item?.fileContentHeader, item?.ws, item?.env || 'dev');
|
|
4889
|
+
return new ApiRequest(server, item?.path ? item.path : [], item?.headers ? item.headers : {}, item?.adapter, item?.mapper, item?.polling ? Math.floor(item.polling) : 0, item?.retry ? RetryOptions.adapt(item.retry) : RetryOptions.adapt(), item?.stream ? item.stream : false, item?.streamType || StreamType.AI_STREAMING, item?.displayError ? item.displayError : false, item?.displaySuccess ? item.displaySuccess : false, item?.successMessage, item?.errorMessage, item?.saveAs, item?.fileContentHeader, item?.ws, item?.env || 'dev', item?.uploadFiles, item?.uploadFieldName, item?.uploadHttpMethod, Array.isArray(item?.allowedTypes) ? item.allowedTypes : [], item?.maxFileSize, item?.maxTotalSize);
|
|
4660
4890
|
}
|
|
4661
4891
|
}
|
|
4662
4892
|
|
|
@@ -7235,9 +7465,11 @@ class RequestHeadersInterceptor {
|
|
|
7235
7465
|
}));
|
|
7236
7466
|
}
|
|
7237
7467
|
intercept(request, next) {
|
|
7468
|
+
// Don't override Content-Type for FormData (file uploads) — let browser set multipart/form-data
|
|
7469
|
+
const skipContentType = request.body instanceof FormData;
|
|
7238
7470
|
request = request.clone({
|
|
7239
7471
|
setHeaders: {
|
|
7240
|
-
'Content-Type': 'application/json',
|
|
7472
|
+
...(skipContentType ? {} : { 'Content-Type': 'application/json' }),
|
|
7241
7473
|
'Accept-Language': this.language || 'en-CA',
|
|
7242
7474
|
'Current-Date': this.currentDate
|
|
7243
7475
|
}
|
|
@@ -10387,6 +10619,133 @@ class DatabaseDataSource extends DataSource {
|
|
|
10387
10619
|
}
|
|
10388
10620
|
}
|
|
10389
10621
|
|
|
10622
|
+
class UploadStateModel {
|
|
10623
|
+
constructor(selectedFiles = [], isUploading = false, progress = 0, currentFile = null, errorMessage = null, successMessage = null) {
|
|
10624
|
+
this.selectedFiles = selectedFiles;
|
|
10625
|
+
this.isUploading = isUploading;
|
|
10626
|
+
this.progress = progress;
|
|
10627
|
+
this.currentFile = currentFile;
|
|
10628
|
+
this.errorMessage = errorMessage;
|
|
10629
|
+
this.successMessage = successMessage;
|
|
10630
|
+
}
|
|
10631
|
+
static adapt(item) {
|
|
10632
|
+
return new UploadStateModel(Array.isArray(item?.selectedFiles) ? item.selectedFiles : [], item?.isUploading ?? false, item?.progress ?? 0, item?.currentFile ?? null, item?.errorMessage ?? null, item?.successMessage ?? null);
|
|
10633
|
+
}
|
|
10634
|
+
}
|
|
10635
|
+
|
|
10636
|
+
class UploadDemoComponent {
|
|
10637
|
+
constructor() {
|
|
10638
|
+
this.httpManager = inject(HTTPManagerService);
|
|
10639
|
+
this.toastService = inject(ToastMessageDisplayService);
|
|
10640
|
+
this.uploadState = UploadStateModel.adapt();
|
|
10641
|
+
this.allowedTypes = ['image/jpeg', 'image/png'];
|
|
10642
|
+
this.maxFileSize = 40 * 1024 * 1024; // 40MB
|
|
10643
|
+
}
|
|
10644
|
+
ngOnInit() {
|
|
10645
|
+
// Initialize component
|
|
10646
|
+
}
|
|
10647
|
+
ngOnDestroy() {
|
|
10648
|
+
// Clean up subscriptions
|
|
10649
|
+
}
|
|
10650
|
+
onFileSelected(event) {
|
|
10651
|
+
const input = event.target;
|
|
10652
|
+
const files = input.files;
|
|
10653
|
+
if (!files || files.length === 0) {
|
|
10654
|
+
return;
|
|
10655
|
+
}
|
|
10656
|
+
this.uploadState.selectedFiles = [];
|
|
10657
|
+
this.uploadState.errorMessage = null;
|
|
10658
|
+
for (let i = 0; i < files.length; i++) {
|
|
10659
|
+
const file = files[i];
|
|
10660
|
+
const validationError = this.validateFile(file);
|
|
10661
|
+
if (validationError) {
|
|
10662
|
+
this.uploadState.errorMessage = validationError;
|
|
10663
|
+
continue;
|
|
10664
|
+
}
|
|
10665
|
+
this.uploadState.selectedFiles.push(file);
|
|
10666
|
+
}
|
|
10667
|
+
if (this.uploadState.selectedFiles.length === 0 && !this.uploadState.errorMessage) {
|
|
10668
|
+
this.uploadState.errorMessage = 'Please select at least one valid file (JPG or PNG)';
|
|
10669
|
+
}
|
|
10670
|
+
}
|
|
10671
|
+
validateFile(file) {
|
|
10672
|
+
// Check file type
|
|
10673
|
+
if (!this.allowedTypes.includes(file.type)) {
|
|
10674
|
+
return `File "${file.name}" is not a valid type. Only JPG and PNG files are allowed.`;
|
|
10675
|
+
}
|
|
10676
|
+
// Check file size
|
|
10677
|
+
if (file.size > this.maxFileSize) {
|
|
10678
|
+
return `File "${file.name}" exceeds maximum size of 10MB.`;
|
|
10679
|
+
}
|
|
10680
|
+
return null;
|
|
10681
|
+
}
|
|
10682
|
+
clearSelection() {
|
|
10683
|
+
this.uploadState.selectedFiles = [];
|
|
10684
|
+
this.uploadState.errorMessage = null;
|
|
10685
|
+
this.uploadState.successMessage = null;
|
|
10686
|
+
this.uploadState.progress = 0;
|
|
10687
|
+
this.uploadState.currentFile = null;
|
|
10688
|
+
}
|
|
10689
|
+
startUpload() {
|
|
10690
|
+
if (this.uploadState.selectedFiles.length === 0) {
|
|
10691
|
+
this.uploadState.errorMessage = 'Please select at least one file to upload';
|
|
10692
|
+
return;
|
|
10693
|
+
}
|
|
10694
|
+
if (this.uploadState.errorMessage) {
|
|
10695
|
+
return;
|
|
10696
|
+
}
|
|
10697
|
+
this.uploadState.isUploading = true;
|
|
10698
|
+
this.uploadState.progress = 0;
|
|
10699
|
+
this.uploadState.errorMessage = null;
|
|
10700
|
+
this.uploadState.successMessage = null;
|
|
10701
|
+
const options = ApiRequest.adapt({
|
|
10702
|
+
server: 'gtlcApi',
|
|
10703
|
+
path: ['uploader'],
|
|
10704
|
+
uploadFieldName: 'files',
|
|
10705
|
+
allowedTypes: this.allowedTypes,
|
|
10706
|
+
maxFileSize: this.maxFileSize
|
|
10707
|
+
});
|
|
10708
|
+
this.httpManager.uploadRequest(this.uploadState.selectedFiles, options, ['upload'])
|
|
10709
|
+
.subscribe({
|
|
10710
|
+
next: (response) => {
|
|
10711
|
+
this.uploadState.progress = 100;
|
|
10712
|
+
this.uploadState.successMessage = `Successfully uploaded ${this.uploadState.selectedFiles.length} file(s)`;
|
|
10713
|
+
this.toastService.toastMessage({
|
|
10714
|
+
message: this.uploadState.successMessage || '',
|
|
10715
|
+
color: ToastColors.SUCCESS
|
|
10716
|
+
});
|
|
10717
|
+
this.uploadState.isUploading = false;
|
|
10718
|
+
},
|
|
10719
|
+
error: (error) => {
|
|
10720
|
+
this.uploadState.errorMessage = error.message || 'Upload failed. Please try again.';
|
|
10721
|
+
this.toastService.toastMessage({
|
|
10722
|
+
message: this.uploadState.errorMessage || '',
|
|
10723
|
+
color: ToastColors.ERROR
|
|
10724
|
+
});
|
|
10725
|
+
this.uploadState.isUploading = false;
|
|
10726
|
+
this.uploadState.progress = 0;
|
|
10727
|
+
}
|
|
10728
|
+
});
|
|
10729
|
+
}
|
|
10730
|
+
getFileSizeString(size) {
|
|
10731
|
+
if (size < 1024) {
|
|
10732
|
+
return `${size} bytes`;
|
|
10733
|
+
}
|
|
10734
|
+
else if (size < 1024 * 1024) {
|
|
10735
|
+
return `${(size / 1024).toFixed(1)} KB`;
|
|
10736
|
+
}
|
|
10737
|
+
else {
|
|
10738
|
+
return `${(size / (1024 * 1024)).toFixed(1)} MB`;
|
|
10739
|
+
}
|
|
10740
|
+
}
|
|
10741
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UploadDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10742
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: UploadDemoComponent, selector: "lib-upload-demo", ngImport: i0, template: "<div class=\"upload-demo-container\">\n <h2>File Upload Demo</h2>\n <p class=\"demo-description\">Upload multiple JPG or PNG files with progress tracking</p>\n\n <!-- Upload Button & File Input -->\n <div class=\"upload-controls\">\n <button\n mat-raised-button\n color=\"primary\"\n (click)=\"fileInput.click()\"\n [disabled]=\"uploadState.isUploading\"\n class=\"upload-button\">\n <span class=\"material-icons\">upload_file</span>\n Select Files\n </button>\n <input\n #fileInput\n type=\"file\"\n multiple\n accept=\"image/jpeg,image/png\"\n (change)=\"onFileSelected($event)\"\n [disabled]=\"uploadState.isUploading\"\n hidden>\n\n <button\n mat-button\n color=\"warn\"\n (click)=\"clearSelection()\"\n [disabled]=\"uploadState.selectedFiles.length === 0 || uploadState.isUploading\"\n class=\"clear-button\">\n Clear\n </button>\n </div>\n\n <!-- Selected Files Display -->\n <div class=\"selected-files\" *ngIf=\"uploadState.selectedFiles.length > 0\">\n <h3>Selected Files ({{uploadState.selectedFiles.length}})</h3>\n <ul class=\"file-list\">\n <li *ngFor=\"let file of uploadState.selectedFiles\" class=\"file-item\">\n <span class=\"file-icon\">\n <span class=\"material-icons\">insert_drive_file</span>\n </span>\n <span class=\"file-name\">{{file.name}}</span>\n <span class=\"file-size\">{{getFileSizeString(file.size)}}</span>\n <span class=\"file-status valid\">\u2713</span>\n </li>\n </ul>\n </div>\n\n <!-- Validation Errors -->\n <div class=\"error-message\" *ngIf=\"uploadState.errorMessage && !uploadState.isUploading\">\n <span class=\"material-icons\">error</span>\n <span>{{uploadState.errorMessage}}</span>\n </div>\n\n <!-- Progress Bar -->\n <div class=\"progress-container\" *ngIf=\"uploadState.isUploading\">\n <div class=\"progress-header\">\n <span>Uploading...</span>\n <span class=\"progress-percentage\">{{uploadState.progress}}%</span>\n </div>\n <mat-progress-bar\n mode=\"determinate\"\n [value]=\"uploadState.progress\"\n color=\"primary\">\n </mat-progress-bar>\n <div class=\"current-file\" *ngIf=\"uploadState.currentFile\">\n Current: {{uploadState.currentFile}}\n </div>\n </div>\n\n <!-- Success Message -->\n <div class=\"success-message\" *ngIf=\"uploadState.successMessage\">\n <span class=\"material-icons\">check_circle</span>\n <span>{{uploadState.successMessage}}</span>\n </div>\n\n <!-- Upload Action Button -->\n <div class=\"upload-actions\" *ngIf=\"uploadState.selectedFiles.length > 0 && !uploadState.isUploading\">\n <button\n mat-raised-button\n color=\"primary\"\n (click)=\"startUpload()\"\n [disabled]=\"uploadState.selectedFiles.length === 0 || uploadState.errorMessage !== null\"\n class=\"start-upload-button\">\n Upload {{uploadState.selectedFiles.length}} File{{uploadState.selectedFiles.length > 1 ? 's' : ''}}\n </button>\n </div>\n</div>\n", styles: [".upload-demo-container{padding:1rem;max-width:60rem;margin:0 auto}.upload-demo-container h2{font-size:2rem;font-weight:700;color:#333;margin-bottom:.75rem}.upload-demo-container .demo-description{font-size:1rem;color:#666;margin-bottom:1.5rem}.upload-demo-container .upload-controls{display:flex;gap:1rem;margin-bottom:1.5rem;align-items:center}.upload-demo-container .upload-controls .upload-button,.upload-demo-container .upload-controls .clear-button{min-width:10rem}.upload-demo-container .selected-files{background-color:#fbfbfb;border:1px solid #ccc;border-radius:.25rem;padding:1rem;margin-bottom:1.5rem}.upload-demo-container .selected-files h3{font-size:1.125rem;font-weight:500;color:#333;margin-bottom:.5rem}.upload-demo-container .selected-files .file-list{list-style:none;padding:0;margin:0}.upload-demo-container .selected-files .file-list .file-item{display:flex;align-items:center;gap:.5rem;padding:.25rem 0;border-bottom:1px solid #e5e5e5}.upload-demo-container .selected-files .file-list .file-item:last-child{border-bottom:none}.upload-demo-container .selected-files .file-list .file-item .file-icon{color:#286fad;display:flex;align-items:center}.upload-demo-container .selected-files .file-list .file-item .file-name{flex:1;font-size:.875rem;color:#333;font-weight:500}.upload-demo-container .selected-files .file-list .file-item .file-size{font-size:.875rem;color:#666}.upload-demo-container .selected-files .file-list .file-item .file-status.valid{color:#1c8150;font-weight:700}.upload-demo-container .error-message{display:flex;align-items:center;gap:.5rem;padding:1rem;background-color:#d400031a;border:1px solid #d40003;border-radius:.25rem;color:#d40003;margin-bottom:1.5rem;font-size:.875rem}.upload-demo-container .error-message .material-icons{font-size:2.5rem}.upload-demo-container .progress-container{margin-bottom:1.5rem}.upload-demo-container .progress-container .progress-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.25rem}.upload-demo-container .progress-container .progress-header span:first-child{font-size:.875rem;font-weight:500;color:#333}.upload-demo-container .progress-container .progress-header .progress-percentage{font-size:.875rem;font-weight:700;color:#286fad}.upload-demo-container .progress-container .current-file{font-size:.875rem;color:#666;margin-top:.25rem;font-style:italic}.upload-demo-container .success-message{display:flex;align-items:center;gap:.5rem;padding:1rem;background-color:#1c81501a;border:1px solid #1c8150;border-radius:.25rem;color:#1c8150;margin-bottom:1.5rem;font-size:.875rem}.upload-demo-container .success-message .material-icons{font-size:2.5rem}.upload-demo-container .upload-actions{text-align:center;margin-top:1.5rem}.upload-demo-container .upload-actions .start-upload-button{min-width:15rem;padding:.5rem 1.5rem}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i8$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }] }); }
|
|
10743
|
+
}
|
|
10744
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UploadDemoComponent, decorators: [{
|
|
10745
|
+
type: Component,
|
|
10746
|
+
args: [{ selector: 'lib-upload-demo', standalone: false, template: "<div class=\"upload-demo-container\">\n <h2>File Upload Demo</h2>\n <p class=\"demo-description\">Upload multiple JPG or PNG files with progress tracking</p>\n\n <!-- Upload Button & File Input -->\n <div class=\"upload-controls\">\n <button\n mat-raised-button\n color=\"primary\"\n (click)=\"fileInput.click()\"\n [disabled]=\"uploadState.isUploading\"\n class=\"upload-button\">\n <span class=\"material-icons\">upload_file</span>\n Select Files\n </button>\n <input\n #fileInput\n type=\"file\"\n multiple\n accept=\"image/jpeg,image/png\"\n (change)=\"onFileSelected($event)\"\n [disabled]=\"uploadState.isUploading\"\n hidden>\n\n <button\n mat-button\n color=\"warn\"\n (click)=\"clearSelection()\"\n [disabled]=\"uploadState.selectedFiles.length === 0 || uploadState.isUploading\"\n class=\"clear-button\">\n Clear\n </button>\n </div>\n\n <!-- Selected Files Display -->\n <div class=\"selected-files\" *ngIf=\"uploadState.selectedFiles.length > 0\">\n <h3>Selected Files ({{uploadState.selectedFiles.length}})</h3>\n <ul class=\"file-list\">\n <li *ngFor=\"let file of uploadState.selectedFiles\" class=\"file-item\">\n <span class=\"file-icon\">\n <span class=\"material-icons\">insert_drive_file</span>\n </span>\n <span class=\"file-name\">{{file.name}}</span>\n <span class=\"file-size\">{{getFileSizeString(file.size)}}</span>\n <span class=\"file-status valid\">\u2713</span>\n </li>\n </ul>\n </div>\n\n <!-- Validation Errors -->\n <div class=\"error-message\" *ngIf=\"uploadState.errorMessage && !uploadState.isUploading\">\n <span class=\"material-icons\">error</span>\n <span>{{uploadState.errorMessage}}</span>\n </div>\n\n <!-- Progress Bar -->\n <div class=\"progress-container\" *ngIf=\"uploadState.isUploading\">\n <div class=\"progress-header\">\n <span>Uploading...</span>\n <span class=\"progress-percentage\">{{uploadState.progress}}%</span>\n </div>\n <mat-progress-bar\n mode=\"determinate\"\n [value]=\"uploadState.progress\"\n color=\"primary\">\n </mat-progress-bar>\n <div class=\"current-file\" *ngIf=\"uploadState.currentFile\">\n Current: {{uploadState.currentFile}}\n </div>\n </div>\n\n <!-- Success Message -->\n <div class=\"success-message\" *ngIf=\"uploadState.successMessage\">\n <span class=\"material-icons\">check_circle</span>\n <span>{{uploadState.successMessage}}</span>\n </div>\n\n <!-- Upload Action Button -->\n <div class=\"upload-actions\" *ngIf=\"uploadState.selectedFiles.length > 0 && !uploadState.isUploading\">\n <button\n mat-raised-button\n color=\"primary\"\n (click)=\"startUpload()\"\n [disabled]=\"uploadState.selectedFiles.length === 0 || uploadState.errorMessage !== null\"\n class=\"start-upload-button\">\n Upload {{uploadState.selectedFiles.length}} File{{uploadState.selectedFiles.length > 1 ? 's' : ''}}\n </button>\n </div>\n</div>\n", styles: [".upload-demo-container{padding:1rem;max-width:60rem;margin:0 auto}.upload-demo-container h2{font-size:2rem;font-weight:700;color:#333;margin-bottom:.75rem}.upload-demo-container .demo-description{font-size:1rem;color:#666;margin-bottom:1.5rem}.upload-demo-container .upload-controls{display:flex;gap:1rem;margin-bottom:1.5rem;align-items:center}.upload-demo-container .upload-controls .upload-button,.upload-demo-container .upload-controls .clear-button{min-width:10rem}.upload-demo-container .selected-files{background-color:#fbfbfb;border:1px solid #ccc;border-radius:.25rem;padding:1rem;margin-bottom:1.5rem}.upload-demo-container .selected-files h3{font-size:1.125rem;font-weight:500;color:#333;margin-bottom:.5rem}.upload-demo-container .selected-files .file-list{list-style:none;padding:0;margin:0}.upload-demo-container .selected-files .file-list .file-item{display:flex;align-items:center;gap:.5rem;padding:.25rem 0;border-bottom:1px solid #e5e5e5}.upload-demo-container .selected-files .file-list .file-item:last-child{border-bottom:none}.upload-demo-container .selected-files .file-list .file-item .file-icon{color:#286fad;display:flex;align-items:center}.upload-demo-container .selected-files .file-list .file-item .file-name{flex:1;font-size:.875rem;color:#333;font-weight:500}.upload-demo-container .selected-files .file-list .file-item .file-size{font-size:.875rem;color:#666}.upload-demo-container .selected-files .file-list .file-item .file-status.valid{color:#1c8150;font-weight:700}.upload-demo-container .error-message{display:flex;align-items:center;gap:.5rem;padding:1rem;background-color:#d400031a;border:1px solid #d40003;border-radius:.25rem;color:#d40003;margin-bottom:1.5rem;font-size:.875rem}.upload-demo-container .error-message .material-icons{font-size:2.5rem}.upload-demo-container .progress-container{margin-bottom:1.5rem}.upload-demo-container .progress-container .progress-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.25rem}.upload-demo-container .progress-container .progress-header span:first-child{font-size:.875rem;font-weight:500;color:#333}.upload-demo-container .progress-container .progress-header .progress-percentage{font-size:.875rem;font-weight:700;color:#286fad}.upload-demo-container .progress-container .current-file{font-size:.875rem;color:#666;margin-top:.25rem;font-style:italic}.upload-demo-container .success-message{display:flex;align-items:center;gap:.5rem;padding:1rem;background-color:#1c81501a;border:1px solid #1c8150;border-radius:.25rem;color:#1c8150;margin-bottom:1.5rem;font-size:.875rem}.upload-demo-container .success-message .material-icons{font-size:2.5rem}.upload-demo-container .upload-actions{text-align:center;margin-top:1.5rem}.upload-demo-container .upload-actions .start-upload-button{min-width:15rem;padding:.5rem 1.5rem}\n"] }]
|
|
10747
|
+
}] });
|
|
10748
|
+
|
|
10390
10749
|
class HttpRequestServicesDemoComponent {
|
|
10391
10750
|
constructor(configOptions) {
|
|
10392
10751
|
this.configOptions = configOptions;
|
|
@@ -10399,6 +10758,7 @@ class HttpRequestServicesDemoComponent {
|
|
|
10399
10758
|
// { name: "Http Signals Service", value: 'http_signals_service', new: true },
|
|
10400
10759
|
{ name: "Http State Service", value: 'http_state_service' },
|
|
10401
10760
|
{ name: "Http State Service - Websockets", value: 'http_state_service_ws', new: false },
|
|
10761
|
+
{ name: "File Upload Demo", value: 'file_upload_demo', new: true, divider: true },
|
|
10402
10762
|
{ name: "Database Service", value: 'database_service', divider: true, disabled: false },
|
|
10403
10763
|
{ name: "Local Storage Service", value: 'local_storage_service' },
|
|
10404
10764
|
// { name: "Local Signals Storage Service", value: 'local_storage_signals_service', new: true },
|
|
@@ -10415,11 +10775,11 @@ class HttpRequestServicesDemoComponent {
|
|
|
10415
10775
|
this.selectedService = this.requestTypes[type].value;
|
|
10416
10776
|
}
|
|
10417
10777
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HttpRequestServicesDemoComponent, deps: [{ token: CONFIG_SETTINGS_TOKEN }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10418
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: HttpRequestServicesDemoComponent, selector: "app-http-request-services-demo", inputs: { wsServer: "wsServer", jwtToken: "jwtToken", server: "server", user: "user", path: "path", adapter: "adapter", mapper: "mapper" }, ngImport: i0, template: "<mat-toolbar style=\"display:flex\">\n <div>Http Request Manager Services</div>\n <div style=\"flex:1\"></div>\n <button mat-stroked-button [matMenuTriggerFor]=\"menu\">Services</button>\n <mat-menu #menu=\"matMenu\">\n @for (type of requestTypes; track type; let i = $index) {\n @if (type?.divider) {\n <div\n style=\"margin-top: .5rem; margin-bottom: .5rem;\"\n >\n <mat-divider></mat-divider>\n </div>\n }\n <button\n mat-menu-item\n (click)=\"onSelected(i)\"\n [disabled]=\"type.disabled\"\n >\n {{ type.name }}\n </button>\n }\n\n </mat-menu>\n</mat-toolbar>\n\n<span>\n @switch (selectedService) {\n @case ('basic_http_service') {\n <p>\n <app-request-manager-basic-demo></app-request-manager-basic-demo>\n </p>\n }\n @case ('http_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-demo\n [server]=\"server\"\n [adapter]=\"adapter\"\n [mapper]=\"mapper\"\n ></app-request-manager-demo>\n </p>\n }\n <!-- <p *ngSwitchCase=\"'http_signals_service'\">\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-signals-manager-demo></app-request-signals-manager-demo>\n </p> -->\n @case ('http_state_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-state-demo\n [server]=\"server\"\n [adapter]=\"adapter\"\n [mapper]=\"mapper\"\n ></app-request-manager-state-demo>\n </p>\n }\n @case ('http_state_service_ws') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-ws-demo\n [server]=\"server\"\n [wsServer]=\"wsServer\"\n [jwtToken]=\"jwtToken\"\n [user]=\"user\"\n [path]=\"path\"\n ></app-request-manager-ws-demo>\n </p>\n }\n @case ('database_service') {\n <p>\n <app-database-data-demo></app-database-data-demo>\n </p>\n }\n @case ('local_storage_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-local-storage-demo></app-local-storage-demo>\n </p>\n }\n <!-- <p *ngSwitchCase=\"'local_storage_signals_service'\">\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-local-storage-signals-demo></app-local-storage-signals-demo>\n</p> -->\n@case ('store_state_manager') {\n <p>\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-store-state-manager-demo></app-store-state-manager-demo>\n </p>\n}\n@default {\n <p>\n Other\n </p>\n}\n}\n</span>\n\n<ng-template #HTTP_OPTIONS>\n @if (injectionOptions?.httpRequestOptions) {\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - HTTP Options</h3>\n {{ injectionOptions?.httpRequestOptions| json }}\n </div>\n }\n</ng-template>\n\n<ng-template #LOCAL_OPTIONS>\n @if (injectionOptions?.LocalStorageOptions) {\n <ng-container class=\"box\">\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - LocalStorage Options</h3>\n {{ injectionOptions?.LocalStorageOptions| json }}\n </div>\n </ng-container>\n }\n</ng-template>\n\n\n", styles: [".box{padding:1rem;background-color:#f5f5f5;border:thin gray solid;margin-top:1rem}\n"], dependencies: [{ kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i3$2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: RequestManagerBasicDemoComponent, selector: "app-request-manager-basic-demo" }, { kind: "component", type: RequestManagerStateDemoComponent, selector: "app-request-manager-state-demo", inputs: ["server", "adapter", "mapper"] }, { kind: "component", type: RequestManagerDemoComponent, selector: "app-request-manager-demo", inputs: ["server", "adapter", "mapper"] }, { kind: "component", type: LocalStorageDemoComponent, selector: "app-local-storage-demo" }, { kind: "component", type: RequestManagerWsDemoComponent, selector: "app-request-manager-ws-demo", inputs: ["server", "wsServer", "jwtToken", "user", "path"] }, { kind: "component", type: StoreStateManagerDemoComponent, selector: "app-store-state-manager-demo" }, { kind: "component", type: DatabaseDataDemoComponent, selector: "app-database-data-demo" }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] }); }
|
|
10778
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: HttpRequestServicesDemoComponent, selector: "app-http-request-services-demo", inputs: { wsServer: "wsServer", jwtToken: "jwtToken", server: "server", user: "user", path: "path", adapter: "adapter", mapper: "mapper" }, ngImport: i0, template: "<mat-toolbar style=\"display:flex\">\n <div>Http Request Manager Services</div>\n <div style=\"flex:1\"></div>\n <button mat-stroked-button [matMenuTriggerFor]=\"menu\">Services</button>\n <mat-menu #menu=\"matMenu\">\n @for (type of requestTypes; track type; let i = $index) {\n @if (type?.divider) {\n <div\n style=\"margin-top: .5rem; margin-bottom: .5rem;\"\n >\n <mat-divider></mat-divider>\n </div>\n }\n <button\n mat-menu-item\n (click)=\"onSelected(i)\"\n [disabled]=\"type.disabled\"\n >\n {{ type.name }}\n </button>\n }\n\n </mat-menu>\n</mat-toolbar>\n\n<span>\n @switch (selectedService) {\n @case ('basic_http_service') {\n <p>\n <app-request-manager-basic-demo></app-request-manager-basic-demo>\n </p>\n }\n @case ('http_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-demo\n [server]=\"server\"\n [adapter]=\"adapter\"\n [mapper]=\"mapper\"\n ></app-request-manager-demo>\n </p>\n }\n <!-- <p *ngSwitchCase=\"'http_signals_service'\">\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-signals-manager-demo></app-request-signals-manager-demo>\n </p> -->\n @case ('http_state_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-state-demo\n [server]=\"server\"\n [adapter]=\"adapter\"\n [mapper]=\"mapper\"\n ></app-request-manager-state-demo>\n </p>\n }\n @case ('http_state_service_ws') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-ws-demo\n [server]=\"server\"\n [wsServer]=\"wsServer\"\n [jwtToken]=\"jwtToken\"\n [user]=\"user\"\n [path]=\"path\"\n ></app-request-manager-ws-demo>\n </p>\n }\n @case ('file_upload_demo') {\n <p>\n <lib-upload-demo></lib-upload-demo>\n </p>\n }\n @case ('database_service') {\n <p>\n <app-database-data-demo></app-database-data-demo>\n </p>\n }\n @case ('local_storage_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-local-storage-demo></app-local-storage-demo>\n </p>\n }\n <!-- <p *ngSwitchCase=\"'local_storage_signals_service'\">\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-local-storage-signals-demo></app-local-storage-signals-demo>\n</p> -->\n@case ('store_state_manager') {\n <p>\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-store-state-manager-demo></app-store-state-manager-demo>\n </p>\n}\n@default {\n <p>\n Other\n </p>\n}\n}\n</span>\n\n<ng-template #HTTP_OPTIONS>\n @if (injectionOptions?.httpRequestOptions) {\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - HTTP Options</h3>\n {{ injectionOptions?.httpRequestOptions| json }}\n </div>\n }\n</ng-template>\n\n<ng-template #LOCAL_OPTIONS>\n @if (injectionOptions?.LocalStorageOptions) {\n <ng-container class=\"box\">\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - LocalStorage Options</h3>\n {{ injectionOptions?.LocalStorageOptions| json }}\n </div>\n </ng-container>\n }\n</ng-template>\n\n\n", styles: [".box{padding:1rem;background-color:#f5f5f5;border:thin gray solid;margin-top:1rem}\n"], dependencies: [{ kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i3$2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: RequestManagerBasicDemoComponent, selector: "app-request-manager-basic-demo" }, { kind: "component", type: RequestManagerStateDemoComponent, selector: "app-request-manager-state-demo", inputs: ["server", "adapter", "mapper"] }, { kind: "component", type: RequestManagerDemoComponent, selector: "app-request-manager-demo", inputs: ["server", "adapter", "mapper"] }, { kind: "component", type: LocalStorageDemoComponent, selector: "app-local-storage-demo" }, { kind: "component", type: RequestManagerWsDemoComponent, selector: "app-request-manager-ws-demo", inputs: ["server", "wsServer", "jwtToken", "user", "path"] }, { kind: "component", type: StoreStateManagerDemoComponent, selector: "app-store-state-manager-demo" }, { kind: "component", type: DatabaseDataDemoComponent, selector: "app-database-data-demo" }, { kind: "component", type: UploadDemoComponent, selector: "lib-upload-demo" }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] }); }
|
|
10419
10779
|
}
|
|
10420
10780
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HttpRequestServicesDemoComponent, decorators: [{
|
|
10421
10781
|
type: Component,
|
|
10422
|
-
args: [{ selector: 'app-http-request-services-demo', standalone: false, template: "<mat-toolbar style=\"display:flex\">\n <div>Http Request Manager Services</div>\n <div style=\"flex:1\"></div>\n <button mat-stroked-button [matMenuTriggerFor]=\"menu\">Services</button>\n <mat-menu #menu=\"matMenu\">\n @for (type of requestTypes; track type; let i = $index) {\n @if (type?.divider) {\n <div\n style=\"margin-top: .5rem; margin-bottom: .5rem;\"\n >\n <mat-divider></mat-divider>\n </div>\n }\n <button\n mat-menu-item\n (click)=\"onSelected(i)\"\n [disabled]=\"type.disabled\"\n >\n {{ type.name }}\n </button>\n }\n\n </mat-menu>\n</mat-toolbar>\n\n<span>\n @switch (selectedService) {\n @case ('basic_http_service') {\n <p>\n <app-request-manager-basic-demo></app-request-manager-basic-demo>\n </p>\n }\n @case ('http_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-demo\n [server]=\"server\"\n [adapter]=\"adapter\"\n [mapper]=\"mapper\"\n ></app-request-manager-demo>\n </p>\n }\n <!-- <p *ngSwitchCase=\"'http_signals_service'\">\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-signals-manager-demo></app-request-signals-manager-demo>\n </p> -->\n @case ('http_state_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-state-demo\n [server]=\"server\"\n [adapter]=\"adapter\"\n [mapper]=\"mapper\"\n ></app-request-manager-state-demo>\n </p>\n }\n @case ('http_state_service_ws') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-ws-demo\n [server]=\"server\"\n [wsServer]=\"wsServer\"\n [jwtToken]=\"jwtToken\"\n [user]=\"user\"\n [path]=\"path\"\n ></app-request-manager-ws-demo>\n </p>\n }\n @case ('database_service') {\n <p>\n <app-database-data-demo></app-database-data-demo>\n </p>\n }\n @case ('local_storage_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-local-storage-demo></app-local-storage-demo>\n </p>\n }\n <!-- <p *ngSwitchCase=\"'local_storage_signals_service'\">\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-local-storage-signals-demo></app-local-storage-signals-demo>\n</p> -->\n@case ('store_state_manager') {\n <p>\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-store-state-manager-demo></app-store-state-manager-demo>\n </p>\n}\n@default {\n <p>\n Other\n </p>\n}\n}\n</span>\n\n<ng-template #HTTP_OPTIONS>\n @if (injectionOptions?.httpRequestOptions) {\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - HTTP Options</h3>\n {{ injectionOptions?.httpRequestOptions| json }}\n </div>\n }\n</ng-template>\n\n<ng-template #LOCAL_OPTIONS>\n @if (injectionOptions?.LocalStorageOptions) {\n <ng-container class=\"box\">\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - LocalStorage Options</h3>\n {{ injectionOptions?.LocalStorageOptions| json }}\n </div>\n </ng-container>\n }\n</ng-template>\n\n\n", styles: [".box{padding:1rem;background-color:#f5f5f5;border:thin gray solid;margin-top:1rem}\n"] }]
|
|
10782
|
+
args: [{ selector: 'app-http-request-services-demo', standalone: false, template: "<mat-toolbar style=\"display:flex\">\n <div>Http Request Manager Services</div>\n <div style=\"flex:1\"></div>\n <button mat-stroked-button [matMenuTriggerFor]=\"menu\">Services</button>\n <mat-menu #menu=\"matMenu\">\n @for (type of requestTypes; track type; let i = $index) {\n @if (type?.divider) {\n <div\n style=\"margin-top: .5rem; margin-bottom: .5rem;\"\n >\n <mat-divider></mat-divider>\n </div>\n }\n <button\n mat-menu-item\n (click)=\"onSelected(i)\"\n [disabled]=\"type.disabled\"\n >\n {{ type.name }}\n </button>\n }\n\n </mat-menu>\n</mat-toolbar>\n\n<span>\n @switch (selectedService) {\n @case ('basic_http_service') {\n <p>\n <app-request-manager-basic-demo></app-request-manager-basic-demo>\n </p>\n }\n @case ('http_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-demo\n [server]=\"server\"\n [adapter]=\"adapter\"\n [mapper]=\"mapper\"\n ></app-request-manager-demo>\n </p>\n }\n <!-- <p *ngSwitchCase=\"'http_signals_service'\">\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-signals-manager-demo></app-request-signals-manager-demo>\n </p> -->\n @case ('http_state_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-state-demo\n [server]=\"server\"\n [adapter]=\"adapter\"\n [mapper]=\"mapper\"\n ></app-request-manager-state-demo>\n </p>\n }\n @case ('http_state_service_ws') {\n <p>\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-ws-demo\n [server]=\"server\"\n [wsServer]=\"wsServer\"\n [jwtToken]=\"jwtToken\"\n [user]=\"user\"\n [path]=\"path\"\n ></app-request-manager-ws-demo>\n </p>\n }\n @case ('file_upload_demo') {\n <p>\n <lib-upload-demo></lib-upload-demo>\n </p>\n }\n @case ('database_service') {\n <p>\n <app-database-data-demo></app-database-data-demo>\n </p>\n }\n @case ('local_storage_service') {\n <p>\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-local-storage-demo></app-local-storage-demo>\n </p>\n }\n <!-- <p *ngSwitchCase=\"'local_storage_signals_service'\">\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-local-storage-signals-demo></app-local-storage-signals-demo>\n</p> -->\n@case ('store_state_manager') {\n <p>\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-store-state-manager-demo></app-store-state-manager-demo>\n </p>\n}\n@default {\n <p>\n Other\n </p>\n}\n}\n</span>\n\n<ng-template #HTTP_OPTIONS>\n @if (injectionOptions?.httpRequestOptions) {\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - HTTP Options</h3>\n {{ injectionOptions?.httpRequestOptions| json }}\n </div>\n }\n</ng-template>\n\n<ng-template #LOCAL_OPTIONS>\n @if (injectionOptions?.LocalStorageOptions) {\n <ng-container class=\"box\">\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - LocalStorage Options</h3>\n {{ injectionOptions?.LocalStorageOptions| json }}\n </div>\n </ng-container>\n }\n</ng-template>\n\n\n", styles: [".box{padding:1rem;background-color:#f5f5f5;border:thin gray solid;margin-top:1rem}\n"] }]
|
|
10423
10783
|
}], ctorParameters: () => [{ type: ConfigOptions, decorators: [{
|
|
10424
10784
|
type: Inject,
|
|
10425
10785
|
args: [CONFIG_SETTINGS_TOKEN]
|
|
@@ -10979,7 +11339,8 @@ class HttpRequestManagerModule {
|
|
|
10979
11339
|
WsMessagingComponent,
|
|
10980
11340
|
WsNotificationsComponent,
|
|
10981
11341
|
WsAiMessagingComponent,
|
|
10982
|
-
WsChatsComponent
|
|
11342
|
+
WsChatsComponent,
|
|
11343
|
+
UploadDemoComponent], imports: [CommonModule,
|
|
10983
11344
|
ToastMessageDisplayModule,
|
|
10984
11345
|
FormsModule,
|
|
10985
11346
|
ReactiveFormsModule,
|
|
@@ -11003,7 +11364,8 @@ class HttpRequestManagerModule {
|
|
|
11003
11364
|
MatDatepickerModule,
|
|
11004
11365
|
MatNativeDateModule,
|
|
11005
11366
|
MatCardModule,
|
|
11006
|
-
FileDownloaderModule], exports: [HttpRequestServicesDemoComponent
|
|
11367
|
+
FileDownloaderModule], exports: [HttpRequestServicesDemoComponent,
|
|
11368
|
+
UploadDemoComponent] }); }
|
|
11007
11369
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HttpRequestManagerModule, providers: [
|
|
11008
11370
|
{ provide: HTTP_INTERCEPTORS, useClass: WithCredentialsInterceptor, multi: true },
|
|
11009
11371
|
{ provide: HTTP_INTERCEPTORS, useClass: RequestHeadersInterceptor, multi: true },
|
|
@@ -11091,9 +11453,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
11091
11453
|
WsNotificationsComponent,
|
|
11092
11454
|
WsAiMessagingComponent,
|
|
11093
11455
|
WsChatsComponent,
|
|
11456
|
+
UploadDemoComponent,
|
|
11094
11457
|
],
|
|
11095
11458
|
exports: [
|
|
11096
11459
|
HttpRequestServicesDemoComponent,
|
|
11460
|
+
UploadDemoComponent,
|
|
11097
11461
|
],
|
|
11098
11462
|
providers: [
|
|
11099
11463
|
{ provide: HTTP_INTERCEPTORS, useClass: WithCredentialsInterceptor, multi: true },
|
|
@@ -11244,5 +11608,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
11244
11608
|
* Generated bundle index. Do not edit.
|
|
11245
11609
|
*/
|
|
11246
11610
|
|
|
11247
|
-
export { ApiRequest, AppService, AsymmetricalEncryptionService, BatchOptions, BatchResult, CONFIG_SETTINGS_TOKEN, ChannelType, ConfigHTTPOptions, ConfigOptions, DataType, DatabaseDataDemoComponent, DatabaseManagerService, DatabaseStorage, DbService, ErrorDisplaySettings, GlobalStoreOptions, HTTPManagerService, HTTPManagerSignalsService, HTTPManagerStateService, HeadersService, HttpRequestManagerModule, HttpRequestServicesDemoComponent, LocalStorageDemoComponent, LocalStorageManagerService, LocalStorageOptions, LocalStorageSignalsDemoComponent, LocalStorageSignalsManagerService, LoggerService, NotificationMessage, PathQueryService, PublicMessage, Random, RandomHSLColor, RandomHexColor, RandomNumber, RandomNumbers, RandomNumbersUnique, RandomPaletteColor, RandomSignature, RandomStr, RandomVisibleColor, RequestErrorInterceptor, RequestHeadersInterceptor, RequestManagerDemoComponent, RequestManagerStateDemoComponent, RequestOptions, RequestService, RequestSignalsService, RetryOptions, SettingOptions, StateMessage, StateStorageOptions, StorageData, StorageOption, StorageType, StoreStateManagerService, StoreStateManagerSignalsService, StoreStateSignalsDemoComponent, StreamType, SymmetricalEncryptionService, TableSchemaDef, UUID, UUID_STR, UserData, UtilsService, WSOptions, WebSocketMessageService, WithCredentialsInterceptor, calculateBatchProgress, countdown, createChannelName, delayedRetry, isErrorState, isPendingState, isSuccessState, requestPolling, requestStreaming, streamAI, streamAuto, streamEvents, streamJSON, streamNDJSON };
|
|
11611
|
+
export { ApiRequest, AppService, AsymmetricalEncryptionService, BatchOptions, BatchResult, CONFIG_SETTINGS_TOKEN, ChannelType, ConfigHTTPOptions, ConfigOptions, DataType, DatabaseDataDemoComponent, DatabaseManagerService, DatabaseStorage, DbService, ErrorDisplaySettings, GlobalStoreOptions, HTTPManagerService, HTTPManagerSignalsService, HTTPManagerStateService, HeadersService, HttpRequestManagerModule, HttpRequestServicesDemoComponent, InvalidFileInfoModel, LocalStorageDemoComponent, LocalStorageManagerService, LocalStorageOptions, LocalStorageSignalsDemoComponent, LocalStorageSignalsManagerService, LoggerService, NotificationMessage, PathQueryService, PublicMessage, Random, RandomHSLColor, RandomHexColor, RandomNumber, RandomNumbers, RandomNumbersUnique, RandomPaletteColor, RandomSignature, RandomStr, RandomVisibleColor, RequestErrorInterceptor, RequestHeadersInterceptor, RequestManagerDemoComponent, RequestManagerStateDemoComponent, RequestOptions, RequestService, RequestSignalsService, RetryOptions, SettingOptions, StateMessage, StateStorageOptions, StorageData, StorageOption, StorageType, StoreStateManagerService, StoreStateManagerSignalsService, StoreStateSignalsDemoComponent, StreamType, SymmetricalEncryptionService, TableSchemaDef, UUID, UUID_STR, UploadDemoComponent, UploadValidationErrorModel, UserData, UtilsService, WSOptions, WebSocketMessageService, WithCredentialsInterceptor, calculateBatchProgress, countdown, createChannelName, delayedRetry, isErrorState, isPendingState, isSuccessState, requestPolling, requestStreaming, streamAI, streamAuto, streamEvents, streamJSON, streamNDJSON };
|
|
11248
11612
|
//# sourceMappingURL=http-request-manager.mjs.map
|