@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
- cube: 'orders',
54
- measures: ['revenue', 'count'],
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-DQKxzbS3.js";
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.cube) {
103
- errors.push(`Query "${name}" must specify a cube`);
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 !== 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 === 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
- return /* @__PURE__ */ jsx(ComponentRenderer, {
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-DQKxzbS3.js";
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;AA6ED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,WAAW,CAkB3E"}
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,CAmEnB"}
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.1.1",
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.2.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"