@eztrak/shared 0.4.8 → 0.4.9

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 CHANGED
@@ -38,6 +38,15 @@ formatNumber("1234567.5"); // "1,234,567.5"
38
38
  formatNumber(null); // "0"
39
39
  ```
40
40
 
41
+ Truncate text or file names (keeps the file extension):
42
+
43
+ ```js
44
+ import { truncateText, truncateFileName } from "@eztrak/shared/utils";
45
+
46
+ truncateText("A very long description here", 10); // "A very ..."
47
+ truncateFileName("annual-financial-report-2026.pdf", 20); // "annual-financ....pdf"
48
+ ```
49
+
41
50
  RTK Query errors (toast or SweetAlert — no extra wiring):
42
51
 
43
52
  ```js
@@ -6,6 +6,15 @@ var truncateText = (text, maxLength = 20) => {
6
6
  }
7
7
  return text.slice(0, maxLength - 3) + "...";
8
8
  };
9
+ var truncateFileName = (fileName, maxLength = 20) => {
10
+ if (!fileName) return "";
11
+ if (fileName.length <= maxLength) {
12
+ return fileName;
13
+ }
14
+ const extension = fileName.slice(fileName.lastIndexOf("."));
15
+ const truncatedName = fileName.slice(0, maxLength - extension.length - 3) + "...";
16
+ return truncatedName + extension;
17
+ };
9
18
  function getApiError(apiError) {
10
19
  if (!apiError) return "An unknown error occurred";
11
20
  if (typeof apiError === "string") {
@@ -188,6 +197,7 @@ var getFieldsByInputType = (fields = [], key) => {
188
197
 
189
198
  export {
190
199
  truncateText,
200
+ truncateFileName,
191
201
  getApiError,
192
202
  normalizeApiListItems,
193
203
  capitalizeText,
@@ -209,4 +219,4 @@ export {
209
219
  removeByPropertyValues,
210
220
  getFieldsByInputType
211
221
  };
212
- //# sourceMappingURL=chunk-M7SOJOJI.mjs.map
222
+ //# sourceMappingURL=chunk-HZGVVROQ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/helpers.ts"],"sourcesContent":["export const truncateText = (text: string | null | undefined, maxLength = 20) => {\r\n if (!text) return \"\";\r\n if (text.length <= maxLength) {\r\n return text;\r\n }\r\n return text.slice(0, maxLength - 3) + \"...\";\r\n};\r\n\r\nexport const truncateFileName = (\r\n fileName: string | null | undefined,\r\n maxLength = 20\r\n): string => {\r\n if (!fileName) return \"\";\r\n if (fileName.length <= maxLength) {\r\n return fileName;\r\n }\r\n const extension = fileName.slice(fileName.lastIndexOf(\".\"));\r\n const truncatedName =\r\n fileName.slice(0, maxLength - extension.length - 3) + \"...\";\r\n return truncatedName + extension;\r\n};\r\n\r\nexport function getApiError(apiError: unknown): string {\r\n if (!apiError) return \"An unknown error occurred\";\r\n\r\n if (typeof apiError === \"string\") {\r\n return apiError;\r\n }\r\n\r\n const error = apiError as {\r\n response?: { data?: Record<string, unknown> };\r\n message?: string;\r\n };\r\n\r\n if (error.response?.data) {\r\n const responseData = error.response.data;\r\n\r\n if (typeof responseData === \"string\") {\r\n return responseData;\r\n }\r\n\r\n const errors = responseData.errors;\r\n if (errors && typeof errors === \"object\") {\r\n for (const key in errors) {\r\n const messages = (errors as Record<string, unknown>)[key];\r\n if (Array.isArray(messages) && messages.length > 0) {\r\n return String(messages[0]);\r\n }\r\n }\r\n }\r\n\r\n if (responseData.message) {\r\n return String(responseData.message);\r\n }\r\n\r\n if (responseData.title) {\r\n return String(responseData.title);\r\n }\r\n }\r\n\r\n if (error.message) {\r\n return error.message;\r\n }\r\n\r\n return \"An unknown error occurred\";\r\n}\r\n\r\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\r\n if (responseData == null) return [];\r\n if (Array.isArray(responseData)) return responseData;\r\n\r\n const record = responseData as Record<string, unknown>;\r\n const data = record.data;\r\n\r\n if (\r\n data &&\r\n typeof data === \"object\" &&\r\n !Array.isArray(data) &&\r\n Array.isArray((data as { items?: unknown[] }).items)\r\n ) {\r\n return (data as { items: unknown[] }).items;\r\n }\r\n\r\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\r\n if (Array.isArray(returnModel?.items)) return returnModel.items;\r\n if (Array.isArray(data)) return data;\r\n if (typeof data === \"object\" && data !== null) {\r\n return [data];\r\n }\r\n return [];\r\n};\r\n\r\nexport function capitalizeText(name: string | null | undefined): string {\r\n if (!name) return \"\";\r\n return name\r\n .split(\" \")\r\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\r\n .join(\" \");\r\n}\r\n\r\nexport function toLowerCaseText(text: string | null | undefined): string {\r\n if (!text) return \"\";\r\n return text.toLowerCase();\r\n}\r\n\r\nexport const formatDate = (dateString: string | null | undefined): string => {\r\n if (dateString === null || dateString === undefined) return \"-\";\r\n const date = new Date(dateString);\r\n\r\n if (isNaN(date.getTime())) {\r\n return dateString;\r\n }\r\n\r\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = date.getDate().toString().padStart(2, \"0\");\r\n const year = date.getFullYear().toString().slice(-2);\r\n return `${month}/${day}/${year}`;\r\n};\r\n\r\nexport const isEmpty = (obj: object): boolean => {\r\n return Object.keys(obj).length === 0;\r\n};\r\n\r\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\r\n if (!date) return \"\";\r\n\r\n let d: Date;\r\n\r\n if (typeof date === \"string\") {\r\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\r\n return date;\r\n }\r\n d = new Date(date);\r\n } else {\r\n d = new Date(date);\r\n }\r\n\r\n if (isNaN(d.getTime())) return \"\";\r\n\r\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\r\n const year = localDate.getFullYear();\r\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = localDate.getDate().toString().padStart(2, \"0\");\r\n\r\n return `${year}-${month}-${day}`;\r\n};\r\n\r\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\r\n if (!data || data.trim() === \"\") {\r\n return [];\r\n }\r\n return data.split(\",\").map((item) => item.trim());\r\n}\r\n\r\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\r\n return array.includes(searchValue);\r\n}\r\n\r\nexport const currencyFormatter = (value: number | null | undefined): string => {\r\n return value?.toLocaleString(\"en-US\", {\r\n style: \"currency\",\r\n currency: \"USD\",\r\n }) ?? \"\";\r\n};\r\nexport const formatNumber = (number: number | string | null | undefined): string => {\r\n if (isNaN(Number(number)) || number === null || number === undefined) {\r\n return \"0\";\r\n }\r\n\r\n const formattedNumber = Number(number)\r\n .toString()\r\n .replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\r\n\r\n return formattedNumber;\r\n};\r\n\r\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\r\n if (value == null || value === \"\") return 0;\r\n\r\n const raw =\r\n typeof value === \"object\" && value !== null && \"value\" in value\r\n ? (value as { value: unknown }).value\r\n : value;\r\n\r\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\r\n const numericValue = stringValue.replace(/[$,]/g, \"\");\r\n return parseFloat(numericValue) || 0;\r\n};\r\n\r\nexport function flattenTableData<T extends Record<string, unknown>>(\r\n data: T[] | null | undefined,\r\n columns: { field?: string }[] | null | undefined\r\n): T[] {\r\n if (!Array.isArray(data)) return [];\r\n return data.map((row) => {\r\n const flatRow = { ...row };\r\n (columns ?? []).forEach((col) => {\r\n const key = col.field;\r\n if (!key) return;\r\n if (key.includes(\".\")) {\r\n const value = key.split(\".\").reduce<unknown>(\r\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\r\n row\r\n );\r\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\r\n }\r\n });\r\n return flatRow;\r\n });\r\n}\r\n\r\nexport const getErrorMessages = (error: {\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n title?: string;\r\n error?: { name?: string[] };\r\n };\r\n} | null | undefined): string => {\r\n if (error?.data?.errors) {\r\n return Object.values(error.data.errors).flat().join(\"\\n\");\r\n }\r\n return (\r\n error?.data?.title ??\r\n error?.data?.error?.name?.[0] ??\r\n \"Failed to save\"\r\n );\r\n};\r\n\r\nexport const getFieldsByCategory = <T extends { category?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields?.filter(({ category = \"\" }) => category === key);\r\n};\r\n\r\nexport const getFieldsByName = <T extends { name?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ name = \"\" }) => name === key);\r\n};\r\n\r\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\r\n try {\r\n return JSON.parse(jsonString) as T;\r\n } catch (error) {\r\n console.error(\"Error parsing JSON:\", error);\r\n return null;\r\n }\r\n};\r\n\r\nexport const formatDateTime = (dateString: string | null | undefined): string => {\r\n if (!dateString) return \"Invalid Date\";\r\n const date = new Date(dateString);\r\n if (isNaN(date.getTime())) return \"Invalid Date\";\r\n const options: Intl.DateTimeFormatOptions = {\r\n year: \"numeric\",\r\n month: \"numeric\",\r\n day: \"numeric\",\r\n hour: \"numeric\",\r\n minute: \"numeric\",\r\n hour12: true,\r\n };\r\n return date.toLocaleString(\"en-US\", options);\r\n};\r\n\r\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\r\n items: T[] = [],\r\n property: keyof T & string,\r\n values: unknown[] = [],\r\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\r\n): T[] => {\r\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\r\n const normalize = (v: unknown) =>\r\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\r\n const valuesArr = Array.isArray(values) ? values : [values];\r\n const toRemove = new Set(valuesArr.map(normalize));\r\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\r\n};\r\n\r\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ inputType = \"\" }) => inputType === key);\r\n};\r\n"],"mappings":"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","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { ConfirmationAlertOptions, HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatNumber, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText } from './utils/index.mjs';
1
+ export { ConfirmationAlertOptions, HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatNumber, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateFileName, truncateText } from './utils/index.mjs';
2
2
  export { UseGridHeightOptions, useGridHeight, usePaginationUrlSync } from './hooks/index.mjs';
3
3
  export { CustomPagination, CustomPaginationClassNames, CustomPaginationProps, EztrakTab, EztrakTabs, EztrakTabsClassNames, EztrakTabsProps, LayoutStatus, PaginationData, ResetColumnsButton, ResetColumnsButtonProps, TableLayoutToolbarControls, TableLayoutToolbarControlsProps } from './components/index.mjs';
4
4
  import 'clsx';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { ConfirmationAlertOptions, HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatNumber, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText } from './utils/index.js';
1
+ export { ConfirmationAlertOptions, HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatNumber, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateFileName, truncateText } from './utils/index.js';
2
2
  export { UseGridHeightOptions, useGridHeight, usePaginationUrlSync } from './hooks/index.js';
3
3
  export { CustomPagination, CustomPaginationClassNames, CustomPaginationProps, EztrakTab, EztrakTabs, EztrakTabsClassNames, EztrakTabsProps, LayoutStatus, PaginationData, ResetColumnsButton, ResetColumnsButtonProps, TableLayoutToolbarControls, TableLayoutToolbarControlsProps } from './components/index.js';
4
4
  import 'clsx';
package/dist/index.js CHANGED
@@ -58,6 +58,7 @@ __export(src_exports, {
58
58
  removeByPropertyValues: () => removeByPropertyValues,
59
59
  toDateInputValue: () => toDateInputValue,
60
60
  toLowerCaseText: () => toLowerCaseText,
61
+ truncateFileName: () => truncateFileName,
61
62
  truncateText: () => truncateText,
62
63
  useGridHeight: () => useGridHeight,
63
64
  usePaginationUrlSync: () => usePaginationUrlSync
@@ -79,6 +80,15 @@ var truncateText = (text, maxLength = 20) => {
79
80
  }
80
81
  return text.slice(0, maxLength - 3) + "...";
81
82
  };
83
+ var truncateFileName = (fileName, maxLength = 20) => {
84
+ if (!fileName) return "";
85
+ if (fileName.length <= maxLength) {
86
+ return fileName;
87
+ }
88
+ const extension = fileName.slice(fileName.lastIndexOf("."));
89
+ const truncatedName = fileName.slice(0, maxLength - extension.length - 3) + "...";
90
+ return truncatedName + extension;
91
+ };
82
92
  function getApiError(apiError) {
83
93
  if (!apiError) return "An unknown error occurred";
84
94
  if (typeof apiError === "string") {
@@ -945,6 +955,7 @@ function CustomPagination({
945
955
  removeByPropertyValues,
946
956
  toDateInputValue,
947
957
  toLowerCaseText,
958
+ truncateFileName,
948
959
  truncateText,
949
960
  useGridHeight,
950
961
  usePaginationUrlSync
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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","../src/components/tabs/EztrakTabs.tsx","../src/components/pagination/CustomPagination.tsx"],"sourcesContent":["export * from \"./utils\";\r\nexport * from \"./hooks\";\r\nexport * from \"./components\";\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) => {\r\n if (!text) return \"\";\r\n if (text.length <= maxLength) {\r\n return text;\r\n }\r\n return text.slice(0, maxLength - 3) + \"...\";\r\n};\r\n\r\nexport function getApiError(apiError: unknown): string {\r\n if (!apiError) return \"An unknown error occurred\";\r\n\r\n if (typeof apiError === \"string\") {\r\n return apiError;\r\n }\r\n\r\n const error = apiError as {\r\n response?: { data?: Record<string, unknown> };\r\n message?: string;\r\n };\r\n\r\n if (error.response?.data) {\r\n const responseData = error.response.data;\r\n\r\n if (typeof responseData === \"string\") {\r\n return responseData;\r\n }\r\n\r\n const errors = responseData.errors;\r\n if (errors && typeof errors === \"object\") {\r\n for (const key in errors) {\r\n const messages = (errors as Record<string, unknown>)[key];\r\n if (Array.isArray(messages) && messages.length > 0) {\r\n return String(messages[0]);\r\n }\r\n }\r\n }\r\n\r\n if (responseData.message) {\r\n return String(responseData.message);\r\n }\r\n\r\n if (responseData.title) {\r\n return String(responseData.title);\r\n }\r\n }\r\n\r\n if (error.message) {\r\n return error.message;\r\n }\r\n\r\n return \"An unknown error occurred\";\r\n}\r\n\r\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\r\n if (responseData == null) return [];\r\n if (Array.isArray(responseData)) return responseData;\r\n\r\n const record = responseData as Record<string, unknown>;\r\n const data = record.data;\r\n\r\n if (\r\n data &&\r\n typeof data === \"object\" &&\r\n !Array.isArray(data) &&\r\n Array.isArray((data as { items?: unknown[] }).items)\r\n ) {\r\n return (data as { items: unknown[] }).items;\r\n }\r\n\r\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\r\n if (Array.isArray(returnModel?.items)) return returnModel.items;\r\n if (Array.isArray(data)) return data;\r\n if (typeof data === \"object\" && data !== null) {\r\n return [data];\r\n }\r\n return [];\r\n};\r\n\r\nexport function capitalizeText(name: string | null | undefined): string {\r\n if (!name) return \"\";\r\n return name\r\n .split(\" \")\r\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\r\n .join(\" \");\r\n}\r\n\r\nexport function toLowerCaseText(text: string | null | undefined): string {\r\n if (!text) return \"\";\r\n return text.toLowerCase();\r\n}\r\n\r\nexport const formatDate = (dateString: string | null | undefined): string => {\r\n if (dateString === null || dateString === undefined) return \"-\";\r\n const date = new Date(dateString);\r\n\r\n if (isNaN(date.getTime())) {\r\n return dateString;\r\n }\r\n\r\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = date.getDate().toString().padStart(2, \"0\");\r\n const year = date.getFullYear().toString().slice(-2);\r\n return `${month}/${day}/${year}`;\r\n};\r\n\r\nexport const isEmpty = (obj: object): boolean => {\r\n return Object.keys(obj).length === 0;\r\n};\r\n\r\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\r\n if (!date) return \"\";\r\n\r\n let d: Date;\r\n\r\n if (typeof date === \"string\") {\r\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\r\n return date;\r\n }\r\n d = new Date(date);\r\n } else {\r\n d = new Date(date);\r\n }\r\n\r\n if (isNaN(d.getTime())) return \"\";\r\n\r\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\r\n const year = localDate.getFullYear();\r\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = localDate.getDate().toString().padStart(2, \"0\");\r\n\r\n return `${year}-${month}-${day}`;\r\n};\r\n\r\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\r\n if (!data || data.trim() === \"\") {\r\n return [];\r\n }\r\n return data.split(\",\").map((item) => item.trim());\r\n}\r\n\r\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\r\n return array.includes(searchValue);\r\n}\r\n\r\nexport const currencyFormatter = (value: number | null | undefined): string => {\r\n return value?.toLocaleString(\"en-US\", {\r\n style: \"currency\",\r\n currency: \"USD\",\r\n }) ?? \"\";\r\n};\r\nexport const formatNumber = (number: number | string | null | undefined): string => {\r\n if (isNaN(Number(number)) || number === null || number === undefined) {\r\n return \"0\";\r\n }\r\n\r\n const formattedNumber = Number(number)\r\n .toString()\r\n .replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\r\n\r\n return formattedNumber;\r\n};\r\n\r\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\r\n if (value == null || value === \"\") return 0;\r\n\r\n const raw =\r\n typeof value === \"object\" && value !== null && \"value\" in value\r\n ? (value as { value: unknown }).value\r\n : value;\r\n\r\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\r\n const numericValue = stringValue.replace(/[$,]/g, \"\");\r\n return parseFloat(numericValue) || 0;\r\n};\r\n\r\nexport function flattenTableData<T extends Record<string, unknown>>(\r\n data: T[] | null | undefined,\r\n columns: { field?: string }[] | null | undefined\r\n): T[] {\r\n if (!Array.isArray(data)) return [];\r\n return data.map((row) => {\r\n const flatRow = { ...row };\r\n (columns ?? []).forEach((col) => {\r\n const key = col.field;\r\n if (!key) return;\r\n if (key.includes(\".\")) {\r\n const value = key.split(\".\").reduce<unknown>(\r\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\r\n row\r\n );\r\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\r\n }\r\n });\r\n return flatRow;\r\n });\r\n}\r\n\r\nexport const getErrorMessages = (error: {\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n title?: string;\r\n error?: { name?: string[] };\r\n };\r\n} | null | undefined): string => {\r\n if (error?.data?.errors) {\r\n return Object.values(error.data.errors).flat().join(\"\\n\");\r\n }\r\n return (\r\n error?.data?.title ??\r\n error?.data?.error?.name?.[0] ??\r\n \"Failed to save\"\r\n );\r\n};\r\n\r\nexport const getFieldsByCategory = <T extends { category?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields?.filter(({ category = \"\" }) => category === key);\r\n};\r\n\r\nexport const getFieldsByName = <T extends { name?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ name = \"\" }) => name === key);\r\n};\r\n\r\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\r\n try {\r\n return JSON.parse(jsonString) as T;\r\n } catch (error) {\r\n console.error(\"Error parsing JSON:\", error);\r\n return null;\r\n }\r\n};\r\n\r\nexport const formatDateTime = (dateString: string | null | undefined): string => {\r\n if (!dateString) return \"Invalid Date\";\r\n const date = new Date(dateString);\r\n if (isNaN(date.getTime())) return \"Invalid Date\";\r\n const options: Intl.DateTimeFormatOptions = {\r\n year: \"numeric\",\r\n month: \"numeric\",\r\n day: \"numeric\",\r\n hour: \"numeric\",\r\n minute: \"numeric\",\r\n hour12: true,\r\n };\r\n return date.toLocaleString(\"en-US\", options);\r\n};\r\n\r\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\r\n items: T[] = [],\r\n property: keyof T & string,\r\n values: unknown[] = [],\r\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\r\n): T[] => {\r\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\r\n const normalize = (v: unknown) =>\r\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\r\n const valuesArr = Array.isArray(values) ? values : [values];\r\n const toRemove = new Set(valuesArr.map(normalize));\r\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\r\n};\r\n\r\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ inputType = \"\" }) => inputType === key);\r\n};\r\n","import toast from \"react-hot-toast\";\r\nimport Swal from \"sweetalert2\";\r\n\r\nexport type RtkQueryError = {\r\n status?: number | string;\r\n originalStatus?: number;\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n message?: string;\r\n title?: string;\r\n };\r\n error?: string;\r\n};\r\n\r\nexport interface HandleApiErrorOptions {\r\n showAlert?: boolean;\r\n fallbackMessage?: string;\r\n}\r\n\r\nexport function formatValidationErrorsHtml(\r\n errors: Record<string, string[]>\r\n): string {\r\n const items = Object.keys(errors).flatMap((field) =>\r\n (errors[field] || []).map((msg) => `<li>${msg}</li>`)\r\n );\r\n return `\r\n <div style=\"text-align:left\">\r\n <p>Please review and correct the following:</p>\r\n <ul style=\"margin:8px 0 0 16px; list-style:disc;\">\r\n ${items.join(\"\")}\r\n </ul>\r\n </div>\r\n `;\r\n}\r\n\r\nfunction showValidationAlert(html: string): void {\r\n void Swal.fire({\r\n title: \"Validation errors\",\r\n html,\r\n icon: \"error\",\r\n confirmButtonText: \"OK\",\r\n showCancelButton: false,\r\n confirmButtonColor: \"#FF7335\",\r\n });\r\n}\r\n\r\n/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */\r\nexport function handleApiError(\r\n error: RtkQueryError | null | undefined,\r\n { showAlert = false, fallbackMessage }: HandleApiErrorOptions = {}\r\n): void {\r\n if (!error) return;\r\n\r\n const status = error.status ?? error.originalStatus;\r\n const data = error.data;\r\n\r\n if (status === 200) {\r\n return;\r\n }\r\n\r\n if (data?.errors && typeof data.errors === \"object\") {\r\n const errors = data.errors;\r\n\r\n if (showAlert) {\r\n showValidationAlert(formatValidationErrorsHtml(errors));\r\n } else {\r\n Object.keys(errors).forEach((field) => {\r\n (errors[field] || []).forEach((errorMessage) => {\r\n toast.error(errorMessage);\r\n });\r\n });\r\n }\r\n return;\r\n }\r\n\r\n if (status === 404) {\r\n return;\r\n }\r\n\r\n const message =\r\n fallbackMessage ||\r\n data?.message ||\r\n data?.title ||\r\n error.error ||\r\n \"An error occurred. Please try again.\";\r\n\r\n toast.error(message);\r\n}\r\n\r\nexport interface ConfirmationAlertOptions {\r\n title?: string;\r\n text?: string;\r\n icon?: \"warning\" | \"info\" | \"question\" | \"error\" | \"success\";\r\n confirmButtonText?: string;\r\n cancelButtonText?: string;\r\n}\r\n\r\nexport function confirmationAlert(\r\n onConfirm: () => void,\r\n options: ConfirmationAlertOptions = {}\r\n): void {\r\n void Swal.fire({\r\n title: options.title ?? \"Are you sure?\",\r\n text: options.text,\r\n icon: options.icon ?? \"warning\",\r\n showCancelButton: true,\r\n confirmButtonText: options.confirmButtonText ?? \"Yes\",\r\n cancelButtonText: options.cancelButtonText ?? \"Cancel\",\r\n confirmButtonColor: \"#FF7335\",\r\n }).then((result) => {\r\n if (result.isConfirmed) {\r\n onConfirm();\r\n }\r\n });\r\n}\r\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","import {\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useRef,\r\n useState,\r\n type KeyboardEvent,\r\n} from \"react\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport type { EztrakTab, EztrakTabsProps } from \"./types\";\r\n\r\nfunction getInitialTabId(\r\n tabs: EztrakTab[],\r\n defaultTabId?: string\r\n): string | undefined {\r\n if (defaultTabId && tabs.some((t) => t.id === defaultTabId && !t.disabled)) {\r\n return defaultTabId;\r\n }\r\n return tabs.find((t) => !t.disabled)?.id;\r\n}\r\n\r\nfunction getEnabledTabIds(tabs: EztrakTab[]): string[] {\r\n return tabs.filter((t) => !t.disabled).map((t) => t.id);\r\n}\r\n\r\nexport function EztrakTabs({\r\n tabs,\r\n activeTab,\r\n defaultTabId,\r\n onTabChange,\r\n showPanels = true,\r\n keepMounted = false,\r\n classNames,\r\n className,\r\n}: EztrakTabsProps) {\r\n const baseId = useId().replace(/:/g, \"\");\r\n const isControlled = activeTab !== undefined && activeTab !== null;\r\n const [uncontrolledActive, setUncontrolledActive] = useState(() =>\r\n getInitialTabId(tabs, defaultTabId)\r\n );\r\n const tabRefs = useRef<Map<string, HTMLButtonElement>>(new Map());\r\n\r\n const displayActive = isControlled ? activeTab : uncontrolledActive;\r\n\r\n useEffect(() => {\r\n if (isControlled) return;\r\n const enabledIds = getEnabledTabIds(tabs);\r\n if (!displayActive || !enabledIds.includes(displayActive)) {\r\n const next = getInitialTabId(tabs, defaultTabId);\r\n if (next !== displayActive) {\r\n setUncontrolledActive(next);\r\n }\r\n }\r\n }, [tabs, defaultTabId, isControlled, displayActive]);\r\n\r\n const handleTabClick = useCallback(\r\n (tabId: string, disabled?: boolean) => {\r\n if (disabled) return;\r\n if (!isControlled) {\r\n setUncontrolledActive(tabId);\r\n }\r\n onTabChange?.(tabId);\r\n },\r\n [isControlled, onTabChange]\r\n );\r\n\r\n const focusTab = useCallback((tabId: string) => {\r\n tabRefs.current.get(tabId)?.focus();\r\n }, []);\r\n\r\n const handleListKeyDown = useCallback(\r\n (event: KeyboardEvent<HTMLUListElement>) => {\r\n const enabledIds = getEnabledTabIds(tabs);\r\n if (enabledIds.length === 0) return;\r\n\r\n const currentIndex = displayActive\r\n ? enabledIds.indexOf(displayActive)\r\n : -1;\r\n let nextIndex = currentIndex;\r\n\r\n switch (event.key) {\r\n case \"ArrowRight\":\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n nextIndex =\r\n currentIndex < 0\r\n ? 0\r\n : (currentIndex + 1) % enabledIds.length;\r\n break;\r\n case \"ArrowLeft\":\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n nextIndex =\r\n currentIndex < 0\r\n ? enabledIds.length - 1\r\n : (currentIndex - 1 + enabledIds.length) % enabledIds.length;\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n nextIndex = 0;\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n nextIndex = enabledIds.length - 1;\r\n break;\r\n default:\r\n return;\r\n }\r\n\r\n const nextId = enabledIds[nextIndex];\r\n if (nextId) {\r\n handleTabClick(nextId);\r\n focusTab(nextId);\r\n }\r\n },\r\n [tabs, displayActive, handleTabClick, focusTab]\r\n );\r\n\r\n if (!tabs.length) {\r\n return null;\r\n }\r\n\r\n const wrapperClass = cn(\r\n \"eztrak-tabs-wrapper\",\r\n classNames?.wrapper,\r\n className\r\n );\r\n\r\n return (\r\n <div className={wrapperClass}>\r\n <div className={cn(\"eztrak-tabs-container\", classNames?.container)}>\r\n <nav\r\n className={cn(\"eztrak-tabs-nav\", classNames?.nav)}\r\n aria-label=\"Tabs\"\r\n >\r\n <ul\r\n role=\"tablist\"\r\n className={cn(\"eztrak-tabs-list\", classNames?.list)}\r\n onKeyDown={handleListKeyDown}\r\n >\r\n {tabs.map((tab) => {\r\n const isActive = displayActive === tab.id;\r\n const tabId = `${baseId}-tab-${tab.id}`;\r\n const panelId = `${baseId}-panel-${tab.id}`;\r\n\r\n return (\r\n <li\r\n key={tab.id}\r\n role=\"presentation\"\r\n className={cn(\r\n \"eztrak-tabs-item\",\r\n isActive && \"eztrak-tabs-item-active\",\r\n classNames?.item,\r\n isActive && classNames?.itemActive\r\n )}\r\n >\r\n <button\r\n ref={(el) => {\r\n if (el) {\r\n tabRefs.current.set(tab.id, el);\r\n } else {\r\n tabRefs.current.delete(tab.id);\r\n }\r\n }}\r\n type=\"button\"\r\n role=\"tab\"\r\n id={tabId}\r\n aria-selected={isActive}\r\n aria-controls={showPanels ? panelId : undefined}\r\n tabIndex={isActive ? 0 : -1}\r\n disabled={tab.disabled}\r\n className={cn(\r\n \"eztrak-tabs-button\",\r\n isActive && \"eztrak-tabs-button-active\",\r\n classNames?.button,\r\n isActive && classNames?.buttonActive\r\n )}\r\n onClick={() => handleTabClick(tab.id, tab.disabled)}\r\n >\r\n {tab.icon ? (\r\n <span\r\n className={cn(\"eztrak-tabs-icon\", classNames?.icon)}\r\n aria-hidden\r\n >\r\n {tab.icon}\r\n </span>\r\n ) : null}\r\n <span\r\n className={cn(\"eztrak-tabs-label\", classNames?.label)}\r\n >\r\n {tab.label}\r\n </span>\r\n {isActive ? (\r\n <span\r\n className={cn(\r\n \"eztrak-tabs-underline\",\r\n classNames?.underline\r\n )}\r\n aria-hidden\r\n />\r\n ) : null}\r\n </button>\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n </nav>\r\n\r\n {showPanels ? (\r\n <div className={cn(\"eztrak-tabs-content\", classNames?.content)}>\r\n {tabs.map((tab) => {\r\n const isActive = displayActive === tab.id;\r\n const panelId = `${baseId}-panel-${tab.id}`;\r\n const tabId = `${baseId}-tab-${tab.id}`;\r\n\r\n if (!keepMounted && !isActive) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div\r\n key={tab.id}\r\n id={panelId}\r\n role=\"tabpanel\"\r\n aria-labelledby={tabId}\r\n hidden={!isActive}\r\n className={cn(\"eztrak-tabs-panel\", classNames?.panel)}\r\n >\r\n {tab.content}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n ) : null}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { type ChangeEvent, type ReactNode } from \"react\";\r\nimport { useSearchParams } from \"react-router-dom\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { confirmationAlert } from \"../../utils/handleApiError\";\r\nimport type {\r\n CustomPaginationProps,\r\n ResetColumnsButtonProps,\r\n TableLayoutToolbarControlsProps,\r\n} from \"./types\";\r\n\r\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 30, 50, 100];\r\nconst ALL_PAGES_VALUE = -1;\r\n\r\nfunction padCount(num: number) {\r\n return num.toString().padStart(2, \"0\");\r\n}\r\n\r\nfunction RefreshIcon({\r\n size = 14,\r\n className,\r\n}: {\r\n size?: number;\r\n className?: string;\r\n}) {\r\n return (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden=\"true\"\r\n className={className}\r\n >\r\n <path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" />\r\n <path d=\"M21 3v5h-5\" />\r\n <path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" />\r\n <path d=\"M8 16H3v5\" />\r\n </svg>\r\n );\r\n}\r\n\r\nexport function ResetColumnsButton({\r\n onReset,\r\n disabled = false,\r\n isLoading = false,\r\n}: ResetColumnsButtonProps) {\r\n const handleClick = () => {\r\n confirmationAlert(onReset, {\r\n text: \"Reset column order, widths, and visibility to defaults?\",\r\n icon: \"warning\",\r\n title: \"Reset column layout to default\",\r\n });\r\n };\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={handleClick}\r\n disabled={disabled || isLoading}\r\n title=\"Reset column layout to default\"\r\n className=\"inline-flex items-center gap-1.5 rounded-xl border border-primary-150 bg-white px-3 py-1.5 text-sm font-medium text-primary-150 hover:bg-gray-50 focus:outline-none disabled:hover:bg-white\"\r\n >\r\n <RefreshIcon size={14} className={cn(isLoading ? \"animate-spin\" : \"\")} />\r\n Reset columns\r\n </button>\r\n );\r\n}\r\n\r\nexport function TableLayoutToolbarControls({\r\n layoutStatus = {},\r\n onResetLayout,\r\n renderResetControl,\r\n isLoading = false,\r\n}: TableLayoutToolbarControlsProps) {\r\n const { isLayoutLoading, isLayoutSaving, isLayoutResetting } = layoutStatus;\r\n const isLayoutBusy = isLayoutLoading || isLayoutSaving || isLayoutResetting;\r\n\r\n return (\r\n <div className=\"flex items-center gap-3\">\r\n {onResetLayout &&\r\n (renderResetControl ? (\r\n renderResetControl(onResetLayout)\r\n ) : (\r\n <ResetColumnsButton\r\n onReset={onResetLayout}\r\n disabled={isLayoutBusy}\r\n isLoading={isLoading}\r\n />\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CustomPagination({\r\n paginationData,\r\n paginationPageSize,\r\n pageSizeOptions: pageSizeOptionsProp,\r\n isLoading = false,\r\n paramNames,\r\n onPageChange,\r\n onPageSizeChange,\r\n onResetLayout,\r\n renderResetControl,\r\n layoutStatus,\r\n showAllPagesOption = false,\r\n classNames,\r\n className,\r\n}: CustomPaginationProps) {\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n const pageKey = paramNames?.page ?? \"page\";\r\n const perPageKey = paramNames?.perPage ?? \"perPage\";\r\n const pageSizeOptions =\r\n pageSizeOptionsProp ?? paginationPageSize ?? DEFAULT_PAGE_SIZE_OPTIONS;\r\n const perPageParam = searchParams.get(perPageKey);\r\n const perPageNumber =\r\n perPageParam !== null && perPageParam !== \"\"\r\n ? parseInt(perPageParam, 10)\r\n : NaN;\r\n const isShowingAll = perPageNumber === ALL_PAGES_VALUE;\r\n\r\n const currentPage = paginationData\r\n ? Math.max(0, paginationData.currentPage - 1)\r\n : 0;\r\n\r\n const handlePageChange = (pageNumber: number) => {\r\n if (\r\n !paginationData ||\r\n pageNumber < 0 ||\r\n pageNumber >= paginationData.pageCount\r\n ) {\r\n return;\r\n }\r\n\r\n const safePage = Math.max(\r\n 1,\r\n Math.min(pageNumber + 1, paginationData.pageCount)\r\n );\r\n const newParams = new URLSearchParams(searchParams);\r\n newParams.set(pageKey, String(safePage));\r\n setSearchParams(newParams, { replace: true });\r\n onPageChange?.(safePage);\r\n };\r\n\r\n const handlePageSizeChange = (event: ChangeEvent<HTMLSelectElement>) => {\r\n const parsed = parseInt(event.target.value, 10);\r\n if (\r\n !Number.isFinite(parsed) ||\r\n (parsed < 1 && parsed !== ALL_PAGES_VALUE)\r\n ) {\r\n return;\r\n }\r\n\r\n const newParams = new URLSearchParams(searchParams);\r\n newParams.set(pageKey, \"1\");\r\n newParams.set(perPageKey, String(parsed));\r\n setSearchParams(newParams, { replace: true });\r\n onPageSizeChange?.(parsed);\r\n };\r\n\r\n const createPageButtons = () => {\r\n const buttons: ReactNode[] = [];\r\n const maxButtons = 5;\r\n const totalPages = Math.max(1, paginationData?.pageCount ?? 1);\r\n\r\n let startPage = Math.max(0, currentPage - Math.floor(maxButtons / 2));\r\n let endPage = Math.min(totalPages - 1, startPage + maxButtons - 1);\r\n\r\n if (endPage - startPage + 1 < maxButtons) {\r\n startPage = Math.max(0, endPage - maxButtons + 1);\r\n }\r\n\r\n if (startPage > 0) {\r\n buttons.push(\r\n <button\r\n key=\"1\"\r\n type=\"button\"\r\n onClick={() => handlePageChange(0)}\r\n aria-label=\"Page 1\"\r\n className={cn(\r\n \"px-3 py-2 text-sm text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded-md transition-colors\",\r\n classNames?.pageButton\r\n )}\r\n >\r\n 1\r\n </button>\r\n );\r\n\r\n if (startPage > 1) {\r\n buttons.push(\r\n <span\r\n key=\"ellipsis1\"\r\n aria-hidden=\"true\"\r\n className=\"px-2 py-2 text-gray-400\"\r\n >\r\n ...\r\n </span>\r\n );\r\n }\r\n }\r\n\r\n for (let i = startPage; i <= endPage; i++) {\r\n const isActive = currentPage === i;\r\n buttons.push(\r\n <button\r\n key={i + 1}\r\n type=\"button\"\r\n onClick={() => handlePageChange(i)}\r\n aria-label={`Page ${i + 1}`}\r\n aria-current={isActive ? \"page\" : undefined}\r\n className={cn(\r\n \"px-3 py-2 text-sm rounded-md transition-colors\",\r\n isActive\r\n ? cn(\"bg-gray-400 text-white\", classNames?.activePageButton)\r\n : cn(\r\n \"text-gray-600 hover:text-gray-600 hover:bg-gray-50\",\r\n classNames?.pageButton\r\n )\r\n )}\r\n >\r\n {i + 1}\r\n </button>\r\n );\r\n }\r\n\r\n if (endPage < totalPages - 1) {\r\n if (endPage < totalPages - 2) {\r\n buttons.push(\r\n <span\r\n key=\"ellipsis2\"\r\n aria-hidden=\"true\"\r\n className=\"px-2 py-2 text-gray-400\"\r\n >\r\n ...\r\n </span>\r\n );\r\n }\r\n\r\n buttons.push(\r\n <button\r\n key={totalPages}\r\n type=\"button\"\r\n onClick={() => handlePageChange(totalPages - 1)}\r\n aria-label={`Page ${totalPages}`}\r\n className={cn(\r\n \"px-3 py-2 text-sm text-gray-600 hover:text-gray-600 hover:bg-gray-50 rounded-md transition-colors\",\r\n classNames?.pageButton\r\n )}\r\n >\r\n {totalPages}\r\n </button>\r\n );\r\n }\r\n\r\n return buttons;\r\n };\r\n\r\n if (isLoading || !paginationData) {\r\n return (\r\n <div className=\"flex items-center justify-center p-6 bg-gray-50\">\r\n <span className=\"text-gray-500\">\r\n {isLoading ? \"Loading...\" : \"No pagination data\"}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n const effectiveSizeOptions =\r\n paginationData.perPage > 0 &&\r\n !pageSizeOptions.includes(paginationData.perPage)\r\n ? [...pageSizeOptions, paginationData.perPage].sort((a, b) => a - b)\r\n : pageSizeOptions;\r\n\r\n const selectValue = isShowingAll\r\n ? ALL_PAGES_VALUE\r\n : paginationData.perPage ||\r\n (Number.isFinite(perPageNumber) && perPageNumber > 0\r\n ? perPageNumber\r\n : 10);\r\n\r\n const startItem =\r\n paginationData.totalCount === 0\r\n ? 0\r\n : (paginationData.currentPage - 1) * paginationData.perPage + 1;\r\n const endItem = Math.min(\r\n startItem + paginationData.perPage - 1,\r\n paginationData.totalCount\r\n );\r\n\r\n const { isLayoutLoading, isLayoutSaving, isLayoutResetting } =\r\n layoutStatus ?? {};\r\n const isLayoutBusy =\r\n isLayoutLoading || isLayoutSaving || isLayoutResetting;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"flex items-center justify-between pb-4\",\r\n className,\r\n classNames?.root\r\n )}\r\n >\r\n <div className={cn(\"flex-1\", classNames?.info)}>\r\n <span className=\"text-xs font-medium text-neutral-400\">\r\n {isShowingAll\r\n ? `Showing All ${paginationData.totalCount ?? 0} Results`\r\n : `Showing ${padCount(startItem)} - ${padCount(endItem)} of ${paginationData.totalCount ?? 0} results`}\r\n </span>\r\n </div>\r\n\r\n <nav\r\n aria-label=\"Pagination\"\r\n className={cn(\"flex items-center space-x-1\", classNames?.nav)}\r\n >\r\n <button\r\n type=\"button\"\r\n onClick={() => handlePageChange(currentPage - 1)}\r\n disabled={currentPage === 0 || isShowingAll}\r\n className=\"p-2 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed transition-colors\"\r\n aria-label=\"Previous page\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <path d=\"M10.7 2.3a1 1 0 0 1 0 1.4L6.4 8l4.3 4.3a1 1 0 1 1-1.4 1.4l-5-5a1 1 0 0 1 0-1.4l5-5a1 1 0 0 1 1.4 0z\" />\r\n </svg>\r\n </button>\r\n\r\n <div className=\"flex items-center space-x-1\">\r\n {isShowingAll ? (\r\n <span className=\"px-3 py-2 text-sm text-gray-400\" aria-hidden=\"true\">\r\n All\r\n </span>\r\n ) : (\r\n createPageButtons()\r\n )}\r\n </div>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => handlePageChange(currentPage + 1)}\r\n disabled={\r\n currentPage >= paginationData.pageCount - 1 || isShowingAll\r\n }\r\n className=\"p-2 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed transition-colors\"\r\n aria-label=\"Next page\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <path d=\"M5.3 13.7a1 1 0 0 1 0-1.4L9.6 8 5.3 3.7a1 1 0 0 1 1.4-1.4l5 5a1 1 0 0 1 0 1.4l-5 5a1 1 0 0 1-1.4 0z\" />\r\n </svg>\r\n </button>\r\n </nav>\r\n\r\n <div className=\"flex-1 flex justify-end\">\r\n <div className=\"flex items-center gap-3\">\r\n {onResetLayout &&\r\n (renderResetControl ? (\r\n renderResetControl(onResetLayout)\r\n ) : (\r\n <ResetColumnsButton\r\n onReset={onResetLayout}\r\n disabled={isLayoutBusy}\r\n isLoading={isLoading}\r\n />\r\n ))}\r\n <div className=\"flex items-center space-x-2\">\r\n <label\r\n htmlFor=\"pagination-per-page\"\r\n className=\"text-sm text-gray-600\"\r\n >\r\n Items per page\r\n </label>\r\n <select\r\n id=\"pagination-per-page\"\r\n value={selectValue}\r\n onChange={handlePageSizeChange}\r\n className={cn(\r\n \"px-3 py-1.5 text-sm border border-gray-300 rounded-md bg-white text-gray-700 hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors\",\r\n classNames?.select\r\n )}\r\n >\r\n {showAllPagesOption && (\r\n <option value={ALL_PAGES_VALUE}>All</option>\r\n )}\r\n {effectiveSizeOptions.map((option) => (\r\n <option key={option} value={option}>\r\n {option}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default CustomPagination;\r\n"],"mappings":"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","names":["clsx","Swal","toast","import_react","import_react","import_jsx_runtime"]}
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","../src/components/tabs/EztrakTabs.tsx","../src/components/pagination/CustomPagination.tsx"],"sourcesContent":["export * from \"./utils\";\r\nexport * from \"./hooks\";\r\nexport * from \"./components\";\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) => {\r\n if (!text) return \"\";\r\n if (text.length <= maxLength) {\r\n return text;\r\n }\r\n return text.slice(0, maxLength - 3) + \"...\";\r\n};\r\n\r\nexport const truncateFileName = (\r\n fileName: string | null | undefined,\r\n maxLength = 20\r\n): string => {\r\n if (!fileName) return \"\";\r\n if (fileName.length <= maxLength) {\r\n return fileName;\r\n }\r\n const extension = fileName.slice(fileName.lastIndexOf(\".\"));\r\n const truncatedName =\r\n fileName.slice(0, maxLength - extension.length - 3) + \"...\";\r\n return truncatedName + extension;\r\n};\r\n\r\nexport function getApiError(apiError: unknown): string {\r\n if (!apiError) return \"An unknown error occurred\";\r\n\r\n if (typeof apiError === \"string\") {\r\n return apiError;\r\n }\r\n\r\n const error = apiError as {\r\n response?: { data?: Record<string, unknown> };\r\n message?: string;\r\n };\r\n\r\n if (error.response?.data) {\r\n const responseData = error.response.data;\r\n\r\n if (typeof responseData === \"string\") {\r\n return responseData;\r\n }\r\n\r\n const errors = responseData.errors;\r\n if (errors && typeof errors === \"object\") {\r\n for (const key in errors) {\r\n const messages = (errors as Record<string, unknown>)[key];\r\n if (Array.isArray(messages) && messages.length > 0) {\r\n return String(messages[0]);\r\n }\r\n }\r\n }\r\n\r\n if (responseData.message) {\r\n return String(responseData.message);\r\n }\r\n\r\n if (responseData.title) {\r\n return String(responseData.title);\r\n }\r\n }\r\n\r\n if (error.message) {\r\n return error.message;\r\n }\r\n\r\n return \"An unknown error occurred\";\r\n}\r\n\r\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\r\n if (responseData == null) return [];\r\n if (Array.isArray(responseData)) return responseData;\r\n\r\n const record = responseData as Record<string, unknown>;\r\n const data = record.data;\r\n\r\n if (\r\n data &&\r\n typeof data === \"object\" &&\r\n !Array.isArray(data) &&\r\n Array.isArray((data as { items?: unknown[] }).items)\r\n ) {\r\n return (data as { items: unknown[] }).items;\r\n }\r\n\r\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\r\n if (Array.isArray(returnModel?.items)) return returnModel.items;\r\n if (Array.isArray(data)) return data;\r\n if (typeof data === \"object\" && data !== null) {\r\n return [data];\r\n }\r\n return [];\r\n};\r\n\r\nexport function capitalizeText(name: string | null | undefined): string {\r\n if (!name) return \"\";\r\n return name\r\n .split(\" \")\r\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\r\n .join(\" \");\r\n}\r\n\r\nexport function toLowerCaseText(text: string | null | undefined): string {\r\n if (!text) return \"\";\r\n return text.toLowerCase();\r\n}\r\n\r\nexport const formatDate = (dateString: string | null | undefined): string => {\r\n if (dateString === null || dateString === undefined) return \"-\";\r\n const date = new Date(dateString);\r\n\r\n if (isNaN(date.getTime())) {\r\n return dateString;\r\n }\r\n\r\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = date.getDate().toString().padStart(2, \"0\");\r\n const year = date.getFullYear().toString().slice(-2);\r\n return `${month}/${day}/${year}`;\r\n};\r\n\r\nexport const isEmpty = (obj: object): boolean => {\r\n return Object.keys(obj).length === 0;\r\n};\r\n\r\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\r\n if (!date) return \"\";\r\n\r\n let d: Date;\r\n\r\n if (typeof date === \"string\") {\r\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\r\n return date;\r\n }\r\n d = new Date(date);\r\n } else {\r\n d = new Date(date);\r\n }\r\n\r\n if (isNaN(d.getTime())) return \"\";\r\n\r\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\r\n const year = localDate.getFullYear();\r\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = localDate.getDate().toString().padStart(2, \"0\");\r\n\r\n return `${year}-${month}-${day}`;\r\n};\r\n\r\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\r\n if (!data || data.trim() === \"\") {\r\n return [];\r\n }\r\n return data.split(\",\").map((item) => item.trim());\r\n}\r\n\r\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\r\n return array.includes(searchValue);\r\n}\r\n\r\nexport const currencyFormatter = (value: number | null | undefined): string => {\r\n return value?.toLocaleString(\"en-US\", {\r\n style: \"currency\",\r\n currency: \"USD\",\r\n }) ?? \"\";\r\n};\r\nexport const formatNumber = (number: number | string | null | undefined): string => {\r\n if (isNaN(Number(number)) || number === null || number === undefined) {\r\n return \"0\";\r\n }\r\n\r\n const formattedNumber = Number(number)\r\n .toString()\r\n .replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\r\n\r\n return formattedNumber;\r\n};\r\n\r\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\r\n if (value == null || value === \"\") return 0;\r\n\r\n const raw =\r\n typeof value === \"object\" && value !== null && \"value\" in value\r\n ? (value as { value: unknown }).value\r\n : value;\r\n\r\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\r\n const numericValue = stringValue.replace(/[$,]/g, \"\");\r\n return parseFloat(numericValue) || 0;\r\n};\r\n\r\nexport function flattenTableData<T extends Record<string, unknown>>(\r\n data: T[] | null | undefined,\r\n columns: { field?: string }[] | null | undefined\r\n): T[] {\r\n if (!Array.isArray(data)) return [];\r\n return data.map((row) => {\r\n const flatRow = { ...row };\r\n (columns ?? []).forEach((col) => {\r\n const key = col.field;\r\n if (!key) return;\r\n if (key.includes(\".\")) {\r\n const value = key.split(\".\").reduce<unknown>(\r\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\r\n row\r\n );\r\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\r\n }\r\n });\r\n return flatRow;\r\n });\r\n}\r\n\r\nexport const getErrorMessages = (error: {\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n title?: string;\r\n error?: { name?: string[] };\r\n };\r\n} | null | undefined): string => {\r\n if (error?.data?.errors) {\r\n return Object.values(error.data.errors).flat().join(\"\\n\");\r\n }\r\n return (\r\n error?.data?.title ??\r\n error?.data?.error?.name?.[0] ??\r\n \"Failed to save\"\r\n );\r\n};\r\n\r\nexport const getFieldsByCategory = <T extends { category?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields?.filter(({ category = \"\" }) => category === key);\r\n};\r\n\r\nexport const getFieldsByName = <T extends { name?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ name = \"\" }) => name === key);\r\n};\r\n\r\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\r\n try {\r\n return JSON.parse(jsonString) as T;\r\n } catch (error) {\r\n console.error(\"Error parsing JSON:\", error);\r\n return null;\r\n }\r\n};\r\n\r\nexport const formatDateTime = (dateString: string | null | undefined): string => {\r\n if (!dateString) return \"Invalid Date\";\r\n const date = new Date(dateString);\r\n if (isNaN(date.getTime())) return \"Invalid Date\";\r\n const options: Intl.DateTimeFormatOptions = {\r\n year: \"numeric\",\r\n month: \"numeric\",\r\n day: \"numeric\",\r\n hour: \"numeric\",\r\n minute: \"numeric\",\r\n hour12: true,\r\n };\r\n return date.toLocaleString(\"en-US\", options);\r\n};\r\n\r\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\r\n items: T[] = [],\r\n property: keyof T & string,\r\n values: unknown[] = [],\r\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\r\n): T[] => {\r\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\r\n const normalize = (v: unknown) =>\r\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\r\n const valuesArr = Array.isArray(values) ? values : [values];\r\n const toRemove = new Set(valuesArr.map(normalize));\r\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\r\n};\r\n\r\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ inputType = \"\" }) => inputType === key);\r\n};\r\n","import toast from \"react-hot-toast\";\r\nimport Swal from \"sweetalert2\";\r\n\r\nexport type RtkQueryError = {\r\n status?: number | string;\r\n originalStatus?: number;\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n message?: string;\r\n title?: string;\r\n };\r\n error?: string;\r\n};\r\n\r\nexport interface HandleApiErrorOptions {\r\n showAlert?: boolean;\r\n fallbackMessage?: string;\r\n}\r\n\r\nexport function formatValidationErrorsHtml(\r\n errors: Record<string, string[]>\r\n): string {\r\n const items = Object.keys(errors).flatMap((field) =>\r\n (errors[field] || []).map((msg) => `<li>${msg}</li>`)\r\n );\r\n return `\r\n <div style=\"text-align:left\">\r\n <p>Please review and correct the following:</p>\r\n <ul style=\"margin:8px 0 0 16px; list-style:disc;\">\r\n ${items.join(\"\")}\r\n </ul>\r\n </div>\r\n `;\r\n}\r\n\r\nfunction showValidationAlert(html: string): void {\r\n void Swal.fire({\r\n title: \"Validation errors\",\r\n html,\r\n icon: \"error\",\r\n confirmButtonText: \"OK\",\r\n showCancelButton: false,\r\n confirmButtonColor: \"#FF7335\",\r\n });\r\n}\r\n\r\n/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */\r\nexport function handleApiError(\r\n error: RtkQueryError | null | undefined,\r\n { showAlert = false, fallbackMessage }: HandleApiErrorOptions = {}\r\n): void {\r\n if (!error) return;\r\n\r\n const status = error.status ?? error.originalStatus;\r\n const data = error.data;\r\n\r\n if (status === 200) {\r\n return;\r\n }\r\n\r\n if (data?.errors && typeof data.errors === \"object\") {\r\n const errors = data.errors;\r\n\r\n if (showAlert) {\r\n showValidationAlert(formatValidationErrorsHtml(errors));\r\n } else {\r\n Object.keys(errors).forEach((field) => {\r\n (errors[field] || []).forEach((errorMessage) => {\r\n toast.error(errorMessage);\r\n });\r\n });\r\n }\r\n return;\r\n }\r\n\r\n if (status === 404) {\r\n return;\r\n }\r\n\r\n const message =\r\n fallbackMessage ||\r\n data?.message ||\r\n data?.title ||\r\n error.error ||\r\n \"An error occurred. Please try again.\";\r\n\r\n toast.error(message);\r\n}\r\n\r\nexport interface ConfirmationAlertOptions {\r\n title?: string;\r\n text?: string;\r\n icon?: \"warning\" | \"info\" | \"question\" | \"error\" | \"success\";\r\n confirmButtonText?: string;\r\n cancelButtonText?: string;\r\n}\r\n\r\nexport function confirmationAlert(\r\n onConfirm: () => void,\r\n options: ConfirmationAlertOptions = {}\r\n): void {\r\n void Swal.fire({\r\n title: options.title ?? \"Are you sure?\",\r\n text: options.text,\r\n icon: options.icon ?? \"warning\",\r\n showCancelButton: true,\r\n confirmButtonText: options.confirmButtonText ?? \"Yes\",\r\n cancelButtonText: options.cancelButtonText ?? \"Cancel\",\r\n confirmButtonColor: \"#FF7335\",\r\n }).then((result) => {\r\n if (result.isConfirmed) {\r\n onConfirm();\r\n }\r\n });\r\n}\r\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","import {\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useRef,\r\n useState,\r\n type KeyboardEvent,\r\n} from \"react\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport type { EztrakTab, EztrakTabsProps } from \"./types\";\r\n\r\nfunction getInitialTabId(\r\n tabs: EztrakTab[],\r\n defaultTabId?: string\r\n): string | undefined {\r\n if (defaultTabId && tabs.some((t) => t.id === defaultTabId && !t.disabled)) {\r\n return defaultTabId;\r\n }\r\n return tabs.find((t) => !t.disabled)?.id;\r\n}\r\n\r\nfunction getEnabledTabIds(tabs: EztrakTab[]): string[] {\r\n return tabs.filter((t) => !t.disabled).map((t) => t.id);\r\n}\r\n\r\nexport function EztrakTabs({\r\n tabs,\r\n activeTab,\r\n defaultTabId,\r\n onTabChange,\r\n showPanels = true,\r\n keepMounted = false,\r\n classNames,\r\n className,\r\n}: EztrakTabsProps) {\r\n const baseId = useId().replace(/:/g, \"\");\r\n const isControlled = activeTab !== undefined && activeTab !== null;\r\n const [uncontrolledActive, setUncontrolledActive] = useState(() =>\r\n getInitialTabId(tabs, defaultTabId)\r\n );\r\n const tabRefs = useRef<Map<string, HTMLButtonElement>>(new Map());\r\n\r\n const displayActive = isControlled ? activeTab : uncontrolledActive;\r\n\r\n useEffect(() => {\r\n if (isControlled) return;\r\n const enabledIds = getEnabledTabIds(tabs);\r\n if (!displayActive || !enabledIds.includes(displayActive)) {\r\n const next = getInitialTabId(tabs, defaultTabId);\r\n if (next !== displayActive) {\r\n setUncontrolledActive(next);\r\n }\r\n }\r\n }, [tabs, defaultTabId, isControlled, displayActive]);\r\n\r\n const handleTabClick = useCallback(\r\n (tabId: string, disabled?: boolean) => {\r\n if (disabled) return;\r\n if (!isControlled) {\r\n setUncontrolledActive(tabId);\r\n }\r\n onTabChange?.(tabId);\r\n },\r\n [isControlled, onTabChange]\r\n );\r\n\r\n const focusTab = useCallback((tabId: string) => {\r\n tabRefs.current.get(tabId)?.focus();\r\n }, []);\r\n\r\n const handleListKeyDown = useCallback(\r\n (event: KeyboardEvent<HTMLUListElement>) => {\r\n const enabledIds = getEnabledTabIds(tabs);\r\n if (enabledIds.length === 0) return;\r\n\r\n const currentIndex = displayActive\r\n ? enabledIds.indexOf(displayActive)\r\n : -1;\r\n let nextIndex = currentIndex;\r\n\r\n switch (event.key) {\r\n case \"ArrowRight\":\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n nextIndex =\r\n currentIndex < 0\r\n ? 0\r\n : (currentIndex + 1) % enabledIds.length;\r\n break;\r\n case \"ArrowLeft\":\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n nextIndex =\r\n currentIndex < 0\r\n ? enabledIds.length - 1\r\n : (currentIndex - 1 + enabledIds.length) % enabledIds.length;\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n nextIndex = 0;\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n nextIndex = enabledIds.length - 1;\r\n break;\r\n default:\r\n return;\r\n }\r\n\r\n const nextId = enabledIds[nextIndex];\r\n if (nextId) {\r\n handleTabClick(nextId);\r\n focusTab(nextId);\r\n }\r\n },\r\n [tabs, displayActive, handleTabClick, focusTab]\r\n );\r\n\r\n if (!tabs.length) {\r\n return null;\r\n }\r\n\r\n const wrapperClass = cn(\r\n \"eztrak-tabs-wrapper\",\r\n classNames?.wrapper,\r\n className\r\n );\r\n\r\n return (\r\n <div className={wrapperClass}>\r\n <div className={cn(\"eztrak-tabs-container\", classNames?.container)}>\r\n <nav\r\n className={cn(\"eztrak-tabs-nav\", classNames?.nav)}\r\n aria-label=\"Tabs\"\r\n >\r\n <ul\r\n role=\"tablist\"\r\n className={cn(\"eztrak-tabs-list\", classNames?.list)}\r\n onKeyDown={handleListKeyDown}\r\n >\r\n {tabs.map((tab) => {\r\n const isActive = displayActive === tab.id;\r\n const tabId = `${baseId}-tab-${tab.id}`;\r\n const panelId = `${baseId}-panel-${tab.id}`;\r\n\r\n return (\r\n <li\r\n key={tab.id}\r\n role=\"presentation\"\r\n className={cn(\r\n \"eztrak-tabs-item\",\r\n isActive && \"eztrak-tabs-item-active\",\r\n classNames?.item,\r\n isActive && classNames?.itemActive\r\n )}\r\n >\r\n <button\r\n ref={(el) => {\r\n if (el) {\r\n tabRefs.current.set(tab.id, el);\r\n } else {\r\n tabRefs.current.delete(tab.id);\r\n }\r\n }}\r\n type=\"button\"\r\n role=\"tab\"\r\n id={tabId}\r\n aria-selected={isActive}\r\n aria-controls={showPanels ? panelId : undefined}\r\n tabIndex={isActive ? 0 : -1}\r\n disabled={tab.disabled}\r\n className={cn(\r\n \"eztrak-tabs-button\",\r\n isActive && \"eztrak-tabs-button-active\",\r\n classNames?.button,\r\n isActive && classNames?.buttonActive\r\n )}\r\n onClick={() => handleTabClick(tab.id, tab.disabled)}\r\n >\r\n {tab.icon ? (\r\n <span\r\n className={cn(\"eztrak-tabs-icon\", classNames?.icon)}\r\n aria-hidden\r\n >\r\n {tab.icon}\r\n </span>\r\n ) : null}\r\n <span\r\n className={cn(\"eztrak-tabs-label\", classNames?.label)}\r\n >\r\n {tab.label}\r\n </span>\r\n {isActive ? (\r\n <span\r\n className={cn(\r\n \"eztrak-tabs-underline\",\r\n classNames?.underline\r\n )}\r\n aria-hidden\r\n />\r\n ) : null}\r\n </button>\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n </nav>\r\n\r\n {showPanels ? (\r\n <div className={cn(\"eztrak-tabs-content\", classNames?.content)}>\r\n {tabs.map((tab) => {\r\n const isActive = displayActive === tab.id;\r\n const panelId = `${baseId}-panel-${tab.id}`;\r\n const tabId = `${baseId}-tab-${tab.id}`;\r\n\r\n if (!keepMounted && !isActive) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div\r\n key={tab.id}\r\n id={panelId}\r\n role=\"tabpanel\"\r\n aria-labelledby={tabId}\r\n hidden={!isActive}\r\n className={cn(\"eztrak-tabs-panel\", classNames?.panel)}\r\n >\r\n {tab.content}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n ) : null}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { type ChangeEvent, type ReactNode } from \"react\";\r\nimport { useSearchParams } from \"react-router-dom\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { confirmationAlert } from \"../../utils/handleApiError\";\r\nimport type {\r\n CustomPaginationProps,\r\n ResetColumnsButtonProps,\r\n TableLayoutToolbarControlsProps,\r\n} from \"./types\";\r\n\r\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 30, 50, 100];\r\nconst ALL_PAGES_VALUE = -1;\r\n\r\nfunction padCount(num: number) {\r\n return num.toString().padStart(2, \"0\");\r\n}\r\n\r\nfunction RefreshIcon({\r\n size = 14,\r\n className,\r\n}: {\r\n size?: number;\r\n className?: string;\r\n}) {\r\n return (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden=\"true\"\r\n className={className}\r\n >\r\n <path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" />\r\n <path d=\"M21 3v5h-5\" />\r\n <path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" />\r\n <path d=\"M8 16H3v5\" />\r\n </svg>\r\n );\r\n}\r\n\r\nexport function ResetColumnsButton({\r\n onReset,\r\n disabled = false,\r\n isLoading = false,\r\n}: ResetColumnsButtonProps) {\r\n const handleClick = () => {\r\n confirmationAlert(onReset, {\r\n text: \"Reset column order, widths, and visibility to defaults?\",\r\n icon: \"warning\",\r\n title: \"Reset column layout to default\",\r\n });\r\n };\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={handleClick}\r\n disabled={disabled || isLoading}\r\n title=\"Reset column layout to default\"\r\n className=\"inline-flex items-center gap-1.5 rounded-xl border border-primary-150 bg-white px-3 py-1.5 text-sm font-medium text-primary-150 hover:bg-gray-50 focus:outline-none disabled:hover:bg-white\"\r\n >\r\n <RefreshIcon size={14} className={cn(isLoading ? \"animate-spin\" : \"\")} />\r\n Reset columns\r\n </button>\r\n );\r\n}\r\n\r\nexport function TableLayoutToolbarControls({\r\n layoutStatus = {},\r\n onResetLayout,\r\n renderResetControl,\r\n isLoading = false,\r\n}: TableLayoutToolbarControlsProps) {\r\n const { isLayoutLoading, isLayoutSaving, isLayoutResetting } = layoutStatus;\r\n const isLayoutBusy = isLayoutLoading || isLayoutSaving || isLayoutResetting;\r\n\r\n return (\r\n <div className=\"flex items-center gap-3\">\r\n {onResetLayout &&\r\n (renderResetControl ? (\r\n renderResetControl(onResetLayout)\r\n ) : (\r\n <ResetColumnsButton\r\n onReset={onResetLayout}\r\n disabled={isLayoutBusy}\r\n isLoading={isLoading}\r\n />\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CustomPagination({\r\n paginationData,\r\n paginationPageSize,\r\n pageSizeOptions: pageSizeOptionsProp,\r\n isLoading = false,\r\n paramNames,\r\n onPageChange,\r\n onPageSizeChange,\r\n onResetLayout,\r\n renderResetControl,\r\n layoutStatus,\r\n showAllPagesOption = false,\r\n classNames,\r\n className,\r\n}: CustomPaginationProps) {\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n const pageKey = paramNames?.page ?? \"page\";\r\n const perPageKey = paramNames?.perPage ?? \"perPage\";\r\n const pageSizeOptions =\r\n pageSizeOptionsProp ?? paginationPageSize ?? DEFAULT_PAGE_SIZE_OPTIONS;\r\n const perPageParam = searchParams.get(perPageKey);\r\n const perPageNumber =\r\n perPageParam !== null && perPageParam !== \"\"\r\n ? parseInt(perPageParam, 10)\r\n : NaN;\r\n const isShowingAll = perPageNumber === ALL_PAGES_VALUE;\r\n\r\n const currentPage = paginationData\r\n ? Math.max(0, paginationData.currentPage - 1)\r\n : 0;\r\n\r\n const handlePageChange = (pageNumber: number) => {\r\n if (\r\n !paginationData ||\r\n pageNumber < 0 ||\r\n pageNumber >= paginationData.pageCount\r\n ) {\r\n return;\r\n }\r\n\r\n const safePage = Math.max(\r\n 1,\r\n Math.min(pageNumber + 1, paginationData.pageCount)\r\n );\r\n const newParams = new URLSearchParams(searchParams);\r\n newParams.set(pageKey, String(safePage));\r\n setSearchParams(newParams, { replace: true });\r\n onPageChange?.(safePage);\r\n };\r\n\r\n const handlePageSizeChange = (event: ChangeEvent<HTMLSelectElement>) => {\r\n const parsed = parseInt(event.target.value, 10);\r\n if (\r\n !Number.isFinite(parsed) ||\r\n (parsed < 1 && parsed !== ALL_PAGES_VALUE)\r\n ) {\r\n return;\r\n }\r\n\r\n const newParams = new URLSearchParams(searchParams);\r\n newParams.set(pageKey, \"1\");\r\n newParams.set(perPageKey, String(parsed));\r\n setSearchParams(newParams, { replace: true });\r\n onPageSizeChange?.(parsed);\r\n };\r\n\r\n const createPageButtons = () => {\r\n const buttons: ReactNode[] = [];\r\n const maxButtons = 5;\r\n const totalPages = Math.max(1, paginationData?.pageCount ?? 1);\r\n\r\n let startPage = Math.max(0, currentPage - Math.floor(maxButtons / 2));\r\n let endPage = Math.min(totalPages - 1, startPage + maxButtons - 1);\r\n\r\n if (endPage - startPage + 1 < maxButtons) {\r\n startPage = Math.max(0, endPage - maxButtons + 1);\r\n }\r\n\r\n if (startPage > 0) {\r\n buttons.push(\r\n <button\r\n key=\"1\"\r\n type=\"button\"\r\n onClick={() => handlePageChange(0)}\r\n aria-label=\"Page 1\"\r\n className={cn(\r\n \"px-3 py-2 text-sm text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded-md transition-colors\",\r\n classNames?.pageButton\r\n )}\r\n >\r\n 1\r\n </button>\r\n );\r\n\r\n if (startPage > 1) {\r\n buttons.push(\r\n <span\r\n key=\"ellipsis1\"\r\n aria-hidden=\"true\"\r\n className=\"px-2 py-2 text-gray-400\"\r\n >\r\n ...\r\n </span>\r\n );\r\n }\r\n }\r\n\r\n for (let i = startPage; i <= endPage; i++) {\r\n const isActive = currentPage === i;\r\n buttons.push(\r\n <button\r\n key={i + 1}\r\n type=\"button\"\r\n onClick={() => handlePageChange(i)}\r\n aria-label={`Page ${i + 1}`}\r\n aria-current={isActive ? \"page\" : undefined}\r\n className={cn(\r\n \"px-3 py-2 text-sm rounded-md transition-colors\",\r\n isActive\r\n ? cn(\"bg-gray-400 text-white\", classNames?.activePageButton)\r\n : cn(\r\n \"text-gray-600 hover:text-gray-600 hover:bg-gray-50\",\r\n classNames?.pageButton\r\n )\r\n )}\r\n >\r\n {i + 1}\r\n </button>\r\n );\r\n }\r\n\r\n if (endPage < totalPages - 1) {\r\n if (endPage < totalPages - 2) {\r\n buttons.push(\r\n <span\r\n key=\"ellipsis2\"\r\n aria-hidden=\"true\"\r\n className=\"px-2 py-2 text-gray-400\"\r\n >\r\n ...\r\n </span>\r\n );\r\n }\r\n\r\n buttons.push(\r\n <button\r\n key={totalPages}\r\n type=\"button\"\r\n onClick={() => handlePageChange(totalPages - 1)}\r\n aria-label={`Page ${totalPages}`}\r\n className={cn(\r\n \"px-3 py-2 text-sm text-gray-600 hover:text-gray-600 hover:bg-gray-50 rounded-md transition-colors\",\r\n classNames?.pageButton\r\n )}\r\n >\r\n {totalPages}\r\n </button>\r\n );\r\n }\r\n\r\n return buttons;\r\n };\r\n\r\n if (isLoading || !paginationData) {\r\n return (\r\n <div className=\"flex items-center justify-center p-6 bg-gray-50\">\r\n <span className=\"text-gray-500\">\r\n {isLoading ? \"Loading...\" : \"No pagination data\"}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n const effectiveSizeOptions =\r\n paginationData.perPage > 0 &&\r\n !pageSizeOptions.includes(paginationData.perPage)\r\n ? [...pageSizeOptions, paginationData.perPage].sort((a, b) => a - b)\r\n : pageSizeOptions;\r\n\r\n const selectValue = isShowingAll\r\n ? ALL_PAGES_VALUE\r\n : paginationData.perPage ||\r\n (Number.isFinite(perPageNumber) && perPageNumber > 0\r\n ? perPageNumber\r\n : 10);\r\n\r\n const startItem =\r\n paginationData.totalCount === 0\r\n ? 0\r\n : (paginationData.currentPage - 1) * paginationData.perPage + 1;\r\n const endItem = Math.min(\r\n startItem + paginationData.perPage - 1,\r\n paginationData.totalCount\r\n );\r\n\r\n const { isLayoutLoading, isLayoutSaving, isLayoutResetting } =\r\n layoutStatus ?? {};\r\n const isLayoutBusy =\r\n isLayoutLoading || isLayoutSaving || isLayoutResetting;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"flex items-center justify-between pb-4\",\r\n className,\r\n classNames?.root\r\n )}\r\n >\r\n <div className={cn(\"flex-1\", classNames?.info)}>\r\n <span className=\"text-xs font-medium text-neutral-400\">\r\n {isShowingAll\r\n ? `Showing All ${paginationData.totalCount ?? 0} Results`\r\n : `Showing ${padCount(startItem)} - ${padCount(endItem)} of ${paginationData.totalCount ?? 0} results`}\r\n </span>\r\n </div>\r\n\r\n <nav\r\n aria-label=\"Pagination\"\r\n className={cn(\"flex items-center space-x-1\", classNames?.nav)}\r\n >\r\n <button\r\n type=\"button\"\r\n onClick={() => handlePageChange(currentPage - 1)}\r\n disabled={currentPage === 0 || isShowingAll}\r\n className=\"p-2 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed transition-colors\"\r\n aria-label=\"Previous page\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <path d=\"M10.7 2.3a1 1 0 0 1 0 1.4L6.4 8l4.3 4.3a1 1 0 1 1-1.4 1.4l-5-5a1 1 0 0 1 0-1.4l5-5a1 1 0 0 1 1.4 0z\" />\r\n </svg>\r\n </button>\r\n\r\n <div className=\"flex items-center space-x-1\">\r\n {isShowingAll ? (\r\n <span className=\"px-3 py-2 text-sm text-gray-400\" aria-hidden=\"true\">\r\n All\r\n </span>\r\n ) : (\r\n createPageButtons()\r\n )}\r\n </div>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => handlePageChange(currentPage + 1)}\r\n disabled={\r\n currentPage >= paginationData.pageCount - 1 || isShowingAll\r\n }\r\n className=\"p-2 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed transition-colors\"\r\n aria-label=\"Next page\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <path d=\"M5.3 13.7a1 1 0 0 1 0-1.4L9.6 8 5.3 3.7a1 1 0 0 1 1.4-1.4l5 5a1 1 0 0 1 0 1.4l-5 5a1 1 0 0 1-1.4 0z\" />\r\n </svg>\r\n </button>\r\n </nav>\r\n\r\n <div className=\"flex-1 flex justify-end\">\r\n <div className=\"flex items-center gap-3\">\r\n {onResetLayout &&\r\n (renderResetControl ? (\r\n renderResetControl(onResetLayout)\r\n ) : (\r\n <ResetColumnsButton\r\n onReset={onResetLayout}\r\n disabled={isLayoutBusy}\r\n isLoading={isLoading}\r\n />\r\n ))}\r\n <div className=\"flex items-center space-x-2\">\r\n <label\r\n htmlFor=\"pagination-per-page\"\r\n className=\"text-sm text-gray-600\"\r\n >\r\n Items per page\r\n </label>\r\n <select\r\n id=\"pagination-per-page\"\r\n value={selectValue}\r\n onChange={handlePageSizeChange}\r\n className={cn(\r\n \"px-3 py-1.5 text-sm border border-gray-300 rounded-md bg-white text-gray-700 hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors\",\r\n classNames?.select\r\n )}\r\n >\r\n {showAllPagesOption && (\r\n <option value={ALL_PAGES_VALUE}>All</option>\r\n )}\r\n {effectiveSizeOptions.map((option) => (\r\n <option key={option} value={option}>\r\n {option}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default CustomPagination;\r\n"],"mappings":"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","names":["clsx","Swal","toast","import_react","import_react","import_jsx_runtime"]}
package/dist/index.mjs CHANGED
@@ -19,8 +19,9 @@ import {
19
19
  removeByPropertyValues,
20
20
  toDateInputValue,
21
21
  toLowerCaseText,
22
+ truncateFileName,
22
23
  truncateText
23
- } from "./chunk-M7SOJOJI.mjs";
24
+ } from "./chunk-HZGVVROQ.mjs";
24
25
  import {
25
26
  useGridHeight,
26
27
  usePaginationUrlSync
@@ -66,6 +67,7 @@ export {
66
67
  removeByPropertyValues,
67
68
  toDateInputValue,
68
69
  toLowerCaseText,
70
+ truncateFileName,
69
71
  truncateText,
70
72
  useGridHeight,
71
73
  usePaginationUrlSync
@@ -3,6 +3,7 @@ import clsx from 'clsx';
3
3
  declare function cn(...inputs: Parameters<typeof clsx>): string;
4
4
 
5
5
  declare const truncateText: (text: string | null | undefined, maxLength?: number) => string;
6
+ declare const truncateFileName: (fileName: string | null | undefined, maxLength?: number) => string;
6
7
  declare function getApiError(apiError: unknown): string;
7
8
  declare const normalizeApiListItems: (responseData: unknown) => unknown[];
8
9
  declare function capitalizeText(name: string | null | undefined): string;
@@ -68,4 +69,4 @@ interface ConfirmationAlertOptions {
68
69
  }
69
70
  declare function confirmationAlert(onConfirm: () => void, options?: ConfirmationAlertOptions): void;
70
71
 
71
- export { type ConfirmationAlertOptions, type HandleApiErrorOptions, type RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatNumber, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText };
72
+ export { type ConfirmationAlertOptions, type HandleApiErrorOptions, type RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatNumber, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateFileName, truncateText };
@@ -3,6 +3,7 @@ import clsx from 'clsx';
3
3
  declare function cn(...inputs: Parameters<typeof clsx>): string;
4
4
 
5
5
  declare const truncateText: (text: string | null | undefined, maxLength?: number) => string;
6
+ declare const truncateFileName: (fileName: string | null | undefined, maxLength?: number) => string;
6
7
  declare function getApiError(apiError: unknown): string;
7
8
  declare const normalizeApiListItems: (responseData: unknown) => unknown[];
8
9
  declare function capitalizeText(name: string | null | undefined): string;
@@ -68,4 +69,4 @@ interface ConfirmationAlertOptions {
68
69
  }
69
70
  declare function confirmationAlert(onConfirm: () => void, options?: ConfirmationAlertOptions): void;
70
71
 
71
- export { type ConfirmationAlertOptions, type HandleApiErrorOptions, type RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatNumber, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText };
72
+ export { type ConfirmationAlertOptions, type HandleApiErrorOptions, type RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatNumber, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateFileName, truncateText };
@@ -54,6 +54,7 @@ __export(utils_exports, {
54
54
  removeByPropertyValues: () => removeByPropertyValues,
55
55
  toDateInputValue: () => toDateInputValue,
56
56
  toLowerCaseText: () => toLowerCaseText,
57
+ truncateFileName: () => truncateFileName,
57
58
  truncateText: () => truncateText
58
59
  });
59
60
  module.exports = __toCommonJS(utils_exports);
@@ -73,6 +74,15 @@ var truncateText = (text, maxLength = 20) => {
73
74
  }
74
75
  return text.slice(0, maxLength - 3) + "...";
75
76
  };
77
+ var truncateFileName = (fileName, maxLength = 20) => {
78
+ if (!fileName) return "";
79
+ if (fileName.length <= maxLength) {
80
+ return fileName;
81
+ }
82
+ const extension = fileName.slice(fileName.lastIndexOf("."));
83
+ const truncatedName = fileName.slice(0, maxLength - extension.length - 3) + "...";
84
+ return truncatedName + extension;
85
+ };
76
86
  function getApiError(apiError) {
77
87
  if (!apiError) return "An unknown error occurred";
78
88
  if (typeof apiError === "string") {
@@ -346,6 +356,7 @@ function confirmationAlert(onConfirm, options = {}) {
346
356
  removeByPropertyValues,
347
357
  toDateInputValue,
348
358
  toLowerCaseText,
359
+ truncateFileName,
349
360
  truncateText
350
361
  });
351
362
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
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 confirmationAlert,\r\n type RtkQueryError,\r\n type HandleApiErrorOptions,\r\n type ConfirmationAlertOptions,\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) => {\r\n if (!text) return \"\";\r\n if (text.length <= maxLength) {\r\n return text;\r\n }\r\n return text.slice(0, maxLength - 3) + \"...\";\r\n};\r\n\r\nexport function getApiError(apiError: unknown): string {\r\n if (!apiError) return \"An unknown error occurred\";\r\n\r\n if (typeof apiError === \"string\") {\r\n return apiError;\r\n }\r\n\r\n const error = apiError as {\r\n response?: { data?: Record<string, unknown> };\r\n message?: string;\r\n };\r\n\r\n if (error.response?.data) {\r\n const responseData = error.response.data;\r\n\r\n if (typeof responseData === \"string\") {\r\n return responseData;\r\n }\r\n\r\n const errors = responseData.errors;\r\n if (errors && typeof errors === \"object\") {\r\n for (const key in errors) {\r\n const messages = (errors as Record<string, unknown>)[key];\r\n if (Array.isArray(messages) && messages.length > 0) {\r\n return String(messages[0]);\r\n }\r\n }\r\n }\r\n\r\n if (responseData.message) {\r\n return String(responseData.message);\r\n }\r\n\r\n if (responseData.title) {\r\n return String(responseData.title);\r\n }\r\n }\r\n\r\n if (error.message) {\r\n return error.message;\r\n }\r\n\r\n return \"An unknown error occurred\";\r\n}\r\n\r\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\r\n if (responseData == null) return [];\r\n if (Array.isArray(responseData)) return responseData;\r\n\r\n const record = responseData as Record<string, unknown>;\r\n const data = record.data;\r\n\r\n if (\r\n data &&\r\n typeof data === \"object\" &&\r\n !Array.isArray(data) &&\r\n Array.isArray((data as { items?: unknown[] }).items)\r\n ) {\r\n return (data as { items: unknown[] }).items;\r\n }\r\n\r\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\r\n if (Array.isArray(returnModel?.items)) return returnModel.items;\r\n if (Array.isArray(data)) return data;\r\n if (typeof data === \"object\" && data !== null) {\r\n return [data];\r\n }\r\n return [];\r\n};\r\n\r\nexport function capitalizeText(name: string | null | undefined): string {\r\n if (!name) return \"\";\r\n return name\r\n .split(\" \")\r\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\r\n .join(\" \");\r\n}\r\n\r\nexport function toLowerCaseText(text: string | null | undefined): string {\r\n if (!text) return \"\";\r\n return text.toLowerCase();\r\n}\r\n\r\nexport const formatDate = (dateString: string | null | undefined): string => {\r\n if (dateString === null || dateString === undefined) return \"-\";\r\n const date = new Date(dateString);\r\n\r\n if (isNaN(date.getTime())) {\r\n return dateString;\r\n }\r\n\r\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = date.getDate().toString().padStart(2, \"0\");\r\n const year = date.getFullYear().toString().slice(-2);\r\n return `${month}/${day}/${year}`;\r\n};\r\n\r\nexport const isEmpty = (obj: object): boolean => {\r\n return Object.keys(obj).length === 0;\r\n};\r\n\r\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\r\n if (!date) return \"\";\r\n\r\n let d: Date;\r\n\r\n if (typeof date === \"string\") {\r\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\r\n return date;\r\n }\r\n d = new Date(date);\r\n } else {\r\n d = new Date(date);\r\n }\r\n\r\n if (isNaN(d.getTime())) return \"\";\r\n\r\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\r\n const year = localDate.getFullYear();\r\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = localDate.getDate().toString().padStart(2, \"0\");\r\n\r\n return `${year}-${month}-${day}`;\r\n};\r\n\r\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\r\n if (!data || data.trim() === \"\") {\r\n return [];\r\n }\r\n return data.split(\",\").map((item) => item.trim());\r\n}\r\n\r\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\r\n return array.includes(searchValue);\r\n}\r\n\r\nexport const currencyFormatter = (value: number | null | undefined): string => {\r\n return value?.toLocaleString(\"en-US\", {\r\n style: \"currency\",\r\n currency: \"USD\",\r\n }) ?? \"\";\r\n};\r\nexport const formatNumber = (number: number | string | null | undefined): string => {\r\n if (isNaN(Number(number)) || number === null || number === undefined) {\r\n return \"0\";\r\n }\r\n\r\n const formattedNumber = Number(number)\r\n .toString()\r\n .replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\r\n\r\n return formattedNumber;\r\n};\r\n\r\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\r\n if (value == null || value === \"\") return 0;\r\n\r\n const raw =\r\n typeof value === \"object\" && value !== null && \"value\" in value\r\n ? (value as { value: unknown }).value\r\n : value;\r\n\r\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\r\n const numericValue = stringValue.replace(/[$,]/g, \"\");\r\n return parseFloat(numericValue) || 0;\r\n};\r\n\r\nexport function flattenTableData<T extends Record<string, unknown>>(\r\n data: T[] | null | undefined,\r\n columns: { field?: string }[] | null | undefined\r\n): T[] {\r\n if (!Array.isArray(data)) return [];\r\n return data.map((row) => {\r\n const flatRow = { ...row };\r\n (columns ?? []).forEach((col) => {\r\n const key = col.field;\r\n if (!key) return;\r\n if (key.includes(\".\")) {\r\n const value = key.split(\".\").reduce<unknown>(\r\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\r\n row\r\n );\r\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\r\n }\r\n });\r\n return flatRow;\r\n });\r\n}\r\n\r\nexport const getErrorMessages = (error: {\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n title?: string;\r\n error?: { name?: string[] };\r\n };\r\n} | null | undefined): string => {\r\n if (error?.data?.errors) {\r\n return Object.values(error.data.errors).flat().join(\"\\n\");\r\n }\r\n return (\r\n error?.data?.title ??\r\n error?.data?.error?.name?.[0] ??\r\n \"Failed to save\"\r\n );\r\n};\r\n\r\nexport const getFieldsByCategory = <T extends { category?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields?.filter(({ category = \"\" }) => category === key);\r\n};\r\n\r\nexport const getFieldsByName = <T extends { name?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ name = \"\" }) => name === key);\r\n};\r\n\r\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\r\n try {\r\n return JSON.parse(jsonString) as T;\r\n } catch (error) {\r\n console.error(\"Error parsing JSON:\", error);\r\n return null;\r\n }\r\n};\r\n\r\nexport const formatDateTime = (dateString: string | null | undefined): string => {\r\n if (!dateString) return \"Invalid Date\";\r\n const date = new Date(dateString);\r\n if (isNaN(date.getTime())) return \"Invalid Date\";\r\n const options: Intl.DateTimeFormatOptions = {\r\n year: \"numeric\",\r\n month: \"numeric\",\r\n day: \"numeric\",\r\n hour: \"numeric\",\r\n minute: \"numeric\",\r\n hour12: true,\r\n };\r\n return date.toLocaleString(\"en-US\", options);\r\n};\r\n\r\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\r\n items: T[] = [],\r\n property: keyof T & string,\r\n values: unknown[] = [],\r\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\r\n): T[] => {\r\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\r\n const normalize = (v: unknown) =>\r\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\r\n const valuesArr = Array.isArray(values) ? values : [values];\r\n const toRemove = new Set(valuesArr.map(normalize));\r\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\r\n};\r\n\r\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ inputType = \"\" }) => inputType === key);\r\n};\r\n","import toast from \"react-hot-toast\";\r\nimport Swal from \"sweetalert2\";\r\n\r\nexport type RtkQueryError = {\r\n status?: number | string;\r\n originalStatus?: number;\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n message?: string;\r\n title?: string;\r\n };\r\n error?: string;\r\n};\r\n\r\nexport interface HandleApiErrorOptions {\r\n showAlert?: boolean;\r\n fallbackMessage?: string;\r\n}\r\n\r\nexport function formatValidationErrorsHtml(\r\n errors: Record<string, string[]>\r\n): string {\r\n const items = Object.keys(errors).flatMap((field) =>\r\n (errors[field] || []).map((msg) => `<li>${msg}</li>`)\r\n );\r\n return `\r\n <div style=\"text-align:left\">\r\n <p>Please review and correct the following:</p>\r\n <ul style=\"margin:8px 0 0 16px; list-style:disc;\">\r\n ${items.join(\"\")}\r\n </ul>\r\n </div>\r\n `;\r\n}\r\n\r\nfunction showValidationAlert(html: string): void {\r\n void Swal.fire({\r\n title: \"Validation errors\",\r\n html,\r\n icon: \"error\",\r\n confirmButtonText: \"OK\",\r\n showCancelButton: false,\r\n confirmButtonColor: \"#FF7335\",\r\n });\r\n}\r\n\r\n/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */\r\nexport function handleApiError(\r\n error: RtkQueryError | null | undefined,\r\n { showAlert = false, fallbackMessage }: HandleApiErrorOptions = {}\r\n): void {\r\n if (!error) return;\r\n\r\n const status = error.status ?? error.originalStatus;\r\n const data = error.data;\r\n\r\n if (status === 200) {\r\n return;\r\n }\r\n\r\n if (data?.errors && typeof data.errors === \"object\") {\r\n const errors = data.errors;\r\n\r\n if (showAlert) {\r\n showValidationAlert(formatValidationErrorsHtml(errors));\r\n } else {\r\n Object.keys(errors).forEach((field) => {\r\n (errors[field] || []).forEach((errorMessage) => {\r\n toast.error(errorMessage);\r\n });\r\n });\r\n }\r\n return;\r\n }\r\n\r\n if (status === 404) {\r\n return;\r\n }\r\n\r\n const message =\r\n fallbackMessage ||\r\n data?.message ||\r\n data?.title ||\r\n error.error ||\r\n \"An error occurred. Please try again.\";\r\n\r\n toast.error(message);\r\n}\r\n\r\nexport interface ConfirmationAlertOptions {\r\n title?: string;\r\n text?: string;\r\n icon?: \"warning\" | \"info\" | \"question\" | \"error\" | \"success\";\r\n confirmButtonText?: string;\r\n cancelButtonText?: string;\r\n}\r\n\r\nexport function confirmationAlert(\r\n onConfirm: () => void,\r\n options: ConfirmationAlertOptions = {}\r\n): void {\r\n void Swal.fire({\r\n title: options.title ?? \"Are you sure?\",\r\n text: options.text,\r\n icon: options.icon ?? \"warning\",\r\n showCancelButton: true,\r\n confirmButtonText: options.confirmButtonText ?? \"Yes\",\r\n cancelButtonText: options.cancelButtonText ?? \"Cancel\",\r\n confirmButtonColor: \"#FF7335\",\r\n }).then((result) => {\r\n if (result.isConfirmed) {\r\n onConfirm();\r\n }\r\n });\r\n}\r\n"],"mappings":"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","names":["clsx","Swal","toast"]}
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 confirmationAlert,\r\n type RtkQueryError,\r\n type HandleApiErrorOptions,\r\n type ConfirmationAlertOptions,\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) => {\r\n if (!text) return \"\";\r\n if (text.length <= maxLength) {\r\n return text;\r\n }\r\n return text.slice(0, maxLength - 3) + \"...\";\r\n};\r\n\r\nexport const truncateFileName = (\r\n fileName: string | null | undefined,\r\n maxLength = 20\r\n): string => {\r\n if (!fileName) return \"\";\r\n if (fileName.length <= maxLength) {\r\n return fileName;\r\n }\r\n const extension = fileName.slice(fileName.lastIndexOf(\".\"));\r\n const truncatedName =\r\n fileName.slice(0, maxLength - extension.length - 3) + \"...\";\r\n return truncatedName + extension;\r\n};\r\n\r\nexport function getApiError(apiError: unknown): string {\r\n if (!apiError) return \"An unknown error occurred\";\r\n\r\n if (typeof apiError === \"string\") {\r\n return apiError;\r\n }\r\n\r\n const error = apiError as {\r\n response?: { data?: Record<string, unknown> };\r\n message?: string;\r\n };\r\n\r\n if (error.response?.data) {\r\n const responseData = error.response.data;\r\n\r\n if (typeof responseData === \"string\") {\r\n return responseData;\r\n }\r\n\r\n const errors = responseData.errors;\r\n if (errors && typeof errors === \"object\") {\r\n for (const key in errors) {\r\n const messages = (errors as Record<string, unknown>)[key];\r\n if (Array.isArray(messages) && messages.length > 0) {\r\n return String(messages[0]);\r\n }\r\n }\r\n }\r\n\r\n if (responseData.message) {\r\n return String(responseData.message);\r\n }\r\n\r\n if (responseData.title) {\r\n return String(responseData.title);\r\n }\r\n }\r\n\r\n if (error.message) {\r\n return error.message;\r\n }\r\n\r\n return \"An unknown error occurred\";\r\n}\r\n\r\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\r\n if (responseData == null) return [];\r\n if (Array.isArray(responseData)) return responseData;\r\n\r\n const record = responseData as Record<string, unknown>;\r\n const data = record.data;\r\n\r\n if (\r\n data &&\r\n typeof data === \"object\" &&\r\n !Array.isArray(data) &&\r\n Array.isArray((data as { items?: unknown[] }).items)\r\n ) {\r\n return (data as { items: unknown[] }).items;\r\n }\r\n\r\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\r\n if (Array.isArray(returnModel?.items)) return returnModel.items;\r\n if (Array.isArray(data)) return data;\r\n if (typeof data === \"object\" && data !== null) {\r\n return [data];\r\n }\r\n return [];\r\n};\r\n\r\nexport function capitalizeText(name: string | null | undefined): string {\r\n if (!name) return \"\";\r\n return name\r\n .split(\" \")\r\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\r\n .join(\" \");\r\n}\r\n\r\nexport function toLowerCaseText(text: string | null | undefined): string {\r\n if (!text) return \"\";\r\n return text.toLowerCase();\r\n}\r\n\r\nexport const formatDate = (dateString: string | null | undefined): string => {\r\n if (dateString === null || dateString === undefined) return \"-\";\r\n const date = new Date(dateString);\r\n\r\n if (isNaN(date.getTime())) {\r\n return dateString;\r\n }\r\n\r\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = date.getDate().toString().padStart(2, \"0\");\r\n const year = date.getFullYear().toString().slice(-2);\r\n return `${month}/${day}/${year}`;\r\n};\r\n\r\nexport const isEmpty = (obj: object): boolean => {\r\n return Object.keys(obj).length === 0;\r\n};\r\n\r\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\r\n if (!date) return \"\";\r\n\r\n let d: Date;\r\n\r\n if (typeof date === \"string\") {\r\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\r\n return date;\r\n }\r\n d = new Date(date);\r\n } else {\r\n d = new Date(date);\r\n }\r\n\r\n if (isNaN(d.getTime())) return \"\";\r\n\r\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\r\n const year = localDate.getFullYear();\r\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = localDate.getDate().toString().padStart(2, \"0\");\r\n\r\n return `${year}-${month}-${day}`;\r\n};\r\n\r\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\r\n if (!data || data.trim() === \"\") {\r\n return [];\r\n }\r\n return data.split(\",\").map((item) => item.trim());\r\n}\r\n\r\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\r\n return array.includes(searchValue);\r\n}\r\n\r\nexport const currencyFormatter = (value: number | null | undefined): string => {\r\n return value?.toLocaleString(\"en-US\", {\r\n style: \"currency\",\r\n currency: \"USD\",\r\n }) ?? \"\";\r\n};\r\nexport const formatNumber = (number: number | string | null | undefined): string => {\r\n if (isNaN(Number(number)) || number === null || number === undefined) {\r\n return \"0\";\r\n }\r\n\r\n const formattedNumber = Number(number)\r\n .toString()\r\n .replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\r\n\r\n return formattedNumber;\r\n};\r\n\r\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\r\n if (value == null || value === \"\") return 0;\r\n\r\n const raw =\r\n typeof value === \"object\" && value !== null && \"value\" in value\r\n ? (value as { value: unknown }).value\r\n : value;\r\n\r\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\r\n const numericValue = stringValue.replace(/[$,]/g, \"\");\r\n return parseFloat(numericValue) || 0;\r\n};\r\n\r\nexport function flattenTableData<T extends Record<string, unknown>>(\r\n data: T[] | null | undefined,\r\n columns: { field?: string }[] | null | undefined\r\n): T[] {\r\n if (!Array.isArray(data)) return [];\r\n return data.map((row) => {\r\n const flatRow = { ...row };\r\n (columns ?? []).forEach((col) => {\r\n const key = col.field;\r\n if (!key) return;\r\n if (key.includes(\".\")) {\r\n const value = key.split(\".\").reduce<unknown>(\r\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\r\n row\r\n );\r\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\r\n }\r\n });\r\n return flatRow;\r\n });\r\n}\r\n\r\nexport const getErrorMessages = (error: {\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n title?: string;\r\n error?: { name?: string[] };\r\n };\r\n} | null | undefined): string => {\r\n if (error?.data?.errors) {\r\n return Object.values(error.data.errors).flat().join(\"\\n\");\r\n }\r\n return (\r\n error?.data?.title ??\r\n error?.data?.error?.name?.[0] ??\r\n \"Failed to save\"\r\n );\r\n};\r\n\r\nexport const getFieldsByCategory = <T extends { category?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields?.filter(({ category = \"\" }) => category === key);\r\n};\r\n\r\nexport const getFieldsByName = <T extends { name?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ name = \"\" }) => name === key);\r\n};\r\n\r\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\r\n try {\r\n return JSON.parse(jsonString) as T;\r\n } catch (error) {\r\n console.error(\"Error parsing JSON:\", error);\r\n return null;\r\n }\r\n};\r\n\r\nexport const formatDateTime = (dateString: string | null | undefined): string => {\r\n if (!dateString) return \"Invalid Date\";\r\n const date = new Date(dateString);\r\n if (isNaN(date.getTime())) return \"Invalid Date\";\r\n const options: Intl.DateTimeFormatOptions = {\r\n year: \"numeric\",\r\n month: \"numeric\",\r\n day: \"numeric\",\r\n hour: \"numeric\",\r\n minute: \"numeric\",\r\n hour12: true,\r\n };\r\n return date.toLocaleString(\"en-US\", options);\r\n};\r\n\r\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\r\n items: T[] = [],\r\n property: keyof T & string,\r\n values: unknown[] = [],\r\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\r\n): T[] => {\r\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\r\n const normalize = (v: unknown) =>\r\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\r\n const valuesArr = Array.isArray(values) ? values : [values];\r\n const toRemove = new Set(valuesArr.map(normalize));\r\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\r\n};\r\n\r\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ inputType = \"\" }) => inputType === key);\r\n};\r\n","import toast from \"react-hot-toast\";\r\nimport Swal from \"sweetalert2\";\r\n\r\nexport type RtkQueryError = {\r\n status?: number | string;\r\n originalStatus?: number;\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n message?: string;\r\n title?: string;\r\n };\r\n error?: string;\r\n};\r\n\r\nexport interface HandleApiErrorOptions {\r\n showAlert?: boolean;\r\n fallbackMessage?: string;\r\n}\r\n\r\nexport function formatValidationErrorsHtml(\r\n errors: Record<string, string[]>\r\n): string {\r\n const items = Object.keys(errors).flatMap((field) =>\r\n (errors[field] || []).map((msg) => `<li>${msg}</li>`)\r\n );\r\n return `\r\n <div style=\"text-align:left\">\r\n <p>Please review and correct the following:</p>\r\n <ul style=\"margin:8px 0 0 16px; list-style:disc;\">\r\n ${items.join(\"\")}\r\n </ul>\r\n </div>\r\n `;\r\n}\r\n\r\nfunction showValidationAlert(html: string): void {\r\n void Swal.fire({\r\n title: \"Validation errors\",\r\n html,\r\n icon: \"error\",\r\n confirmButtonText: \"OK\",\r\n showCancelButton: false,\r\n confirmButtonColor: \"#FF7335\",\r\n });\r\n}\r\n\r\n/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */\r\nexport function handleApiError(\r\n error: RtkQueryError | null | undefined,\r\n { showAlert = false, fallbackMessage }: HandleApiErrorOptions = {}\r\n): void {\r\n if (!error) return;\r\n\r\n const status = error.status ?? error.originalStatus;\r\n const data = error.data;\r\n\r\n if (status === 200) {\r\n return;\r\n }\r\n\r\n if (data?.errors && typeof data.errors === \"object\") {\r\n const errors = data.errors;\r\n\r\n if (showAlert) {\r\n showValidationAlert(formatValidationErrorsHtml(errors));\r\n } else {\r\n Object.keys(errors).forEach((field) => {\r\n (errors[field] || []).forEach((errorMessage) => {\r\n toast.error(errorMessage);\r\n });\r\n });\r\n }\r\n return;\r\n }\r\n\r\n if (status === 404) {\r\n return;\r\n }\r\n\r\n const message =\r\n fallbackMessage ||\r\n data?.message ||\r\n data?.title ||\r\n error.error ||\r\n \"An error occurred. Please try again.\";\r\n\r\n toast.error(message);\r\n}\r\n\r\nexport interface ConfirmationAlertOptions {\r\n title?: string;\r\n text?: string;\r\n icon?: \"warning\" | \"info\" | \"question\" | \"error\" | \"success\";\r\n confirmButtonText?: string;\r\n cancelButtonText?: string;\r\n}\r\n\r\nexport function confirmationAlert(\r\n onConfirm: () => void,\r\n options: ConfirmationAlertOptions = {}\r\n): void {\r\n void Swal.fire({\r\n title: options.title ?? \"Are you sure?\",\r\n text: options.text,\r\n icon: options.icon ?? \"warning\",\r\n showCancelButton: true,\r\n confirmButtonText: options.confirmButtonText ?? \"Yes\",\r\n cancelButtonText: options.cancelButtonText ?? \"Cancel\",\r\n confirmButtonColor: \"#FF7335\",\r\n }).then((result) => {\r\n if (result.isConfirmed) {\r\n onConfirm();\r\n }\r\n });\r\n}\r\n"],"mappings":"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","names":["clsx","Swal","toast"]}
@@ -19,8 +19,9 @@ import {
19
19
  removeByPropertyValues,
20
20
  toDateInputValue,
21
21
  toLowerCaseText,
22
+ truncateFileName,
22
23
  truncateText
23
- } from "../chunk-M7SOJOJI.mjs";
24
+ } from "../chunk-HZGVVROQ.mjs";
24
25
  import {
25
26
  cn,
26
27
  confirmationAlert,
@@ -52,6 +53,7 @@ export {
52
53
  removeByPropertyValues,
53
54
  toDateInputValue,
54
55
  toLowerCaseText,
56
+ truncateFileName,
55
57
  truncateText
56
58
  };
57
59
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eztrak/shared",
3
- "version": "0.4.8",
3
+ "version": "0.4.9",
4
4
  "homepage": "https://github.com/mehrancentangle/eztrak-packages",
5
5
  "description": "Shared hooks, utils, and UI for Eztrak federation apps",
6
6
  "main": "./dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/helpers.ts"],"sourcesContent":["export const truncateText = (text: string | null | undefined, maxLength = 20) => {\r\n if (!text) return \"\";\r\n if (text.length <= maxLength) {\r\n return text;\r\n }\r\n return text.slice(0, maxLength - 3) + \"...\";\r\n};\r\n\r\nexport function getApiError(apiError: unknown): string {\r\n if (!apiError) return \"An unknown error occurred\";\r\n\r\n if (typeof apiError === \"string\") {\r\n return apiError;\r\n }\r\n\r\n const error = apiError as {\r\n response?: { data?: Record<string, unknown> };\r\n message?: string;\r\n };\r\n\r\n if (error.response?.data) {\r\n const responseData = error.response.data;\r\n\r\n if (typeof responseData === \"string\") {\r\n return responseData;\r\n }\r\n\r\n const errors = responseData.errors;\r\n if (errors && typeof errors === \"object\") {\r\n for (const key in errors) {\r\n const messages = (errors as Record<string, unknown>)[key];\r\n if (Array.isArray(messages) && messages.length > 0) {\r\n return String(messages[0]);\r\n }\r\n }\r\n }\r\n\r\n if (responseData.message) {\r\n return String(responseData.message);\r\n }\r\n\r\n if (responseData.title) {\r\n return String(responseData.title);\r\n }\r\n }\r\n\r\n if (error.message) {\r\n return error.message;\r\n }\r\n\r\n return \"An unknown error occurred\";\r\n}\r\n\r\nexport const normalizeApiListItems = (responseData: unknown): unknown[] => {\r\n if (responseData == null) return [];\r\n if (Array.isArray(responseData)) return responseData;\r\n\r\n const record = responseData as Record<string, unknown>;\r\n const data = record.data;\r\n\r\n if (\r\n data &&\r\n typeof data === \"object\" &&\r\n !Array.isArray(data) &&\r\n Array.isArray((data as { items?: unknown[] }).items)\r\n ) {\r\n return (data as { items: unknown[] }).items;\r\n }\r\n\r\n const returnModel = record.returnModel as { items?: unknown[] } | undefined;\r\n if (Array.isArray(returnModel?.items)) return returnModel.items;\r\n if (Array.isArray(data)) return data;\r\n if (typeof data === \"object\" && data !== null) {\r\n return [data];\r\n }\r\n return [];\r\n};\r\n\r\nexport function capitalizeText(name: string | null | undefined): string {\r\n if (!name) return \"\";\r\n return name\r\n .split(\" \")\r\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\r\n .join(\" \");\r\n}\r\n\r\nexport function toLowerCaseText(text: string | null | undefined): string {\r\n if (!text) return \"\";\r\n return text.toLowerCase();\r\n}\r\n\r\nexport const formatDate = (dateString: string | null | undefined): string => {\r\n if (dateString === null || dateString === undefined) return \"-\";\r\n const date = new Date(dateString);\r\n\r\n if (isNaN(date.getTime())) {\r\n return dateString;\r\n }\r\n\r\n const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = date.getDate().toString().padStart(2, \"0\");\r\n const year = date.getFullYear().toString().slice(-2);\r\n return `${month}/${day}/${year}`;\r\n};\r\n\r\nexport const isEmpty = (obj: object): boolean => {\r\n return Object.keys(obj).length === 0;\r\n};\r\n\r\nexport const toDateInputValue = (date: string | Date | null | undefined): string => {\r\n if (!date) return \"\";\r\n\r\n let d: Date;\r\n\r\n if (typeof date === \"string\") {\r\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\r\n return date;\r\n }\r\n d = new Date(date);\r\n } else {\r\n d = new Date(date);\r\n }\r\n\r\n if (isNaN(d.getTime())) return \"\";\r\n\r\n const localDate = new Date(d.getTime() - d.getTimezoneOffset() * 60000);\r\n const year = localDate.getFullYear();\r\n const month = (localDate.getMonth() + 1).toString().padStart(2, \"0\");\r\n const day = localDate.getDate().toString().padStart(2, \"0\");\r\n\r\n return `${year}-${month}-${day}`;\r\n};\r\n\r\nexport function convertCommaDataToArray(data: string | null | undefined): string[] {\r\n if (!data || data.trim() === \"\") {\r\n return [];\r\n }\r\n return data.split(\",\").map((item) => item.trim());\r\n}\r\n\r\nexport function checkIfExistsInArray<T>(array: T[], searchValue: T): boolean {\r\n return array.includes(searchValue);\r\n}\r\n\r\nexport const currencyFormatter = (value: number | null | undefined): string => {\r\n return value?.toLocaleString(\"en-US\", {\r\n style: \"currency\",\r\n currency: \"USD\",\r\n }) ?? \"\";\r\n};\r\nexport const formatNumber = (number: number | string | null | undefined): string => {\r\n if (isNaN(Number(number)) || number === null || number === undefined) {\r\n return \"0\";\r\n }\r\n\r\n const formattedNumber = Number(number)\r\n .toString()\r\n .replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\r\n\r\n return formattedNumber;\r\n};\r\n\r\nexport const parseCurrencyValueToNumber = (value: unknown): number => {\r\n if (value == null || value === \"\") return 0;\r\n\r\n const raw =\r\n typeof value === \"object\" && value !== null && \"value\" in value\r\n ? (value as { value: unknown }).value\r\n : value;\r\n\r\n const stringValue = raw == null || raw === \"\" ? \"\" : String(raw);\r\n const numericValue = stringValue.replace(/[$,]/g, \"\");\r\n return parseFloat(numericValue) || 0;\r\n};\r\n\r\nexport function flattenTableData<T extends Record<string, unknown>>(\r\n data: T[] | null | undefined,\r\n columns: { field?: string }[] | null | undefined\r\n): T[] {\r\n if (!Array.isArray(data)) return [];\r\n return data.map((row) => {\r\n const flatRow = { ...row };\r\n (columns ?? []).forEach((col) => {\r\n const key = col.field;\r\n if (!key) return;\r\n if (key.includes(\".\")) {\r\n const value = key.split(\".\").reduce<unknown>(\r\n (acc, part) => (acc as Record<string, unknown> | undefined)?.[part],\r\n row\r\n );\r\n (flatRow as Record<string, unknown>)[key] = value ?? \"\";\r\n }\r\n });\r\n return flatRow;\r\n });\r\n}\r\n\r\nexport const getErrorMessages = (error: {\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n title?: string;\r\n error?: { name?: string[] };\r\n };\r\n} | null | undefined): string => {\r\n if (error?.data?.errors) {\r\n return Object.values(error.data.errors).flat().join(\"\\n\");\r\n }\r\n return (\r\n error?.data?.title ??\r\n error?.data?.error?.name?.[0] ??\r\n \"Failed to save\"\r\n );\r\n};\r\n\r\nexport const getFieldsByCategory = <T extends { category?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields?.filter(({ category = \"\" }) => category === key);\r\n};\r\n\r\nexport const getFieldsByName = <T extends { name?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ name = \"\" }) => name === key);\r\n};\r\n\r\nexport const deserializeJson = <T = unknown>(jsonString: string): T | null => {\r\n try {\r\n return JSON.parse(jsonString) as T;\r\n } catch (error) {\r\n console.error(\"Error parsing JSON:\", error);\r\n return null;\r\n }\r\n};\r\n\r\nexport const formatDateTime = (dateString: string | null | undefined): string => {\r\n if (!dateString) return \"Invalid Date\";\r\n const date = new Date(dateString);\r\n if (isNaN(date.getTime())) return \"Invalid Date\";\r\n const options: Intl.DateTimeFormatOptions = {\r\n year: \"numeric\",\r\n month: \"numeric\",\r\n day: \"numeric\",\r\n hour: \"numeric\",\r\n minute: \"numeric\",\r\n hour12: true,\r\n };\r\n return date.toLocaleString(\"en-US\", options);\r\n};\r\n\r\nexport const removeByPropertyValues = <T extends Record<string, unknown>>(\r\n items: T[] = [],\r\n property: keyof T & string,\r\n values: unknown[] = [],\r\n { caseInsensitive = false }: { caseInsensitive?: boolean } = {}\r\n): T[] => {\r\n if (!Array.isArray(items) || !property) return Array.isArray(items) ? items : [];\r\n const normalize = (v: unknown) =>\r\n caseInsensitive && typeof v === \"string\" ? v.toLowerCase() : v;\r\n const valuesArr = Array.isArray(values) ? values : [values];\r\n const toRemove = new Set(valuesArr.map(normalize));\r\n return items.filter((item) => !toRemove.has(normalize(item?.[property])));\r\n};\r\n\r\nexport const getFieldsByInputType = <T extends { inputType?: string }>(\r\n fields: T[] = [],\r\n key: string\r\n): T[] => {\r\n return fields.filter(({ inputType = \"\" }) => inputType === key);\r\n};\r\n"],"mappings":"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","names":[]}