datastake-daf 0.6.486 → 0.6.488
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/dist/components/index.js +49 -5
- package/dist/services/index.js +6338 -0
- package/dist/utils/index.js +297 -0
- package/package.json +1 -1
- package/rollup.config.js +20 -0
- package/src/@daf/core/components/DynamicForm/helper.js +7 -0
- package/src/@daf/core/components/DynamicForm/index.jsx +36 -0
- package/src/@daf/services/BaseHTTPService.js +229 -0
- package/src/@daf/services/ErrorHandler.js +43 -0
- package/src/helpers/StringHelper.js +12 -1
- package/src/helpers/errorHandling.js +97 -0
- package/src/helpers/urlHelpers.js +36 -0
- package/src/services.js +2 -0
- package/src/utils.js +9 -2
package/dist/utils/index.js
CHANGED
|
@@ -5096,6 +5096,16 @@ const safeJsonParse = (value, fallback = value) => {
|
|
|
5096
5096
|
return fallback;
|
|
5097
5097
|
}
|
|
5098
5098
|
};
|
|
5099
|
+
const cleanJSON = json => {
|
|
5100
|
+
for (let key in json) {
|
|
5101
|
+
if (json[key] === undefined) {
|
|
5102
|
+
json[key] = null;
|
|
5103
|
+
} /*else if (typeof json[key] === 'object')
|
|
5104
|
+
json[key] = cleanJSON(json[key]);
|
|
5105
|
+
*/
|
|
5106
|
+
}
|
|
5107
|
+
return json;
|
|
5108
|
+
};
|
|
5099
5109
|
|
|
5100
5110
|
function _checkValue$1(wantedValue, match, fieldValue) {
|
|
5101
5111
|
match = match ? match.trim() : null;
|
|
@@ -6016,6 +6026,152 @@ var browser$1 = {
|
|
|
6016
6026
|
|
|
6017
6027
|
var process = browser$1;
|
|
6018
6028
|
|
|
6029
|
+
/**
|
|
6030
|
+
* @description Manages window.storage
|
|
6031
|
+
* @returns storage objects
|
|
6032
|
+
* @class StorageManager
|
|
6033
|
+
*/
|
|
6034
|
+
class StorageManager {
|
|
6035
|
+
/**
|
|
6036
|
+
* @description Set or update given value in localStorage
|
|
6037
|
+
* @static
|
|
6038
|
+
* @returns Object
|
|
6039
|
+
* @memberof StorageManager
|
|
6040
|
+
*/
|
|
6041
|
+
static set(key, value) {
|
|
6042
|
+
if (key && value) {
|
|
6043
|
+
window.localStorage.setItem(key, value);
|
|
6044
|
+
return {
|
|
6045
|
+
success: true,
|
|
6046
|
+
data: "Storage has been set successfully."
|
|
6047
|
+
};
|
|
6048
|
+
}
|
|
6049
|
+
return {
|
|
6050
|
+
error: true,
|
|
6051
|
+
data: "Storage was not set. Storage key and value is required!"
|
|
6052
|
+
};
|
|
6053
|
+
}
|
|
6054
|
+
|
|
6055
|
+
/**
|
|
6056
|
+
* @description Set or update given value in sessionStorage, used to not remember user after closing opened tab.
|
|
6057
|
+
* @static
|
|
6058
|
+
* @returns Object
|
|
6059
|
+
* @memberof StorageManager
|
|
6060
|
+
*/
|
|
6061
|
+
static setToSession(key, value) {
|
|
6062
|
+
if (key && value) {
|
|
6063
|
+
window.sessionStorage.setItem(key, value);
|
|
6064
|
+
return {
|
|
6065
|
+
success: true,
|
|
6066
|
+
data: "Storage has been set successfully."
|
|
6067
|
+
};
|
|
6068
|
+
}
|
|
6069
|
+
return {
|
|
6070
|
+
error: true,
|
|
6071
|
+
data: "Storage was not set. Storage key and value is required!"
|
|
6072
|
+
};
|
|
6073
|
+
}
|
|
6074
|
+
|
|
6075
|
+
/**
|
|
6076
|
+
* @description Fetch data from localStorage
|
|
6077
|
+
* @static
|
|
6078
|
+
* @returns Object
|
|
6079
|
+
* @memberof StorageManager
|
|
6080
|
+
*/
|
|
6081
|
+
static get(key, defaultValue = undefined) {
|
|
6082
|
+
if (key) {
|
|
6083
|
+
const val = window.localStorage.getItem(key) || window.sessionStorage.getItem(key);
|
|
6084
|
+
return val || defaultValue;
|
|
6085
|
+
}
|
|
6086
|
+
return {
|
|
6087
|
+
error: true,
|
|
6088
|
+
data: "Storage key is required!"
|
|
6089
|
+
};
|
|
6090
|
+
}
|
|
6091
|
+
|
|
6092
|
+
/**
|
|
6093
|
+
* @description Clear only one value from localStorage
|
|
6094
|
+
* @static
|
|
6095
|
+
* @returns Object
|
|
6096
|
+
* @memberof StorageManager
|
|
6097
|
+
*/
|
|
6098
|
+
static clearOne(key) {
|
|
6099
|
+
if (key === 'token') {
|
|
6100
|
+
localStorage.removeItem('trade-type');
|
|
6101
|
+
localStorage.removeItem('trade-value');
|
|
6102
|
+
}
|
|
6103
|
+
if (key) {
|
|
6104
|
+
window.localStorage.removeItem(key) || window.sessionStorage.removeItem(key);
|
|
6105
|
+
}
|
|
6106
|
+
return "Storage key is required!";
|
|
6107
|
+
}
|
|
6108
|
+
|
|
6109
|
+
/**
|
|
6110
|
+
* @description Clear all values from localStorage
|
|
6111
|
+
* @static
|
|
6112
|
+
* @returns Object
|
|
6113
|
+
* @memberof StorageManager
|
|
6114
|
+
*/
|
|
6115
|
+
static clearAll() {
|
|
6116
|
+
window.localStorage.clear();
|
|
6117
|
+
window.sessionStorage.clear();
|
|
6118
|
+
}
|
|
6119
|
+
static hasKey(key) {
|
|
6120
|
+
return typeof this.get(key) === 'string';
|
|
6121
|
+
}
|
|
6122
|
+
static saveFilters(module, namespace, filters = {}, merge = false) {
|
|
6123
|
+
let savedFilters = this.get('filters');
|
|
6124
|
+
try {
|
|
6125
|
+
savedFilters = JSON.parse(savedFilters);
|
|
6126
|
+
} catch (e) {
|
|
6127
|
+
savedFilters = {};
|
|
6128
|
+
}
|
|
6129
|
+
if (!savedFilters) {
|
|
6130
|
+
savedFilters = {};
|
|
6131
|
+
}
|
|
6132
|
+
if (!savedFilters[module]) {
|
|
6133
|
+
savedFilters[module] = {};
|
|
6134
|
+
}
|
|
6135
|
+
if (!savedFilters[module][namespace]) {
|
|
6136
|
+
savedFilters[module][namespace] = {};
|
|
6137
|
+
}
|
|
6138
|
+
if (Object.keys(filters).length) {
|
|
6139
|
+
savedFilters[module][namespace] = merge ? Object.assign(savedFilters[module][namespace], filters) : filters;
|
|
6140
|
+
} else {
|
|
6141
|
+
savedFilters[module][namespace] = {};
|
|
6142
|
+
}
|
|
6143
|
+
this.set('filters', JSON.stringify(savedFilters));
|
|
6144
|
+
return savedFilters[module][namespace];
|
|
6145
|
+
}
|
|
6146
|
+
static getFilters(module, namespace) {
|
|
6147
|
+
let savedFilters = this.get('filters');
|
|
6148
|
+
try {
|
|
6149
|
+
savedFilters = JSON.parse(savedFilters);
|
|
6150
|
+
} catch (e) {
|
|
6151
|
+
savedFilters = {};
|
|
6152
|
+
}
|
|
6153
|
+
if (!savedFilters) {
|
|
6154
|
+
savedFilters = {};
|
|
6155
|
+
}
|
|
6156
|
+
if (!savedFilters[module]) {
|
|
6157
|
+
savedFilters[module] = {};
|
|
6158
|
+
}
|
|
6159
|
+
if (!savedFilters[module][namespace]) {
|
|
6160
|
+
savedFilters[module][namespace] = {};
|
|
6161
|
+
}
|
|
6162
|
+
return savedFilters[module][namespace];
|
|
6163
|
+
}
|
|
6164
|
+
}
|
|
6165
|
+
|
|
6166
|
+
const isProxy = () => {
|
|
6167
|
+
const pathname = window.location.pathname;
|
|
6168
|
+
if (pathname.includes('/proxy/pme') || pathname.includes('/proxy/cadd')) {
|
|
6169
|
+
return window.opener || !!StorageManager.get('proxy_token');
|
|
6170
|
+
}
|
|
6171
|
+
return false;
|
|
6172
|
+
};
|
|
6173
|
+
const getToken = () => isProxy() ? StorageManager.get('proxy_token') : StorageManager.get('token');
|
|
6174
|
+
|
|
6019
6175
|
({
|
|
6020
6176
|
config: PropTypes__default["default"].object,
|
|
6021
6177
|
filters: PropTypes__default["default"].object,
|
|
@@ -13431,17 +13587,153 @@ const processConfig = async configArray => {
|
|
|
13431
13587
|
return processedConfig;
|
|
13432
13588
|
};
|
|
13433
13589
|
|
|
13590
|
+
/**
|
|
13591
|
+
* Utility functions for URL manipulation
|
|
13592
|
+
*/
|
|
13593
|
+
|
|
13594
|
+
/**
|
|
13595
|
+
* Assigns parameters to URL path
|
|
13596
|
+
* Example: assignParamsToUrl('/users/{id}/posts/{postId}', { id: 1, postId: 2 })
|
|
13597
|
+
* Returns: '/users/1/posts/2'
|
|
13598
|
+
*/
|
|
13599
|
+
const assignParamsToUrl = (path, params) => {
|
|
13600
|
+
let paramsPath = path;
|
|
13601
|
+
const matches = path.match(/\{\w+\}/gm);
|
|
13602
|
+
if (matches) {
|
|
13603
|
+
for (let param of matches) {
|
|
13604
|
+
const key = param.match(/\w+/)[0];
|
|
13605
|
+
paramsPath = paramsPath.replace(/\{\w+\}/, params[key]);
|
|
13606
|
+
}
|
|
13607
|
+
}
|
|
13608
|
+
return paramsPath;
|
|
13609
|
+
};
|
|
13610
|
+
|
|
13611
|
+
/**
|
|
13612
|
+
* Build query string from object
|
|
13613
|
+
* Example: buildQueryString({ page: 1, limit: 10 })
|
|
13614
|
+
* Returns: '?page=1&limit=10'
|
|
13615
|
+
*/
|
|
13616
|
+
const buildQueryString = params => {
|
|
13617
|
+
const query = Object.keys(params).filter(key => params[key] !== null && params[key] !== undefined).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&');
|
|
13618
|
+
return query ? `?${query}` : '';
|
|
13619
|
+
};
|
|
13620
|
+
|
|
13621
|
+
/**
|
|
13622
|
+
* Generic error handler factory for axios requests
|
|
13623
|
+
* Highly configurable to adapt to different project needs
|
|
13624
|
+
*/
|
|
13625
|
+
const createErrorHandler = (config = {}) => {
|
|
13626
|
+
const {
|
|
13627
|
+
onUnauthorized,
|
|
13628
|
+
handleError,
|
|
13629
|
+
getStorageManager,
|
|
13630
|
+
checkTokenValidity = true,
|
|
13631
|
+
unauthorizedRedirect = '/',
|
|
13632
|
+
tokenStorageKey = 'token',
|
|
13633
|
+
handleNetworkError = true
|
|
13634
|
+
} = config;
|
|
13635
|
+
return (error, customOnUnauthorized) => {
|
|
13636
|
+
// Handle cases where error.response doesn't exist (network errors)
|
|
13637
|
+
if (!error.response) {
|
|
13638
|
+
if (handleNetworkError && handleError) {
|
|
13639
|
+
handleError({
|
|
13640
|
+
status: 0,
|
|
13641
|
+
statusText: "Network Error",
|
|
13642
|
+
data: ["Please check your internet connection."]
|
|
13643
|
+
});
|
|
13644
|
+
}
|
|
13645
|
+
return Promise.reject(error);
|
|
13646
|
+
}
|
|
13647
|
+
const {
|
|
13648
|
+
status,
|
|
13649
|
+
statusText,
|
|
13650
|
+
data: {
|
|
13651
|
+
errors,
|
|
13652
|
+
message
|
|
13653
|
+
} = {}
|
|
13654
|
+
} = error.response || {
|
|
13655
|
+
data: {}
|
|
13656
|
+
};
|
|
13657
|
+
|
|
13658
|
+
// Handle 401 Unauthorized
|
|
13659
|
+
if (status === 401) {
|
|
13660
|
+
if (checkTokenValidity && getStorageManager) {
|
|
13661
|
+
const token = getStorageManager().get(tokenStorageKey);
|
|
13662
|
+
if (token) {
|
|
13663
|
+
if (typeof customOnUnauthorized === 'function') {
|
|
13664
|
+
customOnUnauthorized();
|
|
13665
|
+
} else if (typeof onUnauthorized === 'function') {
|
|
13666
|
+
onUnauthorized();
|
|
13667
|
+
} else {
|
|
13668
|
+
getStorageManager().clearOne(tokenStorageKey);
|
|
13669
|
+
if (typeof window !== 'undefined') {
|
|
13670
|
+
window.location.href = unauthorizedRedirect;
|
|
13671
|
+
}
|
|
13672
|
+
}
|
|
13673
|
+
}
|
|
13674
|
+
}
|
|
13675
|
+
}
|
|
13676
|
+
|
|
13677
|
+
// Handle 4xx and 5xx errors
|
|
13678
|
+
if (status >= 400 && status <= 500) {
|
|
13679
|
+
if (handleError) {
|
|
13680
|
+
handleError({
|
|
13681
|
+
status,
|
|
13682
|
+
statusText: message || statusText,
|
|
13683
|
+
data: errors || []
|
|
13684
|
+
});
|
|
13685
|
+
}
|
|
13686
|
+
}
|
|
13687
|
+
return Promise.reject(error);
|
|
13688
|
+
};
|
|
13689
|
+
};
|
|
13690
|
+
|
|
13691
|
+
/**
|
|
13692
|
+
* Simple error handler using antd message component
|
|
13693
|
+
* Useful for quick error notifications
|
|
13694
|
+
*/
|
|
13695
|
+
const handleError = err => {
|
|
13696
|
+
const errorMessage = err?.response?.data?.message || err?.message || 'An error occurred';
|
|
13697
|
+
antd.message.error(errorMessage);
|
|
13698
|
+
};
|
|
13699
|
+
|
|
13700
|
+
/**
|
|
13701
|
+
* Success message handler
|
|
13702
|
+
*/
|
|
13703
|
+
const handleSuccess = msg => {
|
|
13704
|
+
antd.message.success(msg || 'Operation successful');
|
|
13705
|
+
};
|
|
13706
|
+
|
|
13707
|
+
/**
|
|
13708
|
+
* Warning message handler
|
|
13709
|
+
*/
|
|
13710
|
+
const handleWarning = msg => {
|
|
13711
|
+
antd.message.warning(msg || 'Warning');
|
|
13712
|
+
};
|
|
13713
|
+
|
|
13714
|
+
/**
|
|
13715
|
+
* Info message handler
|
|
13716
|
+
*/
|
|
13717
|
+
const handleInfo = msg => {
|
|
13718
|
+
antd.message.info(msg);
|
|
13719
|
+
};
|
|
13720
|
+
|
|
13434
13721
|
exports.ErrorFormat = ErrorFormat;
|
|
13435
13722
|
exports.MessageTypes = MessageTypes;
|
|
13723
|
+
exports.StorageManager = StorageManager;
|
|
13724
|
+
exports.assignParamsToUrl = assignParamsToUrl;
|
|
13436
13725
|
exports.btn = button;
|
|
13726
|
+
exports.buildQueryString = buildQueryString;
|
|
13437
13727
|
exports.camelCaseToTitle = camelCaseToTitle;
|
|
13438
13728
|
exports.capitalize = capitalize;
|
|
13439
13729
|
exports.capitalizeAll = capitalizeAll;
|
|
13440
13730
|
exports.captureComponentsAsImages = captureComponentsAsImages;
|
|
13441
13731
|
exports.captureElementsAsImages = captureElementsAsImages;
|
|
13442
13732
|
exports.changeInputMeta = changeInputMeta;
|
|
13733
|
+
exports.cleanJSON = cleanJSON;
|
|
13443
13734
|
exports.convertUndefinedToNull = convertUndefinedToNull;
|
|
13444
13735
|
exports.createDocument = createDocument;
|
|
13736
|
+
exports.createErrorHandler = createErrorHandler;
|
|
13445
13737
|
exports.defaultFilterKeys = defaultFilterKeys;
|
|
13446
13738
|
exports.defaultMapConfig = defaultMapConfig;
|
|
13447
13739
|
exports.defaultTheme = mmtTheme;
|
|
@@ -13464,7 +13756,12 @@ exports.getOptionConfig = getOptionConfig;
|
|
|
13464
13756
|
exports.getOptionLabel = getOptionLabel;
|
|
13465
13757
|
exports.getRangeOfTicks = getRangeOfTicks;
|
|
13466
13758
|
exports.getTagColor = getTagColor;
|
|
13759
|
+
exports.getToken = getToken;
|
|
13467
13760
|
exports.groupSubsections = groupSubsections;
|
|
13761
|
+
exports.handleError = handleError;
|
|
13762
|
+
exports.handleInfo = handleInfo;
|
|
13763
|
+
exports.handleSuccess = handleSuccess;
|
|
13764
|
+
exports.handleWarning = handleWarning;
|
|
13468
13765
|
exports.hasNotChanged = hasNotChanged;
|
|
13469
13766
|
exports.isEmptyOrSpaces = isEmptyOrSpaces;
|
|
13470
13767
|
exports.isModuleApproved = isModuleApproved;
|
package/package.json
CHANGED
package/rollup.config.js
CHANGED
|
@@ -95,6 +95,26 @@ export default [
|
|
|
95
95
|
requireReturnsDefault: "auto",
|
|
96
96
|
}),
|
|
97
97
|
],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
input: "src/services.js",
|
|
101
|
+
output: [
|
|
102
|
+
{
|
|
103
|
+
file: "dist/services/index.js",
|
|
104
|
+
format: "cjs",
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
external,
|
|
108
|
+
plugins: [
|
|
109
|
+
nodePolyfills(),
|
|
110
|
+
resolve({ browser: true }),
|
|
111
|
+
babel({ exclude: "node_modules/**", babelrc: true }),
|
|
112
|
+
peerDep(),
|
|
113
|
+
commonjs({
|
|
114
|
+
include: /node_modules/,
|
|
115
|
+
requireReturnsDefault: "auto",
|
|
116
|
+
}),
|
|
117
|
+
],
|
|
98
118
|
},
|
|
99
119
|
{
|
|
100
120
|
input: "src/hooks.js",
|
|
@@ -89,6 +89,13 @@ export const checkCondition = (condition, repeatValues, formsValue) => {
|
|
|
89
89
|
};
|
|
90
90
|
export function showHideInput(input, formsValue, repeatIndex, repeatValues, setValues, ref) {
|
|
91
91
|
if (input?.meta?.hidden === true) {
|
|
92
|
+
// Set default value for hidden fields
|
|
93
|
+
if (input?.meta?.defaultValue !== undefined && !propHasValue(formsValue[ref])) {
|
|
94
|
+
formsValue[ref] = input.meta.defaultValue;
|
|
95
|
+
if (setValues && typeof setValues === 'function') {
|
|
96
|
+
setValues({ ...formsValue });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
92
99
|
return false;
|
|
93
100
|
}
|
|
94
101
|
if (input.showIf) {
|
|
@@ -168,6 +168,34 @@ export default function DynamicForm({
|
|
|
168
168
|
}
|
|
169
169
|
}, [data]);
|
|
170
170
|
|
|
171
|
+
// Initialize default values for hidden fields
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
if (Object.keys(form).length > 0) {
|
|
174
|
+
const updatedValues = { ...values };
|
|
175
|
+
let hasChanges = false;
|
|
176
|
+
|
|
177
|
+
// Process all form fields to set default values for hidden fields
|
|
178
|
+
Object.keys(form).forEach(formKey => {
|
|
179
|
+
Object.keys(form[formKey]).forEach(fieldKey => {
|
|
180
|
+
const field = form[formKey][fieldKey];
|
|
181
|
+
if (field?.meta?.hidden === true && field?.meta?.defaultValue !== undefined) {
|
|
182
|
+
const fieldId = field.dataId || fieldKey;
|
|
183
|
+
if (!propHasValue(updatedValues[fieldId])) {
|
|
184
|
+
updatedValues[fieldId] = field.meta.defaultValue;
|
|
185
|
+
hasChanges = true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
if (hasChanges) {
|
|
192
|
+
setValues(updatedValues);
|
|
193
|
+
// Also set the values in the Ant Design form
|
|
194
|
+
MainForm.setFieldsValue(updatedValues);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}, [form]);
|
|
198
|
+
|
|
171
199
|
const setSelectedForm = (id) => {
|
|
172
200
|
setForms(Forms.map(form => {
|
|
173
201
|
(id === form.id)
|
|
@@ -267,6 +295,14 @@ export default function DynamicForm({
|
|
|
267
295
|
}
|
|
268
296
|
value = fileList;
|
|
269
297
|
}
|
|
298
|
+
// Handle default values for hidden fields
|
|
299
|
+
if (input?.meta?.hidden === true && input?.meta?.defaultValue !== undefined && !propHasValue(value)) {
|
|
300
|
+
value = input.meta.defaultValue;
|
|
301
|
+
if (typeof path === 'string') {
|
|
302
|
+
dot.str(path, value, values);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
270
306
|
const config = {
|
|
271
307
|
name,
|
|
272
308
|
call: input.call ? input.call : input?.meta?.call,
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { cleanJSON } from '../../helpers/StringHelper.js';
|
|
3
|
+
import { assignParamsToUrl } from '../../helpers/urlHelpers.js';
|
|
4
|
+
import { getToken } from '../../helpers/Token.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Base HTTP Service Class
|
|
8
|
+
* Provides axios wrapper with token management, cancel tokens, and interceptors
|
|
9
|
+
*/
|
|
10
|
+
export class BaseHTTPService {
|
|
11
|
+
constructor(config = {}) {
|
|
12
|
+
const {getHeaders, getBaseUrl, onError, timeout = 300000, customAxiosConfig = {}} = config;
|
|
13
|
+
|
|
14
|
+
this.getToken = getToken || (() => null);
|
|
15
|
+
this.getHeaders = getHeaders || (() => ({}));
|
|
16
|
+
this.getBaseUrl = getBaseUrl || (() => null);
|
|
17
|
+
this.onError = onError || (() => null);
|
|
18
|
+
this.cleanJSON = cleanJSON;
|
|
19
|
+
this.timeout = timeout;
|
|
20
|
+
this.customAxiosConfig = customAxiosConfig;
|
|
21
|
+
|
|
22
|
+
// Init
|
|
23
|
+
this.cancelToken = {}
|
|
24
|
+
this.token = this.getToken();
|
|
25
|
+
|
|
26
|
+
this.setupAxios();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setupAxios() {
|
|
30
|
+
const headers = {
|
|
31
|
+
Authorization: `Bearer ${this.token}`,
|
|
32
|
+
...this.getHeaders(),
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
this.api = axios.create({
|
|
36
|
+
baseURL: this.getBaseUrl(),
|
|
37
|
+
headers,
|
|
38
|
+
timeout: this.timeout,
|
|
39
|
+
...this.customAxiosConfig,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
this.setupInterceptors();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
setupInterceptors() {
|
|
46
|
+
this.api.interceptors.response.use((response) => response,
|
|
47
|
+
(error) => Promise.reject(error)
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// Request interceptor - clean JSON data
|
|
51
|
+
this.api.interceptors.request.use(
|
|
52
|
+
(config) => {
|
|
53
|
+
if (['post', 'put', 'patch'].includes(config.method)) {
|
|
54
|
+
config.data = this.cleanJSON(config.data);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return config;
|
|
58
|
+
},
|
|
59
|
+
(error) => Promise.reject(error)
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
reloadAxios() {
|
|
64
|
+
const token = this.getToken();
|
|
65
|
+
this.token = token;
|
|
66
|
+
|
|
67
|
+
const options = {
|
|
68
|
+
baseURL: this.getBaseURL(),
|
|
69
|
+
timeout: this.timeout,
|
|
70
|
+
...this.customAxiosConfig,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
if (token) {
|
|
74
|
+
options.headers = {
|
|
75
|
+
Authorization: `Bearer ${token}`,
|
|
76
|
+
...this.getHeaders(),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
this.api = axios.create(options);
|
|
81
|
+
this.setupInterceptors();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async formatResponse(call) {
|
|
85
|
+
try {
|
|
86
|
+
const res = await call;
|
|
87
|
+
const { data, status, statusText } = res || {};
|
|
88
|
+
this.cancelToken = {};
|
|
89
|
+
return { data, status, statusText };
|
|
90
|
+
} catch (error) {
|
|
91
|
+
return Promise.reject(error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
apiPost(options) {
|
|
96
|
+
// Check if there are any previous pending requests
|
|
97
|
+
if (typeof this.cancelToken[options.url] != typeof undefined) {
|
|
98
|
+
try {
|
|
99
|
+
this.cancelToken[options.url].cancel("Operation canceled due to new request.");
|
|
100
|
+
} catch (e) {
|
|
101
|
+
console.log(e);
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
this.cancelToken[options.url] = axios.CancelToken.source();
|
|
107
|
+
const token = this.getToken();
|
|
108
|
+
|
|
109
|
+
if (token !== this.token || !token) {
|
|
110
|
+
this.reloadAxios();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return this.formatResponse(
|
|
114
|
+
this.api.post(options.url, options.data, {
|
|
115
|
+
baseURL: options.baseURL || this.getBaseURL(options),
|
|
116
|
+
cancelToken: this.cancelToken[options.url].token,
|
|
117
|
+
headers: {
|
|
118
|
+
Authorization: `Bearer ${this.getToken()}`,
|
|
119
|
+
...this.getHeaders(),
|
|
120
|
+
...(options?.headers || {}),
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
.catch((err) => this.onError(err))
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
apiGet(options) {
|
|
128
|
+
const token = this.getToken();
|
|
129
|
+
|
|
130
|
+
if (token !== this.token || !token) {
|
|
131
|
+
this.reloadAxios();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const { url, ...config } = options;
|
|
135
|
+
|
|
136
|
+
return this.formatResponse(
|
|
137
|
+
this.api.get(url, {
|
|
138
|
+
...config,
|
|
139
|
+
baseURL: options.baseURL || this.getBaseURL(options),
|
|
140
|
+
headers: {
|
|
141
|
+
Authorization: `Bearer ${this.getToken()}`,
|
|
142
|
+
...this.getHeaders(),
|
|
143
|
+
...(config?.headers || {}),
|
|
144
|
+
}
|
|
145
|
+
})
|
|
146
|
+
.catch((err) => this.onError(err))
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
apiDelete(options) {
|
|
151
|
+
const token = this.getToken();
|
|
152
|
+
|
|
153
|
+
if (token !== this.token || !token) {
|
|
154
|
+
this.reloadAxios();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const { url, ...config } = options;
|
|
158
|
+
|
|
159
|
+
return this.formatResponse(
|
|
160
|
+
this.api.delete(url, {
|
|
161
|
+
...config,
|
|
162
|
+
baseURL: options.baseURL || this.getBaseURL(options),
|
|
163
|
+
headers: {
|
|
164
|
+
Authorization: `Bearer ${this.getToken()}`,
|
|
165
|
+
...this.getHeaders(),
|
|
166
|
+
...(config?.headers || {}),
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
.catch((err) => this.onError(err))
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
apiPut(options) {
|
|
174
|
+
if (typeof this.cancelToken[options.url] != typeof undefined) {
|
|
175
|
+
try {
|
|
176
|
+
this.cancelToken[options.url].cancel("Operation canceled due to new request.");
|
|
177
|
+
} catch (e) {
|
|
178
|
+
console.log(e);
|
|
179
|
+
return {};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
this.cancelToken[options.url] = axios.CancelToken.source();
|
|
184
|
+
const token = this.getToken();
|
|
185
|
+
|
|
186
|
+
if (token !== this.token || !token) {
|
|
187
|
+
this.reloadAxios();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return this.formatResponse(
|
|
191
|
+
this.api.put(options.url, options.data, {
|
|
192
|
+
cancelToken: this.cancelToken[options.url].token,
|
|
193
|
+
baseURL: options.baseURL || this.getBaseURL(options),
|
|
194
|
+
headers: {
|
|
195
|
+
Authorization: `Bearer ${this.getToken()}`,
|
|
196
|
+
...this.getHeaders(),
|
|
197
|
+
...(options?.headers || {}),
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
.catch((err) => this.onError(err, options.onUnauthorized))
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
apiPatch(options) {
|
|
205
|
+
const token = this.getToken();
|
|
206
|
+
|
|
207
|
+
if (token !== this.token || !token) {
|
|
208
|
+
this.reloadAxios();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return this.formatResponse(
|
|
212
|
+
this.api.patch(options.url, options.data, {
|
|
213
|
+
baseURL: options.baseURL || this.getBaseURL(options),
|
|
214
|
+
headers: {
|
|
215
|
+
Authorization: `Bearer ${this.getToken()}`,
|
|
216
|
+
...this.getHeaders(),
|
|
217
|
+
...(options?.headers || {}),
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
.catch((err) => this.onError(err))
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
// Utility method
|
|
226
|
+
assignParamsToUrl(path, params) {
|
|
227
|
+
return assignParamsToUrl(path, params);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export class ErrorHandler {
|
|
2
|
+
constructor(config = {}) {
|
|
3
|
+
this.store = config.store;
|
|
4
|
+
this.addToastAction = config.addToastAction;
|
|
5
|
+
this.formatData = config.formatData || this.defaultFormatData;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
handle({stats, statusText, data}) {
|
|
9
|
+
if(this.store && this.addToastAction) {
|
|
10
|
+
this.store.dispatch(this.addToastAction({
|
|
11
|
+
title: statusText,
|
|
12
|
+
type: 'danger',
|
|
13
|
+
body: this.formatData(data),
|
|
14
|
+
}));
|
|
15
|
+
} else {
|
|
16
|
+
console.error('Error: ', {stats, statusText, data});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
defaultFormatData(errors) {
|
|
21
|
+
if (!Array.isArray(errors)) {
|
|
22
|
+
return String(errors);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const e = [];
|
|
26
|
+
errors.forEach(error => {
|
|
27
|
+
if (error && typeof error === 'object' && error.constraints) {
|
|
28
|
+
Object.keys(error.constraints)
|
|
29
|
+
.forEach(key => e.push(error.constraints[key]));
|
|
30
|
+
} else if (typeof error === 'string') {
|
|
31
|
+
e.push(error);
|
|
32
|
+
} else {
|
|
33
|
+
e.push(JSON.stringify(error));
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return e.join('\n');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static createInstance(config) {
|
|
41
|
+
return new ErrorHandler(config);
|
|
42
|
+
}
|
|
43
|
+
}
|