@pagamio/frontend-commons-lib 0.8.209 → 0.8.210
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/lib/api/client.js +2 -1
- package/lib/dashboard-visuals/hooks/useChartData.js +4 -1
- package/lib/dashboard-visuals/index.d.ts +3 -0
- package/lib/dashboard-visuals/index.js +13 -5
- package/lib/dashboard-visuals/utils/api.d.ts +6 -0
- package/lib/dashboard-visuals/utils/api.js +6 -0
- package/lib/dashboard-visuals/visuals/Tile.js +17 -3
- package/package.json +1 -1
package/lib/api/client.js
CHANGED
|
@@ -322,7 +322,8 @@ export class ApiClient {
|
|
|
322
322
|
data = response;
|
|
323
323
|
}
|
|
324
324
|
if (this.config.onResponse) {
|
|
325
|
-
|
|
325
|
+
const transformedData = await this.config.onResponse(response, data);
|
|
326
|
+
data = transformedData;
|
|
326
327
|
}
|
|
327
328
|
return data;
|
|
328
329
|
}
|
|
@@ -48,6 +48,9 @@ export const useChartData = (url, query, transform) => {
|
|
|
48
48
|
lastDataRef.current = data;
|
|
49
49
|
lastFetchTimeRef.current = Date.now();
|
|
50
50
|
},
|
|
51
|
+
onError: (error) => {
|
|
52
|
+
console.error('[useChartData] Error fetching data', { url, query, error });
|
|
53
|
+
},
|
|
51
54
|
});
|
|
52
55
|
// Effect to update last fetch time when data changes
|
|
53
56
|
useEffect(() => {
|
|
@@ -55,7 +58,7 @@ export const useChartData = (url, query, transform) => {
|
|
|
55
58
|
lastDataRef.current = data;
|
|
56
59
|
lastFetchTimeRef.current = Date.now();
|
|
57
60
|
}
|
|
58
|
-
}, [data]);
|
|
61
|
+
}, [data, url]);
|
|
59
62
|
const transformedData = transform ? transform(data) : data;
|
|
60
63
|
const isEmpty = !error && !loading && Array.isArray(transformedData) ? !transformedData.length : transformedData === undefined;
|
|
61
64
|
// Enhanced refresh function that uses intelligent caching without custom headers
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { FilterConfig } from './components/types';
|
|
3
|
+
import { type DashboardApiPaths } from './utils';
|
|
3
4
|
type FilterValue = string | string[] | Date | null | undefined;
|
|
4
5
|
interface Config {
|
|
5
6
|
title: string;
|
|
@@ -33,6 +34,8 @@ interface DashboardWrapperProps {
|
|
|
33
34
|
resetFilters?: () => void;
|
|
34
35
|
handleApplyFilters?: () => void;
|
|
35
36
|
handleApplyTourFilters?: () => void;
|
|
37
|
+
/** Custom API paths for different domains*/
|
|
38
|
+
apiPaths?: DashboardApiPaths;
|
|
36
39
|
}
|
|
37
40
|
declare const DashboardWrapper: React.FC<DashboardWrapperProps>;
|
|
38
41
|
export default DashboardWrapper;
|
|
@@ -7,7 +7,7 @@ import { FilterComponent, Tab } from '../components';
|
|
|
7
7
|
import { useMediaQueries } from '../shared';
|
|
8
8
|
import ErrorState from './components/ErrorState';
|
|
9
9
|
import FilterComponentSkeleton from './components/FilterComponentSkeleton';
|
|
10
|
-
import {
|
|
10
|
+
import { defaultDashboardApiPaths, getFilterOptionsData, getGridColProps } from './utils';
|
|
11
11
|
import componentRegistry from './visualRegistry';
|
|
12
12
|
const OverviewContent = ({ visualData, renderContent, renderVisual }) => {
|
|
13
13
|
return (_jsxs(_Fragment, { children: [renderContent(), _jsx("main", { children: visualData.map((section) => (_jsxs("div", { className: "mb-2", children: [section.sectionTitle && _jsx("h2", { className: "mb-2 text-1xl font-semibold", children: section.sectionTitle }), _jsx(Grid, { gutter: "md", align: "stretch", className: "mb-[6px]", children: section.data.map((visual) => {
|
|
@@ -51,7 +51,7 @@ const renderFilterComponent = ({ isLoading, error, filters, filterOptions, selec
|
|
|
51
51
|
rangeKeys: filter.rangeKeys,
|
|
52
52
|
})), showClearFilters: true, selectedFilters: selectedFilters, handleFilterChange: handleFilterChange, handleApplyFilters: handleApplyFilters, resetFilters: resetFilters, isNarrow: isNarrow }));
|
|
53
53
|
};
|
|
54
|
-
const DashboardWrapper = ({ data, showVisualHeader = true, showEventsTabbedLayout = false, handleFilterChange = () => { }, selectedFilters = {}, tourSelectedFilters = {}, resetFilters = () => { }, handleApplyFilters = () => { }, handleApplyTourFilters = () => { }, handleTourFilterChange = () => { }, }) => {
|
|
54
|
+
const DashboardWrapper = ({ data, showVisualHeader = true, showEventsTabbedLayout = false, handleFilterChange = () => { }, selectedFilters = {}, tourSelectedFilters = {}, resetFilters = () => { }, handleApplyFilters = () => { }, handleApplyTourFilters = () => { }, handleTourFilterChange = () => { }, apiPaths = defaultDashboardApiPaths, }) => {
|
|
55
55
|
const [loading, setLoading] = useState(true);
|
|
56
56
|
const [error, setError] = useState(null);
|
|
57
57
|
const [tourError, setTourError] = useState(null);
|
|
@@ -99,7 +99,9 @@ const DashboardWrapper = ({ data, showVisualHeader = true, showEventsTabbedLayou
|
|
|
99
99
|
const fetchFilters = (filters, isTour = false) => {
|
|
100
100
|
filters.forEach((filter) => {
|
|
101
101
|
if (filter.query) {
|
|
102
|
-
|
|
102
|
+
// Use custom apiPaths.query if filter doesn't have its own url
|
|
103
|
+
const defaultQueryUrl = apiPaths.query;
|
|
104
|
+
const queryUrl = isTour ? (filter.tourUrl ?? defaultQueryUrl) : (filter.url ?? defaultQueryUrl);
|
|
103
105
|
fetchFilterData(filter.name, filter.valueKey, queryUrl, filter.query, isTour);
|
|
104
106
|
}
|
|
105
107
|
});
|
|
@@ -108,7 +110,7 @@ const DashboardWrapper = ({ data, showVisualHeader = true, showEventsTabbedLayou
|
|
|
108
110
|
if (config.tourFilters) {
|
|
109
111
|
fetchFilters(config.tourFilters, true);
|
|
110
112
|
}
|
|
111
|
-
}, [config.filters, isRefreshOpttonsQuery]);
|
|
113
|
+
}, [config.filters, isRefreshOpttonsQuery, apiPaths]);
|
|
112
114
|
const handleRetry = () => {
|
|
113
115
|
setIsRefreshOpttonsQuery((prev) => prev + 1);
|
|
114
116
|
};
|
|
@@ -167,6 +169,11 @@ const DashboardWrapper = ({ data, showVisualHeader = true, showEventsTabbedLayou
|
|
|
167
169
|
console.error(`Visual type "${metricData.type}" not recognized in section "${sectionTitle}" at visual index ${index}.`);
|
|
168
170
|
return null;
|
|
169
171
|
}
|
|
172
|
+
// Determine URL based on component type and custom apiPaths
|
|
173
|
+
// If metricData already has a custom url, use it; otherwise use apiPaths
|
|
174
|
+
const isTileType = metricData.type === 'Tile' || metricData.type === 'MetricSummaryCard';
|
|
175
|
+
const defaultUrl = isTileType ? apiPaths.metrics : apiPaths.query;
|
|
176
|
+
const url = metricData.url || defaultUrl;
|
|
170
177
|
const props = {
|
|
171
178
|
data: metricData.data,
|
|
172
179
|
options: metricData.options,
|
|
@@ -179,9 +186,10 @@ const DashboardWrapper = ({ data, showVisualHeader = true, showEventsTabbedLayou
|
|
|
179
186
|
themeColor: config.themeColor,
|
|
180
187
|
currencyDisplaySymbol: metricData.currencyDisplaySymbol,
|
|
181
188
|
...metricData,
|
|
189
|
+
url, // Override url with apiPaths or metricData.url
|
|
182
190
|
};
|
|
183
191
|
return (_jsx(Grid.Col, { span: matchesSmall ? 12 : span, offset: offset, children: _jsx(VisualComponent, { ...props }) }, `visual-${sectionTitle}-${visual.id}`));
|
|
184
|
-
}, [config.themeColor, isXs, isSm]);
|
|
192
|
+
}, [config.themeColor, isXs, isSm, apiPaths]);
|
|
185
193
|
const tabs = [
|
|
186
194
|
{
|
|
187
195
|
id: 1,
|
|
@@ -3,3 +3,9 @@ export declare enum DashboardPaths {
|
|
|
3
3
|
QUERY = "/dashboard/query",
|
|
4
4
|
METRICS = "/dashboard/metrics"
|
|
5
5
|
}
|
|
6
|
+
export interface DashboardApiPaths {
|
|
7
|
+
query: string;
|
|
8
|
+
metrics: string;
|
|
9
|
+
paged?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const defaultDashboardApiPaths: DashboardApiPaths;
|
|
@@ -4,3 +4,9 @@ export var DashboardPaths;
|
|
|
4
4
|
DashboardPaths["QUERY"] = "/dashboard/query";
|
|
5
5
|
DashboardPaths["METRICS"] = "/dashboard/metrics";
|
|
6
6
|
})(DashboardPaths || (DashboardPaths = {}));
|
|
7
|
+
// Default paths matching the enum
|
|
8
|
+
export const defaultDashboardApiPaths = {
|
|
9
|
+
query: DashboardPaths.QUERY,
|
|
10
|
+
metrics: DashboardPaths.METRICS,
|
|
11
|
+
paged: DashboardPaths.PAGED,
|
|
12
|
+
};
|
|
@@ -6,9 +6,23 @@ import { useChartData } from '../hooks/useChartData';
|
|
|
6
6
|
import { DashboardPaths, formatValue } from '../utils';
|
|
7
7
|
const Tile = ({ query, title, format, url = DashboardPaths.METRICS, details, valueKey, previousValueKey, changeKey, currency: propCurrency, currencyDisplaySymbol, ...props }) => {
|
|
8
8
|
const { data, error, loading, isEmpty, refresh } = useChartData(url, query);
|
|
9
|
-
// Safe default values
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
// Safe default values - handle both flat and nested data structures
|
|
10
|
+
let value = 0;
|
|
11
|
+
if (data) {
|
|
12
|
+
// Check if data is an array (events analytics format)
|
|
13
|
+
if (Array.isArray(data)) {
|
|
14
|
+
// Aggregate values across all items
|
|
15
|
+
value = data.reduce((sum, item) => {
|
|
16
|
+
const itemValue = Number(item[valueKey]) || 0;
|
|
17
|
+
return sum + itemValue;
|
|
18
|
+
}, 0);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
// Direct access for flat structure
|
|
22
|
+
value = data[valueKey] ?? 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const currency = propCurrency || (!Array.isArray(data) ? data?.additionalData?.currency : undefined) || undefined;
|
|
12
26
|
return (_jsx(Card, { title: title, children: _jsx(ChartWrapper, { loading: loading && !data, error: error, isEmpty: isEmpty, onRetry: refresh, children: _jsx("div", { className: "flex justify-between", style: { height: '50px' }, children: _jsx("div", { className: "text-xl font-400", children: currency
|
|
13
27
|
? formatPrice(Number(value.toFixed(2)), currency, 2, undefined, currencyDisplaySymbol)
|
|
14
28
|
: formatValue(Number(value.toFixed(2)), 'number') }) }) }) }));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagamio/frontend-commons-lib",
|
|
3
3
|
"description": "Pagamio library for Frontend reusable components like the form engine and table container",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.210",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
7
7
|
"provenance": false
|