@bonnard/react 0.1.1 → 0.2.1
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
|
@@ -34,9 +34,8 @@ function RevenueByCategory() {
|
|
|
34
34
|
return (
|
|
35
35
|
<BarChart
|
|
36
36
|
title="Revenue by Category"
|
|
37
|
-
measures={['revenue']}
|
|
38
|
-
dimensions={['product_category']}
|
|
39
|
-
cube="orders"
|
|
37
|
+
measures={['orders.revenue']}
|
|
38
|
+
dimensions={['orders.product_category']}
|
|
40
39
|
/>
|
|
41
40
|
);
|
|
42
41
|
}
|
|
@@ -50,9 +49,8 @@ import { useBonnardQuery } from '@bonnard/react';
|
|
|
50
49
|
function OrderStats() {
|
|
51
50
|
const { data, loading, error } = useBonnardQuery({
|
|
52
51
|
query: {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
dimensions: ['status'],
|
|
52
|
+
measures: ['orders.revenue', 'orders.count'],
|
|
53
|
+
dimensions: ['orders.status'],
|
|
56
54
|
},
|
|
57
55
|
});
|
|
58
56
|
|
|
@@ -62,7 +60,7 @@ function OrderStats() {
|
|
|
62
60
|
return (
|
|
63
61
|
<ul>
|
|
64
62
|
{data?.map((row, i) => (
|
|
65
|
-
<li key={i}>{row.status}: ${row.revenue}</li>
|
|
63
|
+
<li key={i}>{row['orders.status']}: ${row['orders.revenue']}</li>
|
|
66
64
|
))}
|
|
67
65
|
</ul>
|
|
68
66
|
);
|
package/dist/dashboard.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as BarChart, i as LineChart, n as PieChart, o as BigValue, r as AreaChart, t as DataTable, u as useBonnard } from "./data-table-
|
|
1
|
+
import { a as BarChart, i as LineChart, n as PieChart, o as BigValue, r as AreaChart, t as DataTable, u as useBonnard } from "./data-table-C3K4rPh2.js";
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
import DOMPurify from "isomorphic-dompurify";
|
|
4
4
|
import matter from "gray-matter";
|
|
@@ -99,8 +99,8 @@ function parseDashboard(markdown) {
|
|
|
99
99
|
}
|
|
100
100
|
try {
|
|
101
101
|
const options = yaml.parse(node.value);
|
|
102
|
-
if (!options || !options.
|
|
103
|
-
errors.push(`Query "${name}" must specify
|
|
102
|
+
if (!options || !options.measures && !options.dimensions) {
|
|
103
|
+
errors.push(`Query "${name}" must specify measures or dimensions`);
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
106
|
queries.set(name, options);
|
|
@@ -360,6 +360,29 @@ function applyDateRange(queryName, options, props, state) {
|
|
|
360
360
|
};
|
|
361
361
|
return options;
|
|
362
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Extract the short field name from a potentially qualified name.
|
|
365
|
+
* "sales_invoices.status" → "status", "status" → "status"
|
|
366
|
+
*/
|
|
367
|
+
function shortFieldName(name) {
|
|
368
|
+
const dot = name.indexOf(".");
|
|
369
|
+
return dot >= 0 ? name.slice(dot + 1) : name;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Resolve a filter dimension for a target query.
|
|
373
|
+
*
|
|
374
|
+
* The Dropdown `dimension` prop is qualified with the data query's view
|
|
375
|
+
* (e.g. "sales_opportunities.assignee"). When the filter targets a query
|
|
376
|
+
* from a different view, we re-qualify the dimension with that view's prefix.
|
|
377
|
+
*/
|
|
378
|
+
function resolveFilterDimension(dimension, targetQuery) {
|
|
379
|
+
const field = shortFieldName(dimension);
|
|
380
|
+
const allFields = [...targetQuery.measures || [], ...targetQuery.dimensions || []];
|
|
381
|
+
if (allFields.length === 0) return dimension;
|
|
382
|
+
const firstDot = allFields[0].indexOf(".");
|
|
383
|
+
if (firstDot < 0) return dimension;
|
|
384
|
+
return `${allFields[0].slice(0, firstDot)}.${field}`;
|
|
385
|
+
}
|
|
363
386
|
function applyDropdown(queryName, options, props, state) {
|
|
364
387
|
const dimension = props.dimension;
|
|
365
388
|
if (!dimension) return options;
|
|
@@ -368,21 +391,23 @@ function applyDropdown(queryName, options, props, state) {
|
|
|
368
391
|
const dataQuery = props.data;
|
|
369
392
|
if (dataQuery && dataQuery === queryName) return options;
|
|
370
393
|
if (!targets.includes(queryName)) return options;
|
|
394
|
+
const resolved = resolveFilterDimension(dimension, options);
|
|
395
|
+
const field = shortFieldName(dimension);
|
|
371
396
|
if (state === null || state === "") {
|
|
372
397
|
if (options.filters) {
|
|
373
|
-
options.filters = options.filters.filter((f) => f.dimension !==
|
|
398
|
+
options.filters = options.filters.filter((f) => shortFieldName(f.dimension) !== field);
|
|
374
399
|
if (options.filters.length === 0) delete options.filters;
|
|
375
400
|
}
|
|
376
401
|
return options;
|
|
377
402
|
}
|
|
378
403
|
const newFilter = {
|
|
379
|
-
dimension,
|
|
404
|
+
dimension: resolved,
|
|
380
405
|
operator: "equals",
|
|
381
406
|
values: [state]
|
|
382
407
|
};
|
|
383
408
|
if (!options.filters) options.filters = [newFilter];
|
|
384
409
|
else {
|
|
385
|
-
const idx = options.filters.findIndex((f) => f.dimension ===
|
|
410
|
+
const idx = options.filters.findIndex((f) => shortFieldName(f.dimension) === field);
|
|
386
411
|
if (idx >= 0) options.filters[idx] = newFilter;
|
|
387
412
|
else options.filters.push(newFilter);
|
|
388
413
|
}
|
|
@@ -773,10 +798,21 @@ function SectionRenderer({ section, queryStates }) {
|
|
|
773
798
|
queryStates
|
|
774
799
|
}, i))
|
|
775
800
|
});
|
|
776
|
-
|
|
801
|
+
const isBigValue = section.component.type === "BigValue";
|
|
802
|
+
const inner = /* @__PURE__ */ jsx(ComponentRenderer, {
|
|
777
803
|
component: section.component,
|
|
778
804
|
queryStates
|
|
779
805
|
});
|
|
806
|
+
if (isBigValue) return inner;
|
|
807
|
+
return /* @__PURE__ */ jsx("div", {
|
|
808
|
+
style: {
|
|
809
|
+
borderRadius: "var(--bon-radius, 8px)",
|
|
810
|
+
border: "1px solid var(--bon-border, rgba(128,128,128,0.2))",
|
|
811
|
+
backgroundColor: "var(--bon-card-bg, transparent)",
|
|
812
|
+
padding: 16
|
|
813
|
+
},
|
|
814
|
+
children: inner
|
|
815
|
+
});
|
|
780
816
|
}
|
|
781
817
|
function ComponentRenderer({ component, queryStates }) {
|
|
782
818
|
const { type, props } = component;
|
|
@@ -328,6 +328,12 @@ function buildSeries(data, x, y, series) {
|
|
|
328
328
|
labels: [],
|
|
329
329
|
datasets: []
|
|
330
330
|
};
|
|
331
|
+
const firstX = String(data[0][x] ?? "");
|
|
332
|
+
if (/^\d{4}-\d{2}-\d{2}/.test(firstX)) data = [...data].sort((a, b) => {
|
|
333
|
+
const aVal = String(a[x] ?? "");
|
|
334
|
+
const bVal = String(b[x] ?? "");
|
|
335
|
+
return aVal.localeCompare(bVal);
|
|
336
|
+
});
|
|
331
337
|
const yColumns = y.split(",").map((col) => col.trim()).filter(Boolean);
|
|
332
338
|
if (!series) return {
|
|
333
339
|
labels: data.map((row) => String(row[x] ?? "")),
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as BarChart, c as PALETTES, i as LineChart, l as BonnardContext, n as PieChart, o as BigValue, r as AreaChart, s as CHART_COLORS, t as DataTable, u as useBonnard } from "./data-table-
|
|
1
|
+
import { a as BarChart, c as PALETTES, i as LineChart, l as BonnardContext, n as PieChart, o as BigValue, r as AreaChart, s as CHART_COLORS, t as DataTable, u as useBonnard } from "./data-table-C3K4rPh2.js";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { createClient } from "@bonnard/sdk";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply-inputs.d.ts","sourceRoot":"","sources":["../../src/lib/apply-inputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAU,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG7D,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzB;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC;AAE9E;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,YAAY,EACzB,SAAS,EAAE,YAAY,EAAE,EACzB,WAAW,EAAE,WAAW,GACvB,YAAY,CAmBd;
|
|
1
|
+
{"version":3,"file":"apply-inputs.d.ts","sourceRoot":"","sources":["../../src/lib/apply-inputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAU,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG7D,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzB;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC;AAE9E;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,YAAY,EACzB,SAAS,EAAE,YAAY,EAAE,EACzB,WAAW,EAAE,WAAW,GACvB,YAAY,CAmBd;AAiHD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,WAAW,CAkB3E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-series.d.ts","sourceRoot":"","sources":["../../src/lib/build-series.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,aAAa;IAC5B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,6BAA6B;IAC7B,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,CAAC,EAAE,MAAM,GACd,iBAAiB,
|
|
1
|
+
{"version":3,"file":"build-series.d.ts","sourceRoot":"","sources":["../../src/lib/build-series.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,aAAa;IAC5B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,6BAA6B;IAC7B,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,CAAC,EAAE,MAAM,GACd,iBAAiB,CA+EnB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bonnard/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Bonnard embedded analytics — React charts, dashboards, and hooks",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"isomorphic-dompurify": "^2.0.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@bonnard/sdk": "^0.
|
|
50
|
+
"@bonnard/sdk": "^0.3.0",
|
|
51
51
|
"@types/react": "^19.0.0",
|
|
52
52
|
"tsdown": "^0.12.5",
|
|
53
53
|
"typescript": "^5.5.0"
|