@eztrak/shared 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -3
- package/dist/{chunk-WARJTN5T.mjs → chunk-POG3P25K.mjs} +57 -2
- package/dist/chunk-POG3P25K.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -1
- package/dist/utils/index.d.mts +19 -1
- package/dist/utils/index.d.ts +19 -1
- package/dist/utils/index.js +57 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +5 -1
- package/package.json +6 -2
- package/dist/chunk-WARJTN5T.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -8,12 +8,14 @@ Shared utilities, hooks, and UI components for Eztrak applications.
|
|
|
8
8
|
npm install @eztrak/shared
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Peer dependencies
|
|
11
|
+
Peer dependencies (hooks + `handleApiError`):
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npm install react react-dom react-router-dom
|
|
14
|
+
npm install react react-dom react-router-dom react-toastify sweetalert2
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
Your app must still render `<ToastContainer />` from react-toastify (as you already do).
|
|
18
|
+
|
|
17
19
|
## Usage
|
|
18
20
|
|
|
19
21
|
### Utils
|
|
@@ -26,6 +28,18 @@ import { cn, formatDate, getApiError, isEmpty } from "@eztrak/shared/utils";
|
|
|
26
28
|
|
|
27
29
|
`cn` combines [`clsx`](https://github.com/lukeed/clsx) with [`tailwind-merge`](https://github.com/dcastil/tailwind-merge).
|
|
28
30
|
|
|
31
|
+
RTK Query errors (toast or SweetAlert — no extra wiring):
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
import { handleApiError } from "@eztrak/shared/utils";
|
|
35
|
+
|
|
36
|
+
// Toasts each validation message (or a single generic error)
|
|
37
|
+
handleApiError(error, { fallbackMessage: "Save failed" });
|
|
38
|
+
|
|
39
|
+
// SweetAlert list for validation errors
|
|
40
|
+
handleApiError(error, { showAlert: true });
|
|
41
|
+
```
|
|
42
|
+
|
|
29
43
|
### Hooks
|
|
30
44
|
|
|
31
45
|
```js
|
|
@@ -45,7 +59,7 @@ import { cn, useGridHeight } from "@eztrak/shared";
|
|
|
45
59
|
| Subpath | Description |
|
|
46
60
|
| --- | --- |
|
|
47
61
|
| `@eztrak/shared` | Main entry — re-exports utils and hooks |
|
|
48
|
-
| `@eztrak/shared/utils` | `cn`, date/format helpers, API error helpers, form field helpers |
|
|
62
|
+
| `@eztrak/shared/utils` | `cn`, `handleApiError`, date/format helpers, API error helpers, form field helpers |
|
|
49
63
|
| `@eztrak/shared/hooks` | `usePaginationUrlSync`, `useGridHeight` |
|
|
50
64
|
|
|
51
65
|
## Requirements
|
|
@@ -186,6 +186,59 @@ var getFieldsByInputType = (fields = [], key) => {
|
|
|
186
186
|
return fields.filter(({ inputType = "" }) => inputType === key);
|
|
187
187
|
};
|
|
188
188
|
|
|
189
|
+
// src/utils/handleApiError.ts
|
|
190
|
+
import { toast } from "react-toastify";
|
|
191
|
+
import Swal from "sweetalert2";
|
|
192
|
+
function formatValidationErrorsHtml(errors) {
|
|
193
|
+
const items = Object.keys(errors).flatMap(
|
|
194
|
+
(field) => (errors[field] || []).map((msg) => `<li>${msg}</li>`)
|
|
195
|
+
);
|
|
196
|
+
return `
|
|
197
|
+
<div style="text-align:left">
|
|
198
|
+
<p>Please review and correct the following:</p>
|
|
199
|
+
<ul style="margin:8px 0 0 16px; list-style:disc;">
|
|
200
|
+
${items.join("")}
|
|
201
|
+
</ul>
|
|
202
|
+
</div>
|
|
203
|
+
`;
|
|
204
|
+
}
|
|
205
|
+
function showValidationAlert(html) {
|
|
206
|
+
void Swal.fire({
|
|
207
|
+
title: "Validation errors",
|
|
208
|
+
html,
|
|
209
|
+
icon: "error",
|
|
210
|
+
confirmButtonText: "OK",
|
|
211
|
+
showCancelButton: false,
|
|
212
|
+
confirmButtonColor: "#FF7335"
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function handleApiError(error, { showAlert = false, fallbackMessage } = {}) {
|
|
216
|
+
if (!error) return;
|
|
217
|
+
const status = error.status ?? error.originalStatus;
|
|
218
|
+
const data = error.data;
|
|
219
|
+
if (status === 200) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (data?.errors && typeof data.errors === "object") {
|
|
223
|
+
const errors = data.errors;
|
|
224
|
+
if (showAlert) {
|
|
225
|
+
showValidationAlert(formatValidationErrorsHtml(errors));
|
|
226
|
+
} else {
|
|
227
|
+
Object.keys(errors).forEach((field) => {
|
|
228
|
+
(errors[field] || []).forEach((errorMessage) => {
|
|
229
|
+
toast.error(errorMessage);
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (status === 404) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const message = fallbackMessage || data?.message || data?.title || error.error || "An error occurred. Please try again.";
|
|
239
|
+
toast.error(message);
|
|
240
|
+
}
|
|
241
|
+
|
|
189
242
|
export {
|
|
190
243
|
cn,
|
|
191
244
|
truncateText,
|
|
@@ -207,6 +260,8 @@ export {
|
|
|
207
260
|
deserializeJson,
|
|
208
261
|
formatDateTime,
|
|
209
262
|
removeByPropertyValues,
|
|
210
|
-
getFieldsByInputType
|
|
263
|
+
getFieldsByInputType,
|
|
264
|
+
formatValidationErrorsHtml,
|
|
265
|
+
handleApiError
|
|
211
266
|
};
|
|
212
|
-
//# sourceMappingURL=chunk-
|
|
267
|
+
//# sourceMappingURL=chunk-POG3P25K.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/cn.ts","../src/utils/helpers.ts","../src/utils/handleApiError.ts"],"sourcesContent":["import clsx from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: Parameters<typeof clsx>) {\r\n return twMerge(clsx(inputs));\r\n}\r\n","export const truncateText = (text: string | null | undefined, maxLength = 20) => {\n if (!text) return \"\";\n if (text.length <= maxLength) {\n return text;\n }\n return text.slice(0, maxLength - 3) + \"...\";\n};\n\nexport function getApiError(apiError: unknown): string {\n if (!apiError) return \"An unknown error occurred\";\n\n if (typeof apiError === \"string\") {\n return apiError;\n }\n\n const error = apiError as {\n response?: { data?: Record<string, unknown> };\n message?: string;\n };\n\n if (error.response?.data) {\n const responseData = error.response.data;\n\n if (typeof responseData === \"string\") {\n return responseData;\n }\n\n const errors = responseData.errors;\n if (errors && typeof errors === \"object\") {\n for (const key in errors) {\n const messages = (errors as Record<string, unknown>)[key];\n if (Array.isArray(messages) && messages.length > 0) {\n return String(messages[0]);\n }\n }\n }\n\n if (responseData.message) {\n return String(responseData.message);\n }\n\n if (responseData.title) {\n return String(responseData.title);\n }\n }\n\n if (error.message) {\n return error.message;\n }\n\n return \"An unknown error occurred\";\n}\n\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\n if (responseData == null) return [];\n if (Array.isArray(responseData)) return responseData;\n\n const record = responseData as Record<string, unknown>;\n const data = record.data;\n\n if (\n data &&\n typeof data === \"object\" &&\n !Array.isArray(data) &&\n Array.isArray((data as { items?: unknown[] }).items)\n ) {\n return (data as { items: unknown[] }).items;\n }\n\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\n if (Array.isArray(returnModel?.items)) return returnModel.items;\n if (Array.isArray(data)) return data;\n if (typeof data === \"object\" && data !== null) {\n return [data];\n }\n return [];\n};\n\nexport function capitalizeText(name: string | null | undefined): string {\n if (!name) return \"\";\n return name\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\nexport function toLowerCaseText(text: string | null | undefined): string {\n if (!text) return \"\";\n return text.toLowerCase();\n}\n\nexport const formatDate = (dateString: string | null | undefined): string => {\n if (dateString === null || dateString === undefined) return \"-\";\n const date = new Date(dateString);\n\n if (isNaN(date.getTime())) {\n return dateString;\n }\n\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\n const day = date.getDate().toString().padStart(2, \"0\");\n const year = date.getFullYear().toString().slice(-2);\n return `${month}/${day}/${year}`;\n};\n\nexport const isEmpty = (obj: object): boolean => {\n return Object.keys(obj).length === 0;\n};\n\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\n if (!date) return \"\";\n\n let d: Date;\n\n if (typeof date === \"string\") {\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n return date;\n }\n d = new Date(date);\n } else {\n d = new Date(date);\n }\n\n if (isNaN(d.getTime())) return \"\";\n\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\n const year = localDate.getFullYear();\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\n const day = localDate.getDate().toString().padStart(2, \"0\");\n\n return `${year}-${month}-${day}`;\n};\n\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\n if (!data || data.trim() === \"\") {\n return [];\n }\n return data.split(\",\").map((item) => item.trim());\n}\n\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\n return array.includes(searchValue);\n}\n\nexport const currencyFormatter = (value: number | null | undefined): string => {\n return value?.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n }) ?? \"\";\n};\n\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\n if (value == null || value === \"\") return 0;\n\n const raw =\n typeof value === \"object\" && value !== null && \"value\" in value\n ? (value as { value: unknown }).value\n : value;\n\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\n const numericValue = stringValue.replace(/[$,]/g, \"\");\n return parseFloat(numericValue) || 0;\n};\n\nexport function flattenTableData<T extends Record<string, unknown>>(\n data: T[] | null | undefined,\n columns: { field?: string }[] | null | undefined\n): T[] {\n if (!Array.isArray(data)) return [];\n return data.map((row) => {\n const flatRow = { ...row };\n (columns ?? []).forEach((col) => {\n const key = col.field;\n if (!key) return;\n if (key.includes(\".\")) {\n const value = key.split(\".\").reduce<unknown>(\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\n row\n );\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\n }\n });\n return flatRow;\n });\n}\n\nexport const getErrorMessages = (error: {\n data?: {\n errors?: Record<string, string[]>;\n title?: string;\n error?: { name?: string[] };\n };\n} | null | undefined): string => {\n if (error?.data?.errors) {\n return Object.values(error.data.errors).flat().join(\"\\n\");\n }\n return (\n error?.data?.title ??\n error?.data?.error?.name?.[0] ??\n \"Failed to save\"\n );\n};\n\nexport const getFieldsByCategory = <T extends { category?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields?.filter(({ category = \"\" }) => category === key);\n};\n\nexport const getFieldsByName = <T extends { name?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ name = \"\" }) => name === key);\n};\n\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\n try {\n return JSON.parse(jsonString) as T;\n } catch (error) {\n console.error(\"Error parsing JSON:\", error);\n return null;\n }\n};\n\nexport const formatDateTime = (dateString: string | null | undefined): string => {\n if (!dateString) return \"Invalid Date\";\n const date = new Date(dateString);\n if (isNaN(date.getTime())) return \"Invalid Date\";\n const options: Intl.DateTimeFormatOptions = {\n year: \"numeric\",\n month: \"numeric\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n hour12: true,\n };\n return date.toLocaleString(\"en-US\", options);\n};\n\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\n items: T[] = [],\n property: keyof T & string,\n values: unknown[] = [],\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\n): T[] => {\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\n const normalize = (v: unknown) =>\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\n const valuesArr = Array.isArray(values) ? values : [values];\n const toRemove = new Set(valuesArr.map(normalize));\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\n};\n\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ inputType = \"\" }) => inputType === key);\n};\n","import { toast } from \"react-toastify\";\nimport Swal from \"sweetalert2\";\n\nexport type RtkQueryError = {\n status?: number | string;\n originalStatus?: number;\n data?: {\n errors?: Record<string, string[]>;\n message?: string;\n title?: string;\n };\n error?: string;\n};\n\nexport interface HandleApiErrorOptions {\n showAlert?: boolean;\n fallbackMessage?: string;\n}\n\nexport function formatValidationErrorsHtml(\n errors: Record<string, string[]>\n): string {\n const items = Object.keys(errors).flatMap((field) =>\n (errors[field] || []).map((msg) => `<li>${msg}</li>`)\n );\n return `\n <div style=\"text-align:left\">\n <p>Please review and correct the following:</p>\n <ul style=\"margin:8px 0 0 16px; list-style:disc;\">\n ${items.join(\"\")}\n </ul>\n </div>\n `;\n}\n\nfunction showValidationAlert(html: string): void {\n void Swal.fire({\n title: \"Validation errors\",\n html,\n icon: \"error\",\n confirmButtonText: \"OK\",\n showCancelButton: false,\n confirmButtonColor: \"#FF7335\",\n });\n}\n\n/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */\nexport function handleApiError(\n error: RtkQueryError | null | undefined,\n { showAlert = false, fallbackMessage }: HandleApiErrorOptions = {}\n): void {\n if (!error) return;\n\n const status = error.status ?? error.originalStatus;\n const data = error.data;\n\n if (status === 200) {\n return;\n }\n\n if (data?.errors && typeof data.errors === \"object\") {\n const errors = data.errors;\n\n if (showAlert) {\n showValidationAlert(formatValidationErrorsHtml(errors));\n } else {\n Object.keys(errors).forEach((field) => {\n (errors[field] || []).forEach((errorMessage) => {\n toast.error(errorMessage);\n });\n });\n }\n return;\n }\n\n if (status === 404) {\n return;\n }\n\n const message =\n fallbackMessage ||\n data?.message ||\n data?.title ||\n error.error ||\n \"An error occurred. Please try again.\";\n\n toast.error(message);\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { capitalizeText, checkIfExistsInArray, cn, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText } from './utils/index.mjs';
|
|
1
|
+
export { HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText } from './utils/index.mjs';
|
|
2
2
|
export { UseGridHeightOptions, useGridHeight, usePaginationUrlSync } from './hooks/index.mjs';
|
|
3
3
|
import 'clsx';
|
|
4
4
|
import 'react-router-dom';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { capitalizeText, checkIfExistsInArray, cn, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText } from './utils/index.js';
|
|
1
|
+
export { HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText } from './utils/index.js';
|
|
2
2
|
export { UseGridHeightOptions, useGridHeight, usePaginationUrlSync } from './hooks/index.js';
|
|
3
3
|
import 'clsx';
|
|
4
4
|
import 'react-router-dom';
|
package/dist/index.js
CHANGED
|
@@ -39,11 +39,13 @@ __export(src_exports, {
|
|
|
39
39
|
flattenTableData: () => flattenTableData,
|
|
40
40
|
formatDate: () => formatDate,
|
|
41
41
|
formatDateTime: () => formatDateTime,
|
|
42
|
+
formatValidationErrorsHtml: () => formatValidationErrorsHtml,
|
|
42
43
|
getApiError: () => getApiError,
|
|
43
44
|
getErrorMessages: () => getErrorMessages,
|
|
44
45
|
getFieldsByCategory: () => getFieldsByCategory,
|
|
45
46
|
getFieldsByInputType: () => getFieldsByInputType,
|
|
46
47
|
getFieldsByName: () => getFieldsByName,
|
|
48
|
+
handleApiError: () => handleApiError,
|
|
47
49
|
isEmpty: () => isEmpty,
|
|
48
50
|
normalizeApiListItems: () => normalizeApiListItems,
|
|
49
51
|
parseCurrencyValueToNumber: () => parseCurrencyValueToNumber,
|
|
@@ -244,6 +246,59 @@ var getFieldsByInputType = (fields = [], key) => {
|
|
|
244
246
|
return fields.filter(({ inputType = "" }) => inputType === key);
|
|
245
247
|
};
|
|
246
248
|
|
|
249
|
+
// src/utils/handleApiError.ts
|
|
250
|
+
var import_react_toastify = require("react-toastify");
|
|
251
|
+
var import_sweetalert2 = __toESM(require("sweetalert2"));
|
|
252
|
+
function formatValidationErrorsHtml(errors) {
|
|
253
|
+
const items = Object.keys(errors).flatMap(
|
|
254
|
+
(field) => (errors[field] || []).map((msg) => `<li>${msg}</li>`)
|
|
255
|
+
);
|
|
256
|
+
return `
|
|
257
|
+
<div style="text-align:left">
|
|
258
|
+
<p>Please review and correct the following:</p>
|
|
259
|
+
<ul style="margin:8px 0 0 16px; list-style:disc;">
|
|
260
|
+
${items.join("")}
|
|
261
|
+
</ul>
|
|
262
|
+
</div>
|
|
263
|
+
`;
|
|
264
|
+
}
|
|
265
|
+
function showValidationAlert(html) {
|
|
266
|
+
void import_sweetalert2.default.fire({
|
|
267
|
+
title: "Validation errors",
|
|
268
|
+
html,
|
|
269
|
+
icon: "error",
|
|
270
|
+
confirmButtonText: "OK",
|
|
271
|
+
showCancelButton: false,
|
|
272
|
+
confirmButtonColor: "#FF7335"
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
function handleApiError(error, { showAlert = false, fallbackMessage } = {}) {
|
|
276
|
+
if (!error) return;
|
|
277
|
+
const status = error.status ?? error.originalStatus;
|
|
278
|
+
const data = error.data;
|
|
279
|
+
if (status === 200) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (data?.errors && typeof data.errors === "object") {
|
|
283
|
+
const errors = data.errors;
|
|
284
|
+
if (showAlert) {
|
|
285
|
+
showValidationAlert(formatValidationErrorsHtml(errors));
|
|
286
|
+
} else {
|
|
287
|
+
Object.keys(errors).forEach((field) => {
|
|
288
|
+
(errors[field] || []).forEach((errorMessage) => {
|
|
289
|
+
import_react_toastify.toast.error(errorMessage);
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (status === 404) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
const message = fallbackMessage || data?.message || data?.title || error.error || "An error occurred. Please try again.";
|
|
299
|
+
import_react_toastify.toast.error(message);
|
|
300
|
+
}
|
|
301
|
+
|
|
247
302
|
// src/hooks/usePaginationUrlSync.ts
|
|
248
303
|
var import_react = require("react");
|
|
249
304
|
var usePaginationUrlSync = (searchParams, setSearchParams, page, setPage, perPage, setPerPage, defaultPage = 1, defaultPerPage = 20) => {
|
|
@@ -321,11 +376,13 @@ var useGridHeight = ({
|
|
|
321
376
|
flattenTableData,
|
|
322
377
|
formatDate,
|
|
323
378
|
formatDateTime,
|
|
379
|
+
formatValidationErrorsHtml,
|
|
324
380
|
getApiError,
|
|
325
381
|
getErrorMessages,
|
|
326
382
|
getFieldsByCategory,
|
|
327
383
|
getFieldsByInputType,
|
|
328
384
|
getFieldsByName,
|
|
385
|
+
handleApiError,
|
|
329
386
|
isEmpty,
|
|
330
387
|
normalizeApiListItems,
|
|
331
388
|
parseCurrencyValueToNumber,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils/cn.ts","../src/utils/helpers.ts","../src/hooks/usePaginationUrlSync.ts","../src/hooks/useGridHeight.ts"],"sourcesContent":["export * from \"./utils\";\nexport * from \"./hooks\";\n","import clsx from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: Parameters<typeof clsx>) {\r\n return twMerge(clsx(inputs));\r\n}\r\n","export const truncateText = (text: string | null | undefined, maxLength = 20) => {\n if (!text) return \"\";\n if (text.length <= maxLength) {\n return text;\n }\n return text.slice(0, maxLength - 3) + \"...\";\n};\n\nexport function getApiError(apiError: unknown): string {\n if (!apiError) return \"An unknown error occurred\";\n\n if (typeof apiError === \"string\") {\n return apiError;\n }\n\n const error = apiError as {\n response?: { data?: Record<string, unknown> };\n message?: string;\n };\n\n if (error.response?.data) {\n const responseData = error.response.data;\n\n if (typeof responseData === \"string\") {\n return responseData;\n }\n\n const errors = responseData.errors;\n if (errors && typeof errors === \"object\") {\n for (const key in errors) {\n const messages = (errors as Record<string, unknown>)[key];\n if (Array.isArray(messages) && messages.length > 0) {\n return String(messages[0]);\n }\n }\n }\n\n if (responseData.message) {\n return String(responseData.message);\n }\n\n if (responseData.title) {\n return String(responseData.title);\n }\n }\n\n if (error.message) {\n return error.message;\n }\n\n return \"An unknown error occurred\";\n}\n\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\n if (responseData == null) return [];\n if (Array.isArray(responseData)) return responseData;\n\n const record = responseData as Record<string, unknown>;\n const data = record.data;\n\n if (\n data &&\n typeof data === \"object\" &&\n !Array.isArray(data) &&\n Array.isArray((data as { items?: unknown[] }).items)\n ) {\n return (data as { items: unknown[] }).items;\n }\n\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\n if (Array.isArray(returnModel?.items)) return returnModel.items;\n if (Array.isArray(data)) return data;\n if (typeof data === \"object\" && data !== null) {\n return [data];\n }\n return [];\n};\n\nexport function capitalizeText(name: string | null | undefined): string {\n if (!name) return \"\";\n return name\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\nexport function toLowerCaseText(text: string | null | undefined): string {\n if (!text) return \"\";\n return text.toLowerCase();\n}\n\nexport const formatDate = (dateString: string | null | undefined): string => {\n if (dateString === null || dateString === undefined) return \"-\";\n const date = new Date(dateString);\n\n if (isNaN(date.getTime())) {\n return dateString;\n }\n\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\n const day = date.getDate().toString().padStart(2, \"0\");\n const year = date.getFullYear().toString().slice(-2);\n return `${month}/${day}/${year}`;\n};\n\nexport const isEmpty = (obj: object): boolean => {\n return Object.keys(obj).length === 0;\n};\n\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\n if (!date) return \"\";\n\n let d: Date;\n\n if (typeof date === \"string\") {\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n return date;\n }\n d = new Date(date);\n } else {\n d = new Date(date);\n }\n\n if (isNaN(d.getTime())) return \"\";\n\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\n const year = localDate.getFullYear();\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\n const day = localDate.getDate().toString().padStart(2, \"0\");\n\n return `${year}-${month}-${day}`;\n};\n\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\n if (!data || data.trim() === \"\") {\n return [];\n }\n return data.split(\",\").map((item) => item.trim());\n}\n\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\n return array.includes(searchValue);\n}\n\nexport const currencyFormatter = (value: number | null | undefined): string => {\n return value?.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n }) ?? \"\";\n};\n\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\n if (value == null || value === \"\") return 0;\n\n const raw =\n typeof value === \"object\" && value !== null && \"value\" in value\n ? (value as { value: unknown }).value\n : value;\n\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\n const numericValue = stringValue.replace(/[$,]/g, \"\");\n return parseFloat(numericValue) || 0;\n};\n\nexport function flattenTableData<T extends Record<string, unknown>>(\n data: T[] | null | undefined,\n columns: { field?: string }[] | null | undefined\n): T[] {\n if (!Array.isArray(data)) return [];\n return data.map((row) => {\n const flatRow = { ...row };\n (columns ?? []).forEach((col) => {\n const key = col.field;\n if (!key) return;\n if (key.includes(\".\")) {\n const value = key.split(\".\").reduce<unknown>(\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\n row\n );\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\n }\n });\n return flatRow;\n });\n}\n\nexport const getErrorMessages = (error: {\n data?: {\n errors?: Record<string, string[]>;\n title?: string;\n error?: { name?: string[] };\n };\n} | null | undefined): string => {\n if (error?.data?.errors) {\n return Object.values(error.data.errors).flat().join(\"\\n\");\n }\n return (\n error?.data?.title ??\n error?.data?.error?.name?.[0] ??\n \"Failed to save\"\n );\n};\n\nexport const getFieldsByCategory = <T extends { category?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields?.filter(({ category = \"\" }) => category === key);\n};\n\nexport const getFieldsByName = <T extends { name?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ name = \"\" }) => name === key);\n};\n\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\n try {\n return JSON.parse(jsonString) as T;\n } catch (error) {\n console.error(\"Error parsing JSON:\", error);\n return null;\n }\n};\n\nexport const formatDateTime = (dateString: string | null | undefined): string => {\n if (!dateString) return \"Invalid Date\";\n const date = new Date(dateString);\n if (isNaN(date.getTime())) return \"Invalid Date\";\n const options: Intl.DateTimeFormatOptions = {\n year: \"numeric\",\n month: \"numeric\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n hour12: true,\n };\n return date.toLocaleString(\"en-US\", options);\n};\n\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\n items: T[] = [],\n property: keyof T & string,\n values: unknown[] = [],\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\n): T[] => {\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\n const normalize = (v: unknown) =>\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\n const valuesArr = Array.isArray(values) ? values : [values];\n const toRemove = new Set(valuesArr.map(normalize));\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\n};\n\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ inputType = \"\" }) => inputType === key);\n};\n","import { useEffect } from \"react\";\nimport type { SetURLSearchParams } from \"react-router-dom\";\n\nexport const usePaginationUrlSync = (\n searchParams: URLSearchParams,\n setSearchParams: SetURLSearchParams,\n page: number,\n setPage: (page: number) => void,\n perPage: number,\n setPerPage: (perPage: number) => void,\n defaultPage = 1,\n defaultPerPage = 20\n) => {\n useEffect(() => {\n const currentUrlPage = parseInt(searchParams.get(\"page\") ?? \"\") || defaultPage;\n const currentUrlPerPage =\n parseInt(searchParams.get(\"perPage\") ?? \"\") || defaultPerPage;\n const hasPageParam = searchParams.has(\"page\");\n const hasPerPageParam = searchParams.has(\"perPage\");\n\n if (!hasPageParam || !hasPerPageParam) {\n const newParams = new URLSearchParams(searchParams);\n\n if (!hasPageParam) {\n newParams.set(\"page\", defaultPage.toString());\n }\n\n if (!hasPerPageParam) {\n newParams.set(\"perPage\", defaultPerPage.toString());\n }\n\n setSearchParams(newParams, { replace: true });\n return;\n }\n\n if (currentUrlPage !== page) {\n setPage(currentUrlPage);\n }\n\n if (currentUrlPerPage !== perPage) {\n setPerPage(currentUrlPerPage);\n }\n }, [\n searchParams,\n setSearchParams,\n page,\n setPage,\n perPage,\n setPerPage,\n defaultPage,\n defaultPerPage,\n ]);\n};\n","import { useEffect, useState } from \"react\";\n\nexport interface UseGridHeightOptions {\n height?: string;\n headerId?: string;\n footerId?: string;\n offset?: number;\n}\n\nexport const useGridHeight = ({\n height,\n headerId = \"layout-header\",\n footerId = \"layout-footer\",\n offset = 390,\n}: UseGridHeightOptions = {}) => {\n const [gridHeight, setGridHeight] = useState(height || \"300px\");\n\n useEffect(() => {\n if (height) {\n setGridHeight(height);\n return;\n }\n\n const calculateHeight = () => {\n const header = document.getElementById(headerId);\n const footer = document.getElementById(footerId);\n\n const headerHeight = header ? header.offsetHeight : 0;\n const footerHeight = footer ? footer.offsetHeight : 0;\n const totalHeight = window.innerHeight;\n\n const remainingHeight = totalHeight - headerHeight - footerHeight - offset;\n setGridHeight(`${remainingHeight}px`);\n };\n\n calculateHeight();\n window.addEventListener(\"resize\", calculateHeight);\n return () => window.removeEventListener(\"resize\", calculateHeight);\n }, [height, headerId, footerId, offset]);\n\n return gridHeight;\n};\n"],"mappings":"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","names":["clsx","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils/cn.ts","../src/utils/helpers.ts","../src/utils/handleApiError.ts","../src/hooks/usePaginationUrlSync.ts","../src/hooks/useGridHeight.ts"],"sourcesContent":["export * from \"./utils\";\nexport * from \"./hooks\";\n","import clsx from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: Parameters<typeof clsx>) {\r\n return twMerge(clsx(inputs));\r\n}\r\n","export const truncateText = (text: string | null | undefined, maxLength = 20) => {\n if (!text) return \"\";\n if (text.length <= maxLength) {\n return text;\n }\n return text.slice(0, maxLength - 3) + \"...\";\n};\n\nexport function getApiError(apiError: unknown): string {\n if (!apiError) return \"An unknown error occurred\";\n\n if (typeof apiError === \"string\") {\n return apiError;\n }\n\n const error = apiError as {\n response?: { data?: Record<string, unknown> };\n message?: string;\n };\n\n if (error.response?.data) {\n const responseData = error.response.data;\n\n if (typeof responseData === \"string\") {\n return responseData;\n }\n\n const errors = responseData.errors;\n if (errors && typeof errors === \"object\") {\n for (const key in errors) {\n const messages = (errors as Record<string, unknown>)[key];\n if (Array.isArray(messages) && messages.length > 0) {\n return String(messages[0]);\n }\n }\n }\n\n if (responseData.message) {\n return String(responseData.message);\n }\n\n if (responseData.title) {\n return String(responseData.title);\n }\n }\n\n if (error.message) {\n return error.message;\n }\n\n return \"An unknown error occurred\";\n}\n\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\n if (responseData == null) return [];\n if (Array.isArray(responseData)) return responseData;\n\n const record = responseData as Record<string, unknown>;\n const data = record.data;\n\n if (\n data &&\n typeof data === \"object\" &&\n !Array.isArray(data) &&\n Array.isArray((data as { items?: unknown[] }).items)\n ) {\n return (data as { items: unknown[] }).items;\n }\n\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\n if (Array.isArray(returnModel?.items)) return returnModel.items;\n if (Array.isArray(data)) return data;\n if (typeof data === \"object\" && data !== null) {\n return [data];\n }\n return [];\n};\n\nexport function capitalizeText(name: string | null | undefined): string {\n if (!name) return \"\";\n return name\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\nexport function toLowerCaseText(text: string | null | undefined): string {\n if (!text) return \"\";\n return text.toLowerCase();\n}\n\nexport const formatDate = (dateString: string | null | undefined): string => {\n if (dateString === null || dateString === undefined) return \"-\";\n const date = new Date(dateString);\n\n if (isNaN(date.getTime())) {\n return dateString;\n }\n\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\n const day = date.getDate().toString().padStart(2, \"0\");\n const year = date.getFullYear().toString().slice(-2);\n return `${month}/${day}/${year}`;\n};\n\nexport const isEmpty = (obj: object): boolean => {\n return Object.keys(obj).length === 0;\n};\n\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\n if (!date) return \"\";\n\n let d: Date;\n\n if (typeof date === \"string\") {\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n return date;\n }\n d = new Date(date);\n } else {\n d = new Date(date);\n }\n\n if (isNaN(d.getTime())) return \"\";\n\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\n const year = localDate.getFullYear();\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\n const day = localDate.getDate().toString().padStart(2, \"0\");\n\n return `${year}-${month}-${day}`;\n};\n\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\n if (!data || data.trim() === \"\") {\n return [];\n }\n return data.split(\",\").map((item) => item.trim());\n}\n\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\n return array.includes(searchValue);\n}\n\nexport const currencyFormatter = (value: number | null | undefined): string => {\n return value?.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n }) ?? \"\";\n};\n\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\n if (value == null || value === \"\") return 0;\n\n const raw =\n typeof value === \"object\" && value !== null && \"value\" in value\n ? (value as { value: unknown }).value\n : value;\n\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\n const numericValue = stringValue.replace(/[$,]/g, \"\");\n return parseFloat(numericValue) || 0;\n};\n\nexport function flattenTableData<T extends Record<string, unknown>>(\n data: T[] | null | undefined,\n columns: { field?: string }[] | null | undefined\n): T[] {\n if (!Array.isArray(data)) return [];\n return data.map((row) => {\n const flatRow = { ...row };\n (columns ?? []).forEach((col) => {\n const key = col.field;\n if (!key) return;\n if (key.includes(\".\")) {\n const value = key.split(\".\").reduce<unknown>(\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\n row\n );\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\n }\n });\n return flatRow;\n });\n}\n\nexport const getErrorMessages = (error: {\n data?: {\n errors?: Record<string, string[]>;\n title?: string;\n error?: { name?: string[] };\n };\n} | null | undefined): string => {\n if (error?.data?.errors) {\n return Object.values(error.data.errors).flat().join(\"\\n\");\n }\n return (\n error?.data?.title ??\n error?.data?.error?.name?.[0] ??\n \"Failed to save\"\n );\n};\n\nexport const getFieldsByCategory = <T extends { category?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields?.filter(({ category = \"\" }) => category === key);\n};\n\nexport const getFieldsByName = <T extends { name?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ name = \"\" }) => name === key);\n};\n\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\n try {\n return JSON.parse(jsonString) as T;\n } catch (error) {\n console.error(\"Error parsing JSON:\", error);\n return null;\n }\n};\n\nexport const formatDateTime = (dateString: string | null | undefined): string => {\n if (!dateString) return \"Invalid Date\";\n const date = new Date(dateString);\n if (isNaN(date.getTime())) return \"Invalid Date\";\n const options: Intl.DateTimeFormatOptions = {\n year: \"numeric\",\n month: \"numeric\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n hour12: true,\n };\n return date.toLocaleString(\"en-US\", options);\n};\n\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\n items: T[] = [],\n property: keyof T & string,\n values: unknown[] = [],\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\n): T[] => {\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\n const normalize = (v: unknown) =>\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\n const valuesArr = Array.isArray(values) ? values : [values];\n const toRemove = new Set(valuesArr.map(normalize));\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\n};\n\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ inputType = \"\" }) => inputType === key);\n};\n","import { toast } from \"react-toastify\";\nimport Swal from \"sweetalert2\";\n\nexport type RtkQueryError = {\n status?: number | string;\n originalStatus?: number;\n data?: {\n errors?: Record<string, string[]>;\n message?: string;\n title?: string;\n };\n error?: string;\n};\n\nexport interface HandleApiErrorOptions {\n showAlert?: boolean;\n fallbackMessage?: string;\n}\n\nexport function formatValidationErrorsHtml(\n errors: Record<string, string[]>\n): string {\n const items = Object.keys(errors).flatMap((field) =>\n (errors[field] || []).map((msg) => `<li>${msg}</li>`)\n );\n return `\n <div style=\"text-align:left\">\n <p>Please review and correct the following:</p>\n <ul style=\"margin:8px 0 0 16px; list-style:disc;\">\n ${items.join(\"\")}\n </ul>\n </div>\n `;\n}\n\nfunction showValidationAlert(html: string): void {\n void Swal.fire({\n title: \"Validation errors\",\n html,\n icon: \"error\",\n confirmButtonText: \"OK\",\n showCancelButton: false,\n confirmButtonColor: \"#FF7335\",\n });\n}\n\n/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */\nexport function handleApiError(\n error: RtkQueryError | null | undefined,\n { showAlert = false, fallbackMessage }: HandleApiErrorOptions = {}\n): void {\n if (!error) return;\n\n const status = error.status ?? error.originalStatus;\n const data = error.data;\n\n if (status === 200) {\n return;\n }\n\n if (data?.errors && typeof data.errors === \"object\") {\n const errors = data.errors;\n\n if (showAlert) {\n showValidationAlert(formatValidationErrorsHtml(errors));\n } else {\n Object.keys(errors).forEach((field) => {\n (errors[field] || []).forEach((errorMessage) => {\n toast.error(errorMessage);\n });\n });\n }\n return;\n }\n\n if (status === 404) {\n return;\n }\n\n const message =\n fallbackMessage ||\n data?.message ||\n data?.title ||\n error.error ||\n \"An error occurred. Please try again.\";\n\n toast.error(message);\n}\n","import { useEffect } from \"react\";\nimport type { SetURLSearchParams } from \"react-router-dom\";\n\nexport const usePaginationUrlSync = (\n searchParams: URLSearchParams,\n setSearchParams: SetURLSearchParams,\n page: number,\n setPage: (page: number) => void,\n perPage: number,\n setPerPage: (perPage: number) => void,\n defaultPage = 1,\n defaultPerPage = 20\n) => {\n useEffect(() => {\n const currentUrlPage = parseInt(searchParams.get(\"page\") ?? \"\") || defaultPage;\n const currentUrlPerPage =\n parseInt(searchParams.get(\"perPage\") ?? \"\") || defaultPerPage;\n const hasPageParam = searchParams.has(\"page\");\n const hasPerPageParam = searchParams.has(\"perPage\");\n\n if (!hasPageParam || !hasPerPageParam) {\n const newParams = new URLSearchParams(searchParams);\n\n if (!hasPageParam) {\n newParams.set(\"page\", defaultPage.toString());\n }\n\n if (!hasPerPageParam) {\n newParams.set(\"perPage\", defaultPerPage.toString());\n }\n\n setSearchParams(newParams, { replace: true });\n return;\n }\n\n if (currentUrlPage !== page) {\n setPage(currentUrlPage);\n }\n\n if (currentUrlPerPage !== perPage) {\n setPerPage(currentUrlPerPage);\n }\n }, [\n searchParams,\n setSearchParams,\n page,\n setPage,\n perPage,\n setPerPage,\n defaultPage,\n defaultPerPage,\n ]);\n};\n","import { useEffect, useState } from \"react\";\n\nexport interface UseGridHeightOptions {\n height?: string;\n headerId?: string;\n footerId?: string;\n offset?: number;\n}\n\nexport const useGridHeight = ({\n height,\n headerId = \"layout-header\",\n footerId = \"layout-footer\",\n offset = 390,\n}: UseGridHeightOptions = {}) => {\n const [gridHeight, setGridHeight] = useState(height || \"300px\");\n\n useEffect(() => {\n if (height) {\n setGridHeight(height);\n return;\n }\n\n const calculateHeight = () => {\n const header = document.getElementById(headerId);\n const footer = document.getElementById(footerId);\n\n const headerHeight = header ? header.offsetHeight : 0;\n const footerHeight = footer ? footer.offsetHeight : 0;\n const totalHeight = window.innerHeight;\n\n const remainingHeight = totalHeight - headerHeight - footerHeight - offset;\n setGridHeight(`${remainingHeight}px`);\n };\n\n calculateHeight();\n window.addEventListener(\"resize\", calculateHeight);\n return () => window.removeEventListener(\"resize\", calculateHeight);\n }, [height, headerId, footerId, offset]);\n\n return gridHeight;\n};\n"],"mappings":"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","names":["clsx","Swal","import_react"]}
|
package/dist/index.mjs
CHANGED
|
@@ -8,11 +8,13 @@ import {
|
|
|
8
8
|
flattenTableData,
|
|
9
9
|
formatDate,
|
|
10
10
|
formatDateTime,
|
|
11
|
+
formatValidationErrorsHtml,
|
|
11
12
|
getApiError,
|
|
12
13
|
getErrorMessages,
|
|
13
14
|
getFieldsByCategory,
|
|
14
15
|
getFieldsByInputType,
|
|
15
16
|
getFieldsByName,
|
|
17
|
+
handleApiError,
|
|
16
18
|
isEmpty,
|
|
17
19
|
normalizeApiListItems,
|
|
18
20
|
parseCurrencyValueToNumber,
|
|
@@ -20,7 +22,7 @@ import {
|
|
|
20
22
|
toDateInputValue,
|
|
21
23
|
toLowerCaseText,
|
|
22
24
|
truncateText
|
|
23
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-POG3P25K.mjs";
|
|
24
26
|
import {
|
|
25
27
|
useGridHeight,
|
|
26
28
|
usePaginationUrlSync
|
|
@@ -35,11 +37,13 @@ export {
|
|
|
35
37
|
flattenTableData,
|
|
36
38
|
formatDate,
|
|
37
39
|
formatDateTime,
|
|
40
|
+
formatValidationErrorsHtml,
|
|
38
41
|
getApiError,
|
|
39
42
|
getErrorMessages,
|
|
40
43
|
getFieldsByCategory,
|
|
41
44
|
getFieldsByInputType,
|
|
42
45
|
getFieldsByName,
|
|
46
|
+
handleApiError,
|
|
43
47
|
isEmpty,
|
|
44
48
|
normalizeApiListItems,
|
|
45
49
|
parseCurrencyValueToNumber,
|
package/dist/utils/index.d.mts
CHANGED
|
@@ -41,4 +41,22 @@ declare const getFieldsByInputType: <T extends {
|
|
|
41
41
|
inputType?: string;
|
|
42
42
|
}>(fields: T[] | undefined, key: string) => T[];
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
type RtkQueryError = {
|
|
45
|
+
status?: number | string;
|
|
46
|
+
originalStatus?: number;
|
|
47
|
+
data?: {
|
|
48
|
+
errors?: Record<string, string[]>;
|
|
49
|
+
message?: string;
|
|
50
|
+
title?: string;
|
|
51
|
+
};
|
|
52
|
+
error?: string;
|
|
53
|
+
};
|
|
54
|
+
interface HandleApiErrorOptions {
|
|
55
|
+
showAlert?: boolean;
|
|
56
|
+
fallbackMessage?: string;
|
|
57
|
+
}
|
|
58
|
+
declare function formatValidationErrorsHtml(errors: Record<string, string[]>): string;
|
|
59
|
+
/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */
|
|
60
|
+
declare function handleApiError(error: RtkQueryError | null | undefined, { showAlert, fallbackMessage }?: HandleApiErrorOptions): void;
|
|
61
|
+
|
|
62
|
+
export { type HandleApiErrorOptions, type RtkQueryError, capitalizeText, checkIfExistsInArray, cn, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -41,4 +41,22 @@ declare const getFieldsByInputType: <T extends {
|
|
|
41
41
|
inputType?: string;
|
|
42
42
|
}>(fields: T[] | undefined, key: string) => T[];
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
type RtkQueryError = {
|
|
45
|
+
status?: number | string;
|
|
46
|
+
originalStatus?: number;
|
|
47
|
+
data?: {
|
|
48
|
+
errors?: Record<string, string[]>;
|
|
49
|
+
message?: string;
|
|
50
|
+
title?: string;
|
|
51
|
+
};
|
|
52
|
+
error?: string;
|
|
53
|
+
};
|
|
54
|
+
interface HandleApiErrorOptions {
|
|
55
|
+
showAlert?: boolean;
|
|
56
|
+
fallbackMessage?: string;
|
|
57
|
+
}
|
|
58
|
+
declare function formatValidationErrorsHtml(errors: Record<string, string[]>): string;
|
|
59
|
+
/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */
|
|
60
|
+
declare function handleApiError(error: RtkQueryError | null | undefined, { showAlert, fallbackMessage }?: HandleApiErrorOptions): void;
|
|
61
|
+
|
|
62
|
+
export { type HandleApiErrorOptions, type RtkQueryError, capitalizeText, checkIfExistsInArray, cn, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText };
|
package/dist/utils/index.js
CHANGED
|
@@ -39,11 +39,13 @@ __export(utils_exports, {
|
|
|
39
39
|
flattenTableData: () => flattenTableData,
|
|
40
40
|
formatDate: () => formatDate,
|
|
41
41
|
formatDateTime: () => formatDateTime,
|
|
42
|
+
formatValidationErrorsHtml: () => formatValidationErrorsHtml,
|
|
42
43
|
getApiError: () => getApiError,
|
|
43
44
|
getErrorMessages: () => getErrorMessages,
|
|
44
45
|
getFieldsByCategory: () => getFieldsByCategory,
|
|
45
46
|
getFieldsByInputType: () => getFieldsByInputType,
|
|
46
47
|
getFieldsByName: () => getFieldsByName,
|
|
48
|
+
handleApiError: () => handleApiError,
|
|
47
49
|
isEmpty: () => isEmpty,
|
|
48
50
|
normalizeApiListItems: () => normalizeApiListItems,
|
|
49
51
|
parseCurrencyValueToNumber: () => parseCurrencyValueToNumber,
|
|
@@ -241,6 +243,59 @@ var removeByPropertyValues = (items = [], property, values = [], { caseInsensiti
|
|
|
241
243
|
var getFieldsByInputType = (fields = [], key) => {
|
|
242
244
|
return fields.filter(({ inputType = "" }) => inputType === key);
|
|
243
245
|
};
|
|
246
|
+
|
|
247
|
+
// src/utils/handleApiError.ts
|
|
248
|
+
var import_react_toastify = require("react-toastify");
|
|
249
|
+
var import_sweetalert2 = __toESM(require("sweetalert2"));
|
|
250
|
+
function formatValidationErrorsHtml(errors) {
|
|
251
|
+
const items = Object.keys(errors).flatMap(
|
|
252
|
+
(field) => (errors[field] || []).map((msg) => `<li>${msg}</li>`)
|
|
253
|
+
);
|
|
254
|
+
return `
|
|
255
|
+
<div style="text-align:left">
|
|
256
|
+
<p>Please review and correct the following:</p>
|
|
257
|
+
<ul style="margin:8px 0 0 16px; list-style:disc;">
|
|
258
|
+
${items.join("")}
|
|
259
|
+
</ul>
|
|
260
|
+
</div>
|
|
261
|
+
`;
|
|
262
|
+
}
|
|
263
|
+
function showValidationAlert(html) {
|
|
264
|
+
void import_sweetalert2.default.fire({
|
|
265
|
+
title: "Validation errors",
|
|
266
|
+
html,
|
|
267
|
+
icon: "error",
|
|
268
|
+
confirmButtonText: "OK",
|
|
269
|
+
showCancelButton: false,
|
|
270
|
+
confirmButtonColor: "#FF7335"
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
function handleApiError(error, { showAlert = false, fallbackMessage } = {}) {
|
|
274
|
+
if (!error) return;
|
|
275
|
+
const status = error.status ?? error.originalStatus;
|
|
276
|
+
const data = error.data;
|
|
277
|
+
if (status === 200) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (data?.errors && typeof data.errors === "object") {
|
|
281
|
+
const errors = data.errors;
|
|
282
|
+
if (showAlert) {
|
|
283
|
+
showValidationAlert(formatValidationErrorsHtml(errors));
|
|
284
|
+
} else {
|
|
285
|
+
Object.keys(errors).forEach((field) => {
|
|
286
|
+
(errors[field] || []).forEach((errorMessage) => {
|
|
287
|
+
import_react_toastify.toast.error(errorMessage);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (status === 404) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const message = fallbackMessage || data?.message || data?.title || error.error || "An error occurred. Please try again.";
|
|
297
|
+
import_react_toastify.toast.error(message);
|
|
298
|
+
}
|
|
244
299
|
// Annotate the CommonJS export names for ESM import in node:
|
|
245
300
|
0 && (module.exports = {
|
|
246
301
|
capitalizeText,
|
|
@@ -252,11 +307,13 @@ var getFieldsByInputType = (fields = [], key) => {
|
|
|
252
307
|
flattenTableData,
|
|
253
308
|
formatDate,
|
|
254
309
|
formatDateTime,
|
|
310
|
+
formatValidationErrorsHtml,
|
|
255
311
|
getApiError,
|
|
256
312
|
getErrorMessages,
|
|
257
313
|
getFieldsByCategory,
|
|
258
314
|
getFieldsByInputType,
|
|
259
315
|
getFieldsByName,
|
|
316
|
+
handleApiError,
|
|
260
317
|
isEmpty,
|
|
261
318
|
normalizeApiListItems,
|
|
262
319
|
parseCurrencyValueToNumber,
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/index.ts","../../src/utils/cn.ts","../../src/utils/helpers.ts"],"sourcesContent":["export { cn } from \"./cn\";\r\nexport * from \"./helpers\";\r\n","import clsx from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: Parameters<typeof clsx>) {\r\n return twMerge(clsx(inputs));\r\n}\r\n","export const truncateText = (text: string | null | undefined, maxLength = 20) => {\n if (!text) return \"\";\n if (text.length <= maxLength) {\n return text;\n }\n return text.slice(0, maxLength - 3) + \"...\";\n};\n\nexport function getApiError(apiError: unknown): string {\n if (!apiError) return \"An unknown error occurred\";\n\n if (typeof apiError === \"string\") {\n return apiError;\n }\n\n const error = apiError as {\n response?: { data?: Record<string, unknown> };\n message?: string;\n };\n\n if (error.response?.data) {\n const responseData = error.response.data;\n\n if (typeof responseData === \"string\") {\n return responseData;\n }\n\n const errors = responseData.errors;\n if (errors && typeof errors === \"object\") {\n for (const key in errors) {\n const messages = (errors as Record<string, unknown>)[key];\n if (Array.isArray(messages) && messages.length > 0) {\n return String(messages[0]);\n }\n }\n }\n\n if (responseData.message) {\n return String(responseData.message);\n }\n\n if (responseData.title) {\n return String(responseData.title);\n }\n }\n\n if (error.message) {\n return error.message;\n }\n\n return \"An unknown error occurred\";\n}\n\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\n if (responseData == null) return [];\n if (Array.isArray(responseData)) return responseData;\n\n const record = responseData as Record<string, unknown>;\n const data = record.data;\n\n if (\n data &&\n typeof data === \"object\" &&\n !Array.isArray(data) &&\n Array.isArray((data as { items?: unknown[] }).items)\n ) {\n return (data as { items: unknown[] }).items;\n }\n\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\n if (Array.isArray(returnModel?.items)) return returnModel.items;\n if (Array.isArray(data)) return data;\n if (typeof data === \"object\" && data !== null) {\n return [data];\n }\n return [];\n};\n\nexport function capitalizeText(name: string | null | undefined): string {\n if (!name) return \"\";\n return name\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\nexport function toLowerCaseText(text: string | null | undefined): string {\n if (!text) return \"\";\n return text.toLowerCase();\n}\n\nexport const formatDate = (dateString: string | null | undefined): string => {\n if (dateString === null || dateString === undefined) return \"-\";\n const date = new Date(dateString);\n\n if (isNaN(date.getTime())) {\n return dateString;\n }\n\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\n const day = date.getDate().toString().padStart(2, \"0\");\n const year = date.getFullYear().toString().slice(-2);\n return `${month}/${day}/${year}`;\n};\n\nexport const isEmpty = (obj: object): boolean => {\n return Object.keys(obj).length === 0;\n};\n\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\n if (!date) return \"\";\n\n let d: Date;\n\n if (typeof date === \"string\") {\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n return date;\n }\n d = new Date(date);\n } else {\n d = new Date(date);\n }\n\n if (isNaN(d.getTime())) return \"\";\n\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\n const year = localDate.getFullYear();\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\n const day = localDate.getDate().toString().padStart(2, \"0\");\n\n return `${year}-${month}-${day}`;\n};\n\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\n if (!data || data.trim() === \"\") {\n return [];\n }\n return data.split(\",\").map((item) => item.trim());\n}\n\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\n return array.includes(searchValue);\n}\n\nexport const currencyFormatter = (value: number | null | undefined): string => {\n return value?.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n }) ?? \"\";\n};\n\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\n if (value == null || value === \"\") return 0;\n\n const raw =\n typeof value === \"object\" && value !== null && \"value\" in value\n ? (value as { value: unknown }).value\n : value;\n\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\n const numericValue = stringValue.replace(/[$,]/g, \"\");\n return parseFloat(numericValue) || 0;\n};\n\nexport function flattenTableData<T extends Record<string, unknown>>(\n data: T[] | null | undefined,\n columns: { field?: string }[] | null | undefined\n): T[] {\n if (!Array.isArray(data)) return [];\n return data.map((row) => {\n const flatRow = { ...row };\n (columns ?? []).forEach((col) => {\n const key = col.field;\n if (!key) return;\n if (key.includes(\".\")) {\n const value = key.split(\".\").reduce<unknown>(\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\n row\n );\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\n }\n });\n return flatRow;\n });\n}\n\nexport const getErrorMessages = (error: {\n data?: {\n errors?: Record<string, string[]>;\n title?: string;\n error?: { name?: string[] };\n };\n} | null | undefined): string => {\n if (error?.data?.errors) {\n return Object.values(error.data.errors).flat().join(\"\\n\");\n }\n return (\n error?.data?.title ??\n error?.data?.error?.name?.[0] ??\n \"Failed to save\"\n );\n};\n\nexport const getFieldsByCategory = <T extends { category?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields?.filter(({ category = \"\" }) => category === key);\n};\n\nexport const getFieldsByName = <T extends { name?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ name = \"\" }) => name === key);\n};\n\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\n try {\n return JSON.parse(jsonString) as T;\n } catch (error) {\n console.error(\"Error parsing JSON:\", error);\n return null;\n }\n};\n\nexport const formatDateTime = (dateString: string | null | undefined): string => {\n if (!dateString) return \"Invalid Date\";\n const date = new Date(dateString);\n if (isNaN(date.getTime())) return \"Invalid Date\";\n const options: Intl.DateTimeFormatOptions = {\n year: \"numeric\",\n month: \"numeric\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n hour12: true,\n };\n return date.toLocaleString(\"en-US\", options);\n};\n\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\n items: T[] = [],\n property: keyof T & string,\n values: unknown[] = [],\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\n): T[] => {\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\n const normalize = (v: unknown) =>\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\n const valuesArr = Array.isArray(values) ? values : [values];\n const toRemove = new Set(valuesArr.map(normalize));\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\n};\n\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ inputType = \"\" }) => inputType === key);\n};\n"],"mappings":"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","names":["clsx"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts","../../src/utils/cn.ts","../../src/utils/helpers.ts","../../src/utils/handleApiError.ts"],"sourcesContent":["export { cn } from \"./cn\";\r\nexport * from \"./helpers\";\r\nexport {\r\n handleApiError,\r\n formatValidationErrorsHtml,\r\n type RtkQueryError,\r\n type HandleApiErrorOptions,\r\n} from \"./handleApiError\";\r\n","import clsx from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: Parameters<typeof clsx>) {\r\n return twMerge(clsx(inputs));\r\n}\r\n","export const truncateText = (text: string | null | undefined, maxLength = 20) => {\n if (!text) return \"\";\n if (text.length <= maxLength) {\n return text;\n }\n return text.slice(0, maxLength - 3) + \"...\";\n};\n\nexport function getApiError(apiError: unknown): string {\n if (!apiError) return \"An unknown error occurred\";\n\n if (typeof apiError === \"string\") {\n return apiError;\n }\n\n const error = apiError as {\n response?: { data?: Record<string, unknown> };\n message?: string;\n };\n\n if (error.response?.data) {\n const responseData = error.response.data;\n\n if (typeof responseData === \"string\") {\n return responseData;\n }\n\n const errors = responseData.errors;\n if (errors && typeof errors === \"object\") {\n for (const key in errors) {\n const messages = (errors as Record<string, unknown>)[key];\n if (Array.isArray(messages) && messages.length > 0) {\n return String(messages[0]);\n }\n }\n }\n\n if (responseData.message) {\n return String(responseData.message);\n }\n\n if (responseData.title) {\n return String(responseData.title);\n }\n }\n\n if (error.message) {\n return error.message;\n }\n\n return \"An unknown error occurred\";\n}\n\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\n if (responseData == null) return [];\n if (Array.isArray(responseData)) return responseData;\n\n const record = responseData as Record<string, unknown>;\n const data = record.data;\n\n if (\n data &&\n typeof data === \"object\" &&\n !Array.isArray(data) &&\n Array.isArray((data as { items?: unknown[] }).items)\n ) {\n return (data as { items: unknown[] }).items;\n }\n\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\n if (Array.isArray(returnModel?.items)) return returnModel.items;\n if (Array.isArray(data)) return data;\n if (typeof data === \"object\" && data !== null) {\n return [data];\n }\n return [];\n};\n\nexport function capitalizeText(name: string | null | undefined): string {\n if (!name) return \"\";\n return name\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\nexport function toLowerCaseText(text: string | null | undefined): string {\n if (!text) return \"\";\n return text.toLowerCase();\n}\n\nexport const formatDate = (dateString: string | null | undefined): string => {\n if (dateString === null || dateString === undefined) return \"-\";\n const date = new Date(dateString);\n\n if (isNaN(date.getTime())) {\n return dateString;\n }\n\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\n const day = date.getDate().toString().padStart(2, \"0\");\n const year = date.getFullYear().toString().slice(-2);\n return `${month}/${day}/${year}`;\n};\n\nexport const isEmpty = (obj: object): boolean => {\n return Object.keys(obj).length === 0;\n};\n\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\n if (!date) return \"\";\n\n let d: Date;\n\n if (typeof date === \"string\") {\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n return date;\n }\n d = new Date(date);\n } else {\n d = new Date(date);\n }\n\n if (isNaN(d.getTime())) return \"\";\n\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\n const year = localDate.getFullYear();\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\n const day = localDate.getDate().toString().padStart(2, \"0\");\n\n return `${year}-${month}-${day}`;\n};\n\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\n if (!data || data.trim() === \"\") {\n return [];\n }\n return data.split(\",\").map((item) => item.trim());\n}\n\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\n return array.includes(searchValue);\n}\n\nexport const currencyFormatter = (value: number | null | undefined): string => {\n return value?.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n }) ?? \"\";\n};\n\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\n if (value == null || value === \"\") return 0;\n\n const raw =\n typeof value === \"object\" && value !== null && \"value\" in value\n ? (value as { value: unknown }).value\n : value;\n\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\n const numericValue = stringValue.replace(/[$,]/g, \"\");\n return parseFloat(numericValue) || 0;\n};\n\nexport function flattenTableData<T extends Record<string, unknown>>(\n data: T[] | null | undefined,\n columns: { field?: string }[] | null | undefined\n): T[] {\n if (!Array.isArray(data)) return [];\n return data.map((row) => {\n const flatRow = { ...row };\n (columns ?? []).forEach((col) => {\n const key = col.field;\n if (!key) return;\n if (key.includes(\".\")) {\n const value = key.split(\".\").reduce<unknown>(\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\n row\n );\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\n }\n });\n return flatRow;\n });\n}\n\nexport const getErrorMessages = (error: {\n data?: {\n errors?: Record<string, string[]>;\n title?: string;\n error?: { name?: string[] };\n };\n} | null | undefined): string => {\n if (error?.data?.errors) {\n return Object.values(error.data.errors).flat().join(\"\\n\");\n }\n return (\n error?.data?.title ??\n error?.data?.error?.name?.[0] ??\n \"Failed to save\"\n );\n};\n\nexport const getFieldsByCategory = <T extends { category?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields?.filter(({ category = \"\" }) => category === key);\n};\n\nexport const getFieldsByName = <T extends { name?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ name = \"\" }) => name === key);\n};\n\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\n try {\n return JSON.parse(jsonString) as T;\n } catch (error) {\n console.error(\"Error parsing JSON:\", error);\n return null;\n }\n};\n\nexport const formatDateTime = (dateString: string | null | undefined): string => {\n if (!dateString) return \"Invalid Date\";\n const date = new Date(dateString);\n if (isNaN(date.getTime())) return \"Invalid Date\";\n const options: Intl.DateTimeFormatOptions = {\n year: \"numeric\",\n month: \"numeric\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n hour12: true,\n };\n return date.toLocaleString(\"en-US\", options);\n};\n\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\n items: T[] = [],\n property: keyof T & string,\n values: unknown[] = [],\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\n): T[] => {\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\n const normalize = (v: unknown) =>\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\n const valuesArr = Array.isArray(values) ? values : [values];\n const toRemove = new Set(valuesArr.map(normalize));\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\n};\n\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ inputType = \"\" }) => inputType === key);\n};\n","import { toast } from \"react-toastify\";\nimport Swal from \"sweetalert2\";\n\nexport type RtkQueryError = {\n status?: number | string;\n originalStatus?: number;\n data?: {\n errors?: Record<string, string[]>;\n message?: string;\n title?: string;\n };\n error?: string;\n};\n\nexport interface HandleApiErrorOptions {\n showAlert?: boolean;\n fallbackMessage?: string;\n}\n\nexport function formatValidationErrorsHtml(\n errors: Record<string, string[]>\n): string {\n const items = Object.keys(errors).flatMap((field) =>\n (errors[field] || []).map((msg) => `<li>${msg}</li>`)\n );\n return `\n <div style=\"text-align:left\">\n <p>Please review and correct the following:</p>\n <ul style=\"margin:8px 0 0 16px; list-style:disc;\">\n ${items.join(\"\")}\n </ul>\n </div>\n `;\n}\n\nfunction showValidationAlert(html: string): void {\n void Swal.fire({\n title: \"Validation errors\",\n html,\n icon: \"error\",\n confirmButtonText: \"OK\",\n showCancelButton: false,\n confirmButtonColor: \"#FF7335\",\n });\n}\n\n/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */\nexport function handleApiError(\n error: RtkQueryError | null | undefined,\n { showAlert = false, fallbackMessage }: HandleApiErrorOptions = {}\n): void {\n if (!error) return;\n\n const status = error.status ?? error.originalStatus;\n const data = error.data;\n\n if (status === 200) {\n return;\n }\n\n if (data?.errors && typeof data.errors === \"object\") {\n const errors = data.errors;\n\n if (showAlert) {\n showValidationAlert(formatValidationErrorsHtml(errors));\n } else {\n Object.keys(errors).forEach((field) => {\n (errors[field] || []).forEach((errorMessage) => {\n toast.error(errorMessage);\n });\n });\n }\n return;\n }\n\n if (status === 404) {\n return;\n }\n\n const message =\n fallbackMessage ||\n data?.message ||\n data?.title ||\n error.error ||\n \"An error occurred. Please try again.\";\n\n toast.error(message);\n}\n"],"mappings":"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","names":["clsx","Swal"]}
|
package/dist/utils/index.mjs
CHANGED
|
@@ -8,11 +8,13 @@ import {
|
|
|
8
8
|
flattenTableData,
|
|
9
9
|
formatDate,
|
|
10
10
|
formatDateTime,
|
|
11
|
+
formatValidationErrorsHtml,
|
|
11
12
|
getApiError,
|
|
12
13
|
getErrorMessages,
|
|
13
14
|
getFieldsByCategory,
|
|
14
15
|
getFieldsByInputType,
|
|
15
16
|
getFieldsByName,
|
|
17
|
+
handleApiError,
|
|
16
18
|
isEmpty,
|
|
17
19
|
normalizeApiListItems,
|
|
18
20
|
parseCurrencyValueToNumber,
|
|
@@ -20,7 +22,7 @@ import {
|
|
|
20
22
|
toDateInputValue,
|
|
21
23
|
toLowerCaseText,
|
|
22
24
|
truncateText
|
|
23
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-POG3P25K.mjs";
|
|
24
26
|
export {
|
|
25
27
|
capitalizeText,
|
|
26
28
|
checkIfExistsInArray,
|
|
@@ -31,11 +33,13 @@ export {
|
|
|
31
33
|
flattenTableData,
|
|
32
34
|
formatDate,
|
|
33
35
|
formatDateTime,
|
|
36
|
+
formatValidationErrorsHtml,
|
|
34
37
|
getApiError,
|
|
35
38
|
getErrorMessages,
|
|
36
39
|
getFieldsByCategory,
|
|
37
40
|
getFieldsByInputType,
|
|
38
41
|
getFieldsByName,
|
|
42
|
+
handleApiError,
|
|
39
43
|
isEmpty,
|
|
40
44
|
normalizeApiListItems,
|
|
41
45
|
parseCurrencyValueToNumber,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eztrak/shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
|
|
5
5
|
"homepage": "https://github.com/mehrancentangle/eztrak-packages",
|
|
6
6
|
|
|
@@ -40,7 +40,9 @@
|
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"react": "^18.0.0",
|
|
42
42
|
"react-dom": "^18.0.0",
|
|
43
|
-
"react-router-dom": "^6.0.0 || ^7.0.0"
|
|
43
|
+
"react-router-dom": "^6.0.0 || ^7.0.0",
|
|
44
|
+
"react-toastify": "^9.0.0 || ^10.0.0 || ^11.0.0",
|
|
45
|
+
"sweetalert2": "^11.0.0"
|
|
44
46
|
},
|
|
45
47
|
"peerDependenciesMeta": {
|
|
46
48
|
"react-router-dom": {
|
|
@@ -55,6 +57,8 @@
|
|
|
55
57
|
"react": "^18.3.1",
|
|
56
58
|
"react-dom": "^18.3.1",
|
|
57
59
|
"react-router-dom": "^7.0.0",
|
|
60
|
+
"react-toastify": "^11.0.5",
|
|
61
|
+
"sweetalert2": "^11.22.0",
|
|
58
62
|
"tsup": "^8.0.0",
|
|
59
63
|
"typescript": "^5.7.0"
|
|
60
64
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/cn.ts","../src/utils/helpers.ts"],"sourcesContent":["import clsx from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: Parameters<typeof clsx>) {\r\n return twMerge(clsx(inputs));\r\n}\r\n","export const truncateText = (text: string | null | undefined, maxLength = 20) => {\n if (!text) return \"\";\n if (text.length <= maxLength) {\n return text;\n }\n return text.slice(0, maxLength - 3) + \"...\";\n};\n\nexport function getApiError(apiError: unknown): string {\n if (!apiError) return \"An unknown error occurred\";\n\n if (typeof apiError === \"string\") {\n return apiError;\n }\n\n const error = apiError as {\n response?: { data?: Record<string, unknown> };\n message?: string;\n };\n\n if (error.response?.data) {\n const responseData = error.response.data;\n\n if (typeof responseData === \"string\") {\n return responseData;\n }\n\n const errors = responseData.errors;\n if (errors && typeof errors === \"object\") {\n for (const key in errors) {\n const messages = (errors as Record<string, unknown>)[key];\n if (Array.isArray(messages) && messages.length > 0) {\n return String(messages[0]);\n }\n }\n }\n\n if (responseData.message) {\n return String(responseData.message);\n }\n\n if (responseData.title) {\n return String(responseData.title);\n }\n }\n\n if (error.message) {\n return error.message;\n }\n\n return \"An unknown error occurred\";\n}\n\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\n if (responseData == null) return [];\n if (Array.isArray(responseData)) return responseData;\n\n const record = responseData as Record<string, unknown>;\n const data = record.data;\n\n if (\n data &&\n typeof data === \"object\" &&\n !Array.isArray(data) &&\n Array.isArray((data as { items?: unknown[] }).items)\n ) {\n return (data as { items: unknown[] }).items;\n }\n\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\n if (Array.isArray(returnModel?.items)) return returnModel.items;\n if (Array.isArray(data)) return data;\n if (typeof data === \"object\" && data !== null) {\n return [data];\n }\n return [];\n};\n\nexport function capitalizeText(name: string | null | undefined): string {\n if (!name) return \"\";\n return name\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\nexport function toLowerCaseText(text: string | null | undefined): string {\n if (!text) return \"\";\n return text.toLowerCase();\n}\n\nexport const formatDate = (dateString: string | null | undefined): string => {\n if (dateString === null || dateString === undefined) return \"-\";\n const date = new Date(dateString);\n\n if (isNaN(date.getTime())) {\n return dateString;\n }\n\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\n const day = date.getDate().toString().padStart(2, \"0\");\n const year = date.getFullYear().toString().slice(-2);\n return `${month}/${day}/${year}`;\n};\n\nexport const isEmpty = (obj: object): boolean => {\n return Object.keys(obj).length === 0;\n};\n\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\n if (!date) return \"\";\n\n let d: Date;\n\n if (typeof date === \"string\") {\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n return date;\n }\n d = new Date(date);\n } else {\n d = new Date(date);\n }\n\n if (isNaN(d.getTime())) return \"\";\n\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\n const year = localDate.getFullYear();\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\n const day = localDate.getDate().toString().padStart(2, \"0\");\n\n return `${year}-${month}-${day}`;\n};\n\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\n if (!data || data.trim() === \"\") {\n return [];\n }\n return data.split(\",\").map((item) => item.trim());\n}\n\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\n return array.includes(searchValue);\n}\n\nexport const currencyFormatter = (value: number | null | undefined): string => {\n return value?.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n }) ?? \"\";\n};\n\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\n if (value == null || value === \"\") return 0;\n\n const raw =\n typeof value === \"object\" && value !== null && \"value\" in value\n ? (value as { value: unknown }).value\n : value;\n\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\n const numericValue = stringValue.replace(/[$,]/g, \"\");\n return parseFloat(numericValue) || 0;\n};\n\nexport function flattenTableData<T extends Record<string, unknown>>(\n data: T[] | null | undefined,\n columns: { field?: string }[] | null | undefined\n): T[] {\n if (!Array.isArray(data)) return [];\n return data.map((row) => {\n const flatRow = { ...row };\n (columns ?? []).forEach((col) => {\n const key = col.field;\n if (!key) return;\n if (key.includes(\".\")) {\n const value = key.split(\".\").reduce<unknown>(\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\n row\n );\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\n }\n });\n return flatRow;\n });\n}\n\nexport const getErrorMessages = (error: {\n data?: {\n errors?: Record<string, string[]>;\n title?: string;\n error?: { name?: string[] };\n };\n} | null | undefined): string => {\n if (error?.data?.errors) {\n return Object.values(error.data.errors).flat().join(\"\\n\");\n }\n return (\n error?.data?.title ??\n error?.data?.error?.name?.[0] ??\n \"Failed to save\"\n );\n};\n\nexport const getFieldsByCategory = <T extends { category?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields?.filter(({ category = \"\" }) => category === key);\n};\n\nexport const getFieldsByName = <T extends { name?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ name = \"\" }) => name === key);\n};\n\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\n try {\n return JSON.parse(jsonString) as T;\n } catch (error) {\n console.error(\"Error parsing JSON:\", error);\n return null;\n }\n};\n\nexport const formatDateTime = (dateString: string | null | undefined): string => {\n if (!dateString) return \"Invalid Date\";\n const date = new Date(dateString);\n if (isNaN(date.getTime())) return \"Invalid Date\";\n const options: Intl.DateTimeFormatOptions = {\n year: \"numeric\",\n month: \"numeric\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n hour12: true,\n };\n return date.toLocaleString(\"en-US\", options);\n};\n\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\n items: T[] = [],\n property: keyof T & string,\n values: unknown[] = [],\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\n): T[] => {\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\n const normalize = (v: unknown) =>\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\n const valuesArr = Array.isArray(values) ? values : [values];\n const toRemove = new Set(valuesArr.map(normalize));\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\n};\n\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\n fields: T[] = [],\n key: string\n): T[] => {\n return fields.filter(({ inputType = \"\" }) => inputType === key);\n};\n"],"mappings":"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","names":[]}
|