@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 CHANGED
@@ -322,7 +322,8 @@ export class ApiClient {
322
322
  data = response;
323
323
  }
324
324
  if (this.config.onResponse) {
325
- data = await this.config.onResponse(response, data);
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 { DashboardPaths, getFilterOptionsData, getGridColProps } from './utils';
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
- const queryUrl = isTour ? (filter.tourUrl ?? DashboardPaths.QUERY) : (filter.url ?? DashboardPaths.QUERY);
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
- const value = data?.[valueKey] ?? 0;
11
- const currency = propCurrency || data?.additionalData?.currency || undefined;
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.209",
4
+ "version": "0.8.210",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "provenance": false