@quicdata/analytics 0.0.2 → 0.0.4

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.
Files changed (81) hide show
  1. package/core/auth.d.ts +19 -0
  2. package/core/auth.d.ts.map +1 -0
  3. package/core/auth.js +34 -0
  4. package/core/fetch-data.d.ts +115 -0
  5. package/core/fetch-data.d.ts.map +1 -0
  6. package/core/fetch-data.js +210 -0
  7. package/core/index.d.ts +9 -0
  8. package/core/index.d.ts.map +1 -0
  9. package/core/index.js +4 -0
  10. package/core/types.d.ts +250 -0
  11. package/core/types.d.ts.map +1 -0
  12. package/core/viewport-observer.d.ts +26 -0
  13. package/core/viewport-observer.d.ts.map +1 -0
  14. package/core/viewport-observer.js +38 -0
  15. package/core/widget-transform-runner.d.ts +22 -0
  16. package/core/widget-transform-runner.d.ts.map +1 -0
  17. package/core/widget-transform-runner.js +102 -0
  18. package/dashboard/dashboard-container.d.ts +100 -0
  19. package/dashboard/dashboard-container.d.ts.map +1 -0
  20. package/dashboard/dashboard-container.js +315 -0
  21. package/dashboard/index.d.ts +4 -0
  22. package/dashboard/index.d.ts.map +1 -0
  23. package/dashboard/index.js +2 -0
  24. package/designer/analytics-designer.d.ts +40 -0
  25. package/designer/analytics-designer.d.ts.map +1 -0
  26. package/designer/analytics-designer.js +267 -0
  27. package/designer/index.d.ts +5 -0
  28. package/designer/index.d.ts.map +1 -0
  29. package/designer/index.js +3 -0
  30. package/filters/filter-bar.d.ts +34 -0
  31. package/filters/filter-bar.d.ts.map +1 -0
  32. package/filters/filter-bar.js +233 -0
  33. package/filters/filter-button.d.ts +22 -0
  34. package/filters/filter-button.d.ts.map +1 -0
  35. package/filters/filter-button.js +86 -0
  36. package/filters/index.d.ts +7 -0
  37. package/filters/index.d.ts.map +1 -0
  38. package/filters/index.js +6 -0
  39. package/filters/widget-toolbar.d.ts +24 -0
  40. package/filters/widget-toolbar.d.ts.map +1 -0
  41. package/filters/widget-toolbar.js +216 -0
  42. package/index.d.ts +10 -0
  43. package/index.d.ts.map +1 -0
  44. package/index.js +6 -0
  45. package/package.json +27 -26
  46. package/widgets/analytics-report.d.ts +49 -0
  47. package/widgets/analytics-report.d.ts.map +1 -0
  48. package/widgets/analytics-report.js +306 -0
  49. package/widgets/analytics-widget.d.ts +39 -0
  50. package/widgets/analytics-widget.d.ts.map +1 -0
  51. package/widgets/analytics-widget.js +230 -0
  52. package/widgets/bar-chart.d.ts +13 -0
  53. package/widgets/bar-chart.d.ts.map +1 -0
  54. package/widgets/bar-chart.js +77 -0
  55. package/widgets/base-chart.d.ts +94 -0
  56. package/widgets/base-chart.d.ts.map +1 -0
  57. package/widgets/base-chart.js +535 -0
  58. package/widgets/index.d.ts +14 -0
  59. package/widgets/index.d.ts.map +1 -0
  60. package/widgets/index.js +14 -0
  61. package/widgets/line-chart.d.ts +13 -0
  62. package/widgets/line-chart.d.ts.map +1 -0
  63. package/widgets/line-chart.js +71 -0
  64. package/widgets/pie-chart.d.ts +13 -0
  65. package/widgets/pie-chart.d.ts.map +1 -0
  66. package/widgets/pie-chart.js +55 -0
  67. package/widgets/table.d.ts +101 -0
  68. package/widgets/table.d.ts.map +1 -0
  69. package/widgets/table.js +740 -0
  70. package/workers/widget-transform.worker.d.ts +21 -0
  71. package/workers/widget-transform.worker.d.ts.map +1 -0
  72. package/workers/widget-transform.worker.js +30 -0
  73. package/src/core/index.d.ts +0 -2
  74. package/src/core/index.d.ts.map +0 -1
  75. package/src/core/index.js +0 -3
  76. package/src/index.d.ts +0 -2
  77. package/src/index.d.ts.map +0 -1
  78. package/src/widgets/index.d.ts +0 -2
  79. package/src/widgets/index.d.ts.map +0 -1
  80. package/src/widgets/index.js +0 -3
  81. /package/{src/index.js → core/types.js} +0 -0
@@ -0,0 +1,71 @@
1
+ import { __decorate } from "tslib";
2
+ import { customElement } from 'lit/decorators.js';
3
+ import { BaseChartWidget } from './base-chart.js';
4
+ const LEGEND_NAME_MAX_LEN = 25;
5
+ function legendConfig(multipleSeries) {
6
+ if (!multipleSeries)
7
+ return undefined;
8
+ return {
9
+ type: 'scroll',
10
+ bottom: 8,
11
+ left: 'center',
12
+ formatter: (name) => name.length > LEGEND_NAME_MAX_LEN ? name.slice(0, LEGEND_NAME_MAX_LEN) + '…' : name,
13
+ };
14
+ }
15
+ /**
16
+ * Line chart widget (Apache ECharts). Use data-url or inline data.
17
+ * When widgetData is present (from API), use its categories + series so x-axis is correct (e.g. split_by).
18
+ * Otherwise first column = categories, remaining = series.
19
+ */
20
+ let LineChartWidget = class LineChartWidget extends BaseChartWidget {
21
+ buildOption(data, meta, widgetData) {
22
+ const wd = widgetData;
23
+ // Prefer widgetData whenever API sent it (categories = x-axis, series = one per split) so x-axis is never wrong.
24
+ if (wd && typeof wd === 'object' && Array.isArray(wd.categories)) {
25
+ const categories = wd.categories.map(String);
26
+ const seriesList = Array.isArray(wd.series) ? wd.series : [];
27
+ const series = seriesList.map((s) => ({
28
+ name: String(s?.name ?? ''),
29
+ type: 'line',
30
+ data: Array.isArray(s?.data) ? s.data.map((v) => Number(v) || 0) : [],
31
+ stack: wd.stack ? 'total' : undefined,
32
+ }));
33
+ const multiSeries = series.length > 1;
34
+ return {
35
+ grid: { left: 48, right: 24, top: 24, bottom: multiSeries ? 80 : 48 },
36
+ tooltip: { trigger: 'axis' },
37
+ legend: legendConfig(multiSeries),
38
+ xAxis: { type: 'category', data: categories },
39
+ yAxis: { type: 'value' },
40
+ series,
41
+ };
42
+ }
43
+ const keys = data.length ? Object.keys(data[0]) : Object.keys(meta);
44
+ if (keys.length === 0) {
45
+ return { xAxis: { type: 'category', data: [] }, yAxis: { type: 'value' }, series: [] };
46
+ }
47
+ const categoryKey = keys[0];
48
+ const valueKeys = keys.slice(1).filter((k) => meta[k]?.type === 'number' || typeof (data[0]?.[k]) === 'number');
49
+ const categories = [...new Set(data.map((r) => String(r[categoryKey] ?? '')))];
50
+ const series = valueKeys.length
51
+ ? valueKeys.map((name) => ({
52
+ name,
53
+ type: 'line',
54
+ data: data.map((r) => Number(r[name]) || 0),
55
+ }))
56
+ : [{ name: categoryKey, type: 'line', data: data.map((r) => Number(r[categoryKey]) || 0) }];
57
+ const multiSeries = series.length > 1;
58
+ return {
59
+ grid: { left: 48, right: 24, top: 24, bottom: multiSeries ? 80 : 48 },
60
+ tooltip: { trigger: 'axis' },
61
+ legend: legendConfig(multiSeries),
62
+ xAxis: { type: 'category', data: categories },
63
+ yAxis: { type: 'value' },
64
+ series,
65
+ };
66
+ }
67
+ };
68
+ LineChartWidget = __decorate([
69
+ customElement('analytics-line-chart')
70
+ ], LineChartWidget);
71
+ export { LineChartWidget };
@@ -0,0 +1,13 @@
1
+ import type { EChartsOption } from 'echarts/types/dist/option';
2
+ import { BaseChartWidget } from './base-chart.js';
3
+ /**
4
+ * Pie/Donut chart widget (Apache ECharts). Use data-url or inline data.
5
+ * When widgetData is present (from API), use its items so slice labels use backend formatters (e.g. status -> Pending, Approved).
6
+ * Otherwise: first column = name, second = value; or single column = count per category.
7
+ */
8
+ export declare class PieChartWidget extends BaseChartWidget {
9
+ buildOption(data: Record<string, unknown>[], meta: Record<string, {
10
+ type?: string;
11
+ }>, widgetData?: unknown): EChartsOption;
12
+ }
13
+ //# sourceMappingURL=pie-chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pie-chart.d.ts","sourceRoot":"","sources":["../../../../libs/analytics/src/widgets/pie-chart.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAQlD;;;;GAIG;AACH,qBACa,cAAe,SAAQ,eAAe;IACxC,WAAW,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EACvC,UAAU,CAAC,EAAE,OAAO,GACnB,aAAa;CA2CjB"}
@@ -0,0 +1,55 @@
1
+ import { __decorate } from "tslib";
2
+ import { customElement } from 'lit/decorators.js';
3
+ import { BaseChartWidget } from './base-chart.js';
4
+ /**
5
+ * Pie/Donut chart widget (Apache ECharts). Use data-url or inline data.
6
+ * When widgetData is present (from API), use its items so slice labels use backend formatters (e.g. status -> Pending, Approved).
7
+ * Otherwise: first column = name, second = value; or single column = count per category.
8
+ */
9
+ let PieChartWidget = class PieChartWidget extends BaseChartWidget {
10
+ buildOption(data, meta, widgetData) {
11
+ const wd = widgetData;
12
+ if (wd && typeof wd === 'object' && Array.isArray(wd.items) && wd.items.length > 0) {
13
+ const pieData = wd.items.map((item) => ({
14
+ name: String(item?.name ?? ''),
15
+ value: Number(item?.value) || 0,
16
+ }));
17
+ return {
18
+ tooltip: { trigger: 'item' },
19
+ series: [
20
+ {
21
+ type: 'pie',
22
+ radius: wd.chartType === 'Donut' ? ['40%', '70%'] : '60%',
23
+ data: pieData,
24
+ label: { show: true },
25
+ },
26
+ ],
27
+ };
28
+ }
29
+ const keys = data.length ? Object.keys(data[0]) : Object.keys(meta);
30
+ if (keys.length === 0) {
31
+ return { series: [{ type: 'pie', data: [] }] };
32
+ }
33
+ const nameKey = keys[0];
34
+ const valueKey = keys.length > 1 ? keys[1] : nameKey;
35
+ const pieData = data.map((r) => ({
36
+ name: String(r[nameKey] ?? ''),
37
+ value: Number(r[valueKey]) || 0,
38
+ }));
39
+ return {
40
+ tooltip: { trigger: 'item' },
41
+ series: [
42
+ {
43
+ type: 'pie',
44
+ radius: '60%',
45
+ data: pieData,
46
+ label: { show: true },
47
+ },
48
+ ],
49
+ };
50
+ }
51
+ };
52
+ PieChartWidget = __decorate([
53
+ customElement('analytics-pie-chart')
54
+ ], PieChartWidget);
55
+ export { PieChartWidget };
@@ -0,0 +1,101 @@
1
+ import { LitElement } from 'lit';
2
+ import type { WidgetDefinitionSubset } from '../core/fetch-data.js';
3
+ import type { DashboardContainer } from '../dashboard/dashboard-container.js';
4
+ import '../filters/index.js';
5
+ /**
6
+ * Table widget. Fetches data from data-url (Laravel analytics API)
7
+ * or uses inline data, then renders an HTML table.
8
+ * When dashboard is set, merges dashboard params with dataParams and listens for
9
+ * analytics-dashboard-filter-change and analytics-dashboard-refresh.
10
+ */
11
+ export declare class TableWidget extends LitElement {
12
+ static styles: import("lit").CSSResult;
13
+ /** Optional title override. When unset, the widget uses the title from the API definition. */
14
+ title: string;
15
+ /** API URL to fetch data (e.g. /api/analytics/widgets/1/data). When widgetId + apiUrl are set, overridden by buildWidgetDataUrl(apiUrl, widgetId). */
16
+ dataUrl: string;
17
+ /** Widget id (used with apiUrl to build data URL: /widgets/{id}/data). */
18
+ widgetId: string;
19
+ /** API base URL (host + prefix, e.g. /api/analytics). Used with widgetId to build data URL. */
20
+ apiUrl: string;
21
+ /** Query params for data-url (e.g. date_from, date_to). Widget params override dashboard params for same key. */
22
+ dataParams: Record<string, string | number | boolean>;
23
+ /** When set, widget receives dashboard filter/refresh events and merges dashboard params into requests. */
24
+ dashboard: DashboardContainer | null;
25
+ /** Inline data instead of fetching (for designer preview). */
26
+ data: Record<string, unknown>[] | null;
27
+ /** Inline meta (columns) when using inline data. */
28
+ meta: {
29
+ columns: Record<string, {
30
+ type?: string;
31
+ }>;
32
+ };
33
+ /** Transformed table data from API (columns, columnDefs, header_rows, rows, rowSpanRuns). When set, used for structure and headers instead of deriving from data. */
34
+ private _widgetData;
35
+ /** When true, only fetch/render when widget enters viewport; pause refresh when out of viewport. */
36
+ lazy: boolean;
37
+ /** CSS margin around viewport to trigger visibility earlier (e.g. '200px'). Used when lazy is true. */
38
+ prefetchMargin: string;
39
+ /** When set (e.g. by analytics-widget), definition is not fetched again; used to avoid duplicate definition requests. */
40
+ initialDefinition: WidgetDefinitionSubset | undefined;
41
+ private _loading;
42
+ private _error;
43
+ private _loadGeneration;
44
+ private _loadDataDebounceId;
45
+ private _loadDataInFlight;
46
+ private _ignoreNextFilterChange;
47
+ private _dashboardParams;
48
+ private _widgetFilters;
49
+ private _widgetFilterParams;
50
+ private _hideFilter;
51
+ private _dashboardEl;
52
+ private _viewportVisible;
53
+ /** Title from widget definition (API). Optional `title` attribute overrides this. */
54
+ private _definitionTitle;
55
+ private _hasLoadedOnce;
56
+ private _viewportUnobserve;
57
+ private _resizeObserver;
58
+ private _resizeDelayId;
59
+ private _resizeDebounceId;
60
+ /** Initial delay (ms) before entering debounce; each new resize signal cancels and restarts. */
61
+ private static readonly _RESIZE_DELAY_MS;
62
+ /** Debounce (ms) after delay; resize runs only when no signal for this long. */
63
+ private static readonly _RESIZE_DEBOUNCE_MS;
64
+ constructor();
65
+ private _boundOnDashboardFilterChange;
66
+ private _boundOnDashboardRefresh;
67
+ connectedCallback(): void;
68
+ disconnectedCallback(): void;
69
+ updated(changed: Map<string, unknown>): void;
70
+ private _attachDashboard;
71
+ private _detachDashboard;
72
+ firstUpdated(): void;
73
+ /** Debounce (ms) so multiple updated() calls (e.g. dataUrl then dataParams in separate ticks) result in one fetch. */
74
+ private static readonly _LOAD_DATA_DEBOUNCE_MS;
75
+ /** Debounce data load so multiple updated() calls (e.g. dataUrl then dataParams) result in one fetch. */
76
+ private _scheduleLoadData;
77
+ private _getEffectiveDataUrl;
78
+ private _getEffectiveParams;
79
+ /** Display title: optional host `title` overrides definition title from API. */
80
+ private get _effectiveTitle();
81
+ /** Run a callback after the current update cycle to avoid Lit "change-in-update" warning. */
82
+ private _defer;
83
+ private _loadData;
84
+ private _onWidgetFilterChange;
85
+ /** Column keys in display order. From widgetData when present, else derived from data/meta. */
86
+ private _getColumns;
87
+ /** Body rows. From widgetData.rows when present, else from data. */
88
+ private _getRows;
89
+ /** Header label for column key. From widgetData.columnDefs or header_rows when present. */
90
+ private _getColumnLabel;
91
+ /** Text-align for column. From widgetData.columnDefs when present. */
92
+ private _getColumnAlign;
93
+ /** Rowspan for this cell (column, rowIndex). 0 = merged (skip rendering cell). */
94
+ private _getCellRowSpan;
95
+ private _isTotalsRow;
96
+ render(): import("lit-html").TemplateResult<1>;
97
+ private _renderThead;
98
+ private _renderBodyRow;
99
+ private _formatCell;
100
+ }
101
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../../libs/analytics/src/widgets/table.ts"],"names":[],"mappings":"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"}