@ttoss/react-dashboard 0.1.1 → 0.1.2

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
@@ -7,7 +7,7 @@ A comprehensive React dashboard module that provides fully customizable dashboar
7
7
  ## Installation
8
8
 
9
9
  ```shell
10
- pnpm add @ttoss/react-dashboard @ttoss/components @ttoss/react-icons @ttoss/ui @emotion/react react-day-picker react-grid-layout
10
+ pnpm add @ttoss/react-dashboard
11
11
  ```
12
12
 
13
13
  ## Getting Started
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/react-dashboard",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "ttoss dashboard module for React apps.",
5
5
  "license": "MIT",
6
6
  "author": "ttoss",
@@ -23,26 +23,25 @@
23
23
  "dist"
24
24
  ],
25
25
  "sideEffects": false,
26
- "peerDependencies": {
27
- "react": ">=16.8.0",
28
- "react-day-picker": "^9.11.2",
26
+ "dependencies": {
27
+ "react-day-picker": "^9.11.3",
29
28
  "react-grid-layout": "^1.5.2",
30
- "react-hook-form": "^7.66.1",
31
- "@ttoss/components": "^2.10.1",
32
- "@ttoss/forms": "^0.35.2",
33
- "@ttoss/config": "^1.35.12",
34
- "@ttoss/test-utils": "^4.0.1",
35
- "@ttoss/react-icons": "^0.5.5",
36
- "@ttoss/ui": "^6.0.4"
29
+ "@ttoss/react-icons": "^0.5.6",
30
+ "@ttoss/components": "^2.10.2",
31
+ "@ttoss/react-i18n": "^2.0.25",
32
+ "@ttoss/forms": "^0.35.3",
33
+ "@ttoss/ui": "^6.1.0"
34
+ },
35
+ "peerDependencies": {
36
+ "react": ">=16.8.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@types/react": "^19.2.6",
39
+ "@types/react": "^19.2.7",
40
40
  "@types/react-grid-layout": "^1.3.6",
41
41
  "jest": "^30.2.0",
42
- "react-hook-form": "^7.66.1",
42
+ "react": "^19.2.1",
43
43
  "tsup": "^8.5.1",
44
- "@ttoss/components": "^2.10.1",
45
- "@ttoss/forms": "^0.35.2"
44
+ "@ttoss/config": "^1.35.12"
46
45
  },
47
46
  "keywords": [
48
47
  "React",
package/dist/esm/index.js DELETED
@@ -1,611 +0,0 @@
1
- /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
- import * as React from 'react';
3
- var __defProp = Object.defineProperty;
4
- var __name = (target, value) => __defProp(target, "name", {
5
- value,
6
- configurable: true
7
- });
8
-
9
- // src/Dashboard.tsx
10
- import { Divider, Flex as Flex6 } from "@ttoss/ui";
11
- import * as React8 from "react";
12
-
13
- // src/DashboardGrid.tsx
14
- import "react-grid-layout/css/styles.css";
15
- import { Box as Box3, Flex as Flex3, Spinner } from "@ttoss/ui";
16
- import { Responsive, WidthProvider } from "react-grid-layout";
17
-
18
- // src/Cards/BigNumber.tsx
19
- import { Icon } from "@ttoss/react-icons";
20
- import { Box as Box2, Flex as Flex2, Text as Text2 } from "@ttoss/ui";
21
-
22
- // src/Cards/Wrapper.tsx
23
- import { Box, Flex, Text, TooltipIcon } from "@ttoss/ui";
24
- var CardWrapper = /* @__PURE__ */__name(({
25
- title,
26
- children,
27
- description,
28
- variant = "default"
29
- }) => {
30
- const getBackgroundColor = /* @__PURE__ */__name(() => {
31
- switch (variant) {
32
- case "dark":
33
- return "input.background.secondary.default";
34
- case "light-green":
35
- return "feedback.background.positive.default";
36
- case "default":
37
- default:
38
- return "display.background.primary.default";
39
- }
40
- }, "getBackgroundColor");
41
- const getTitleColor = /* @__PURE__ */__name(() => {
42
- switch (variant) {
43
- case "dark":
44
- return "action.text.primary.default";
45
- case "light-green":
46
- return "feedback.text.positive.default";
47
- case "default":
48
- default:
49
- return "display.text.primary.default";
50
- }
51
- }, "getTitleColor");
52
- return /* @__PURE__ */React.createElement(Flex, {
53
- sx: {
54
- flexDirection: "column",
55
- gap: "3",
56
- backgroundColor: getBackgroundColor(),
57
- borderRadius: "lg",
58
- padding: "4",
59
- width: "100%",
60
- height: "100%",
61
- boxShadow: "0px 2px 8px rgba(0, 0, 0, 0.15)"
62
- }
63
- }, /* @__PURE__ */React.createElement(Box, {
64
- sx: {
65
- alignItems: "center",
66
- gap: "2"
67
- }
68
- }, /* @__PURE__ */React.createElement(Text, {
69
- variant: "h5",
70
- sx: {
71
- color: getTitleColor(),
72
- flex: 1,
73
- minWidth: 0
74
- }
75
- }, title), description && /* @__PURE__ */React.createElement(TooltipIcon, {
76
- variant: "info",
77
- icon: "ant-design:info-circle-outlined",
78
- tooltip: {
79
- children: description
80
- },
81
- sx: {
82
- marginLeft: "2",
83
- flexShrink: 0
84
- }
85
- })), /* @__PURE__ */React.createElement(Flex, {
86
- sx: {
87
- flexDirection: "column",
88
- flex: "auto",
89
- height: "100%",
90
- justifyContent: "center"
91
- }
92
- }, children));
93
- }, "CardWrapper");
94
-
95
- // src/Cards/BigNumber.tsx
96
- var formatNumber = /* @__PURE__ */__name((value, type) => {
97
- if (value === void 0 || value === null) {
98
- return "-";
99
- }
100
- switch (type) {
101
- case "currency":
102
- return new Intl.NumberFormat("pt-BR", {
103
- style: "currency",
104
- currency: "BRL"
105
- }).format(value);
106
- case "percentage":
107
- return `${value.toFixed(2)}%`;
108
- case "number":
109
- default:
110
- {
111
- const formatted = new Intl.NumberFormat("pt-BR", {
112
- minimumFractionDigits: 2,
113
- maximumFractionDigits: 2
114
- }).format(value);
115
- return formatted;
116
- }
117
- }
118
- }, "formatNumber");
119
- var getValueColor = /* @__PURE__ */__name((color, variant) => {
120
- if (variant === "dark") {
121
- return "action.text.primary.default";
122
- }
123
- if (variant === "light-green") {
124
- return "feedback.text.positive.default";
125
- }
126
- if (!color) {
127
- return "display.text.primary.default";
128
- }
129
- if (["green", "accent", "positive"].includes(color.toLowerCase())) {
130
- return "display.text.accent.default";
131
- }
132
- return "display.text.primary.default";
133
- }, "getValueColor");
134
- var getTrendColor = /* @__PURE__ */__name(status => {
135
- if (status === "positive") {
136
- return "display.text.accent.default";
137
- }
138
- if (status === "negative") {
139
- return "display.text.negative.default";
140
- }
141
- return "display.text.primary.default";
142
- }, "getTrendColor");
143
- var BigNumber = /* @__PURE__ */__name(props => {
144
- const total = props.data.api?.total ?? props.data.meta?.total ?? void 0;
145
- const formattedValue = formatNumber(total, props.numberType);
146
- const displayValue = props.numberType === "number" && props.title.toLowerCase().includes("roas") ? `${formattedValue}x` : formattedValue;
147
- const valueColor = getValueColor(props.color, props.variant);
148
- const variant = props.variant || "default";
149
- return /* @__PURE__ */React.createElement(CardWrapper, {
150
- title: props.title,
151
- description: props.description || "",
152
- variant
153
- }, /* @__PURE__ */React.createElement(Flex2, {
154
- sx: {
155
- flexDirection: "column",
156
- gap: "2"
157
- }
158
- }, /* @__PURE__ */React.createElement(Text2, {
159
- sx: {
160
- color: valueColor,
161
- fontSize: "2xl",
162
- fontWeight: "bold",
163
- lineHeight: "1.2"
164
- }
165
- }, displayValue), props.trend && /* @__PURE__ */React.createElement(Flex2, {
166
- sx: {
167
- alignItems: "center",
168
- gap: "1"
169
- }
170
- }, /* @__PURE__ */React.createElement(Box2, {
171
- sx: {
172
- color: getTrendColor(props.trend.status),
173
- display: "flex",
174
- alignItems: "center"
175
- }
176
- }, props.trend.status === "positive" ? /* @__PURE__ */React.createElement(Icon, {
177
- icon: "mdi:arrow-up",
178
- width: 16
179
- }) : props.trend.status === "negative" ? /* @__PURE__ */React.createElement(Icon, {
180
- icon: "mdi:arrow-down",
181
- width: 16
182
- }) : null, props.trend.status === "neutral" ? /* @__PURE__ */React.createElement(Icon, {
183
- icon: "mdi:arrow-right",
184
- width: 16
185
- }) : null), /* @__PURE__ */React.createElement(Text2, {
186
- sx: {
187
- color: getTrendColor(props.trend.status),
188
- fontSize: "sm",
189
- fontWeight: "medium"
190
- }
191
- }, props.trend.status === "positive" ? "+" : "", props.trend.status === "negative" ? "-" : "", props.trend.status === "neutral" ? "" : "", props.trend.value.toFixed(1), "%", " ", props.trend ? "vs. per\xEDodo anterior" : "")), props.additionalInfo && /* @__PURE__ */React.createElement(Text2, {
192
- sx: {
193
- color: getValueColor(props.color, props.variant),
194
- fontSize: "sm",
195
- mt: "1"
196
- }
197
- }, props.additionalInfo), props.status && /* @__PURE__ */React.createElement(Flex2, {
198
- sx: {
199
- alignItems: "center",
200
- gap: "1",
201
- mt: props.trend || props.additionalInfo ? "2" : "1"
202
- }
203
- }, props.status.icon && /* @__PURE__ */React.createElement(Box2, {
204
- sx: {
205
- color: "feedback.text.positive.default",
206
- display: "flex",
207
- alignItems: "center"
208
- }
209
- }, /* @__PURE__ */React.createElement(Icon, {
210
- icon: props.status.icon,
211
- width: 16
212
- })), /* @__PURE__ */React.createElement(Text2, {
213
- sx: {
214
- color: "feedback.text.positive.default",
215
- fontSize: "sm",
216
- fontWeight: "medium"
217
- }
218
- }, props.status.text))));
219
- }, "BigNumber");
220
-
221
- // src/DashboardCard.tsx
222
- var DashboardCard = /* @__PURE__ */__name(props => {
223
- switch (props.type) {
224
- case "bigNumber":
225
- return /* @__PURE__ */React.createElement(BigNumber, props);
226
- default:
227
- return null;
228
- }
229
- }, "DashboardCard");
230
-
231
- // src/DashboardGrid.tsx
232
- var ResponsiveGridLayout = WidthProvider(Responsive);
233
- var DashboardGrid = /* @__PURE__ */__name(({
234
- loading,
235
- selectedTemplate
236
- }) => {
237
- if (!selectedTemplate) {
238
- return null;
239
- }
240
- const breakpoints = {
241
- xs: 0,
242
- sm: 480,
243
- md: 768,
244
- lg: 1024,
245
- xl: 1280,
246
- "2xl": 1536
247
- };
248
- const cols = {
249
- xs: 2,
250
- sm: 2,
251
- md: 12,
252
- lg: 12,
253
- xl: 12,
254
- "2xl": 12
255
- };
256
- const baseLayout = selectedTemplate.grid.map(item => {
257
- const {
258
- card,
259
- ...layout
260
- } = item;
261
- return layout;
262
- });
263
- const layouts = {
264
- xs: baseLayout,
265
- sm: baseLayout,
266
- md: baseLayout,
267
- lg: baseLayout,
268
- xl: baseLayout,
269
- "2xl": baseLayout
270
- };
271
- return /* @__PURE__ */React.createElement(Box3, {
272
- sx: {
273
- width: "100%",
274
- height: "full"
275
- }
276
- }, loading ? /* @__PURE__ */React.createElement(Flex3, {
277
- sx: {
278
- width: "100%",
279
- height: "full",
280
- justifyContent: "center",
281
- alignItems: "center"
282
- }
283
- }, /* @__PURE__ */React.createElement(Spinner, null)) : /* @__PURE__ */React.createElement(ResponsiveGridLayout, {
284
- className: "layout",
285
- layouts,
286
- breakpoints,
287
- cols,
288
- rowHeight: 30,
289
- margin: [10, 10],
290
- containerPadding: [0, 0]
291
- }, selectedTemplate.grid.map(item => {
292
- return /* @__PURE__ */React.createElement("div", {
293
- key: item.i
294
- }, /* @__PURE__ */React.createElement(DashboardCard, item.card));
295
- })));
296
- }, "DashboardGrid");
297
-
298
- // src/DashboardHeader.tsx
299
- import { Flex as Flex5 } from "@ttoss/ui";
300
- import * as React7 from "react";
301
-
302
- // src/DashboardFilters.tsx
303
- import { Flex as Flex4 } from "@ttoss/ui";
304
- import * as React6 from "react";
305
-
306
- // src/DashboardProvider.tsx
307
- import * as React2 from "react";
308
- var DashboardContext = /* @__PURE__ */React2.createContext({
309
- filters: [],
310
- updateFilter: /* @__PURE__ */__name(() => {}, "updateFilter"),
311
- templates: [],
312
- selectedTemplate: void 0
313
- });
314
- var DashboardProvider = /* @__PURE__ */__name(props => {
315
- const {
316
- filters: externalFilters,
317
- templates: externalTemplates,
318
- onFiltersChange
319
- } = props;
320
- const onFiltersChangeRef = React2.useRef(onFiltersChange);
321
- const filtersRef = React2.useRef(externalFilters);
322
- React2.useEffect(() => {
323
- onFiltersChangeRef.current = onFiltersChange;
324
- }, [onFiltersChange]);
325
- React2.useEffect(() => {
326
- filtersRef.current = externalFilters;
327
- }, [externalFilters]);
328
- const updateFilter = React2.useCallback((key, value) => {
329
- const updatedFilters = filtersRef.current.map(filter => {
330
- return filter.key === key ? {
331
- ...filter,
332
- value
333
- } : filter;
334
- });
335
- onFiltersChangeRef.current?.(updatedFilters);
336
- }, []
337
- // Empty deps - we use refs for current values
338
- );
339
- const selectedTemplate = React2.useMemo(() => {
340
- const templateId = externalFilters.find(filter => {
341
- return filter.key === "template";
342
- })?.value;
343
- return externalTemplates.find(template => {
344
- return template.id === templateId;
345
- });
346
- }, [externalFilters, externalTemplates]);
347
- return /* @__PURE__ */React2.createElement(DashboardContext.Provider, {
348
- value: {
349
- filters: externalFilters,
350
- updateFilter,
351
- templates: externalTemplates,
352
- selectedTemplate
353
- }
354
- }, props.children);
355
- }, "DashboardProvider");
356
- var useDashboard = /* @__PURE__ */__name(() => {
357
- const context = React2.useContext(DashboardContext);
358
- if (!context) {
359
- throw new Error("useDashboard must be used within a DashboardProvider");
360
- }
361
- return context;
362
- }, "useDashboard");
363
-
364
- // src/Filters/DateRangeFilter.tsx
365
- import { FormFieldDatePicker } from "@ttoss/forms";
366
- import * as React3 from "react";
367
- import { FormProvider, useForm } from "react-hook-form";
368
- var DateRangeFilter = /* @__PURE__ */__name(({
369
- label,
370
- value,
371
- presets,
372
- onChange
373
- }) => {
374
- const formMethods = useForm({
375
- defaultValues: {
376
- dateRange: value
377
- },
378
- mode: "onChange"
379
- });
380
- React3.useEffect(() => {
381
- if (value !== void 0) {
382
- formMethods.setValue("dateRange", value, {
383
- shouldDirty: false
384
- });
385
- }
386
- }, [value, formMethods]);
387
- const currentValue = formMethods.watch("dateRange");
388
- const dateRangesEqual = React3.useCallback((a, b) => {
389
- if (a === b) {
390
- return true;
391
- }
392
- if (!a || !b) {
393
- return false;
394
- }
395
- const aFrom = a.from?.getTime();
396
- const aTo = a.to?.getTime();
397
- const bFrom = b.from?.getTime();
398
- const bTo = b.to?.getTime();
399
- return aFrom === bFrom && aTo === bTo;
400
- }, []);
401
- React3.useEffect(() => {
402
- if (currentValue !== void 0 && !dateRangesEqual(currentValue, value)) {
403
- onChange?.(currentValue);
404
- }
405
- }, [currentValue, value, onChange, dateRangesEqual]);
406
- return /* @__PURE__ */React3.createElement(FormProvider, formMethods, /* @__PURE__ */React3.createElement(FormFieldDatePicker, {
407
- name: "dateRange",
408
- label,
409
- presets
410
- }));
411
- }, "DateRangeFilter");
412
-
413
- // src/Filters/SelectFilter.tsx
414
- import { FormFieldSelect } from "@ttoss/forms";
415
- import * as React4 from "react";
416
- import { FormProvider as FormProvider2, useForm as useForm2 } from "react-hook-form";
417
- var SelectFilter = /* @__PURE__ */__name(props => {
418
- const {
419
- value,
420
- onChange,
421
- label,
422
- options
423
- } = props;
424
- const formMethods = useForm2({
425
- defaultValues: {
426
- value
427
- },
428
- mode: "onChange"
429
- });
430
- React4.useEffect(() => {
431
- const propValue = value;
432
- formMethods.setValue("value", propValue, {
433
- shouldDirty: false
434
- });
435
- }, [value, formMethods]);
436
- const currentValue = formMethods.watch("value");
437
- React4.useEffect(() => {
438
- if (currentValue !== void 0 && currentValue !== value) {
439
- onChange(currentValue);
440
- }
441
- }, [currentValue, value, onChange]);
442
- return /* @__PURE__ */React4.createElement(FormProvider2, formMethods, /* @__PURE__ */React4.createElement(FormFieldSelect, {
443
- name: "value",
444
- label,
445
- options,
446
- sx: {
447
- fontSize: "sm"
448
- }
449
- }));
450
- }, "SelectFilter");
451
-
452
- // src/Filters/TextFilter.tsx
453
- import { FormFieldInput } from "@ttoss/forms";
454
- import * as React5 from "react";
455
- import { FormProvider as FormProvider3, useForm as useForm3 } from "react-hook-form";
456
- var TextFilter = /* @__PURE__ */__name(props => {
457
- const {
458
- value,
459
- onChange,
460
- label,
461
- placeholder
462
- } = props;
463
- const formMethods = useForm3({
464
- defaultValues: {
465
- value: value.toString()
466
- },
467
- mode: "onChange"
468
- });
469
- React5.useEffect(() => {
470
- const stringValue = value.toString();
471
- formMethods.setValue("value", stringValue, {
472
- shouldDirty: false
473
- });
474
- }, [value, formMethods]);
475
- const currentValue = formMethods.watch("value");
476
- React5.useEffect(() => {
477
- if (currentValue !== void 0 && currentValue !== value.toString()) {
478
- onChange(currentValue);
479
- }
480
- }, [currentValue, value, onChange]);
481
- return /* @__PURE__ */React5.createElement(FormProvider3, formMethods, /* @__PURE__ */React5.createElement(FormFieldInput, {
482
- name: "value",
483
- label,
484
- placeholder,
485
- sx: {
486
- fontSize: "sm"
487
- }
488
- }));
489
- }, "TextFilter");
490
-
491
- // src/DashboardFilters.tsx
492
- var DashboardFilterType = /* @__PURE__ */function (DashboardFilterType2) {
493
- DashboardFilterType2["TEXT"] = "text";
494
- DashboardFilterType2["SELECT"] = "select";
495
- DashboardFilterType2["DATE_RANGE"] = "date-range";
496
- DashboardFilterType2["NUMBER"] = "number";
497
- DashboardFilterType2["BOOLEAN"] = "boolean";
498
- return DashboardFilterType2;
499
- }({});
500
- var DashboardFilters = /* @__PURE__ */__name(() => {
501
- const {
502
- filters,
503
- updateFilter
504
- } = useDashboard();
505
- const onChangeHandlers = React6.useMemo(() => {
506
- const handlers = /* @__PURE__ */new Map();
507
- for (const filter of filters) {
508
- handlers.set(filter.key, value => {
509
- updateFilter(filter.key, value);
510
- });
511
- }
512
- return handlers;
513
- }, [filters, updateFilter]);
514
- return /* @__PURE__ */React6.createElement(Flex4, {
515
- sx: {
516
- gap: "2",
517
- flexDirection: "row",
518
- "@media (max-width: 768px)": {
519
- flexWrap: "wrap"
520
- }
521
- }
522
- }, filters.map(filter => {
523
- const onChange = onChangeHandlers.get(filter.key);
524
- if (!onChange) {
525
- return null;
526
- }
527
- switch (filter.type) {
528
- case "text":
529
- return /* @__PURE__ */React6.createElement(TextFilter, {
530
- key: filter.key,
531
- name: filter.key,
532
- label: filter.label,
533
- value: filter.value,
534
- placeholder: filter.placeholder,
535
- onChange
536
- });
537
- case "select":
538
- return /* @__PURE__ */React6.createElement(SelectFilter, {
539
- key: filter.key,
540
- name: filter.key,
541
- label: filter.label,
542
- value: filter.value,
543
- options: filter.options ?? [],
544
- onChange: /* @__PURE__ */__name(value => {
545
- onChange(value);
546
- }, "onChange")
547
- });
548
- case "date-range":
549
- return /* @__PURE__ */React6.createElement(DateRangeFilter, {
550
- label: filter.label,
551
- key: filter.key,
552
- value: filter.value,
553
- presets: filter.presets,
554
- onChange: /* @__PURE__ */__name(range => {
555
- onChange(range);
556
- }, "onChange")
557
- });
558
- default:
559
- return null;
560
- }
561
- }));
562
- }, "DashboardFilters");
563
-
564
- // src/DashboardHeader.tsx
565
- var DashboardHeader = /* @__PURE__ */__name(({
566
- children
567
- }) => {
568
- return /* @__PURE__ */React7.createElement(Flex5, {
569
- sx: {
570
- padding: "2"
571
- }
572
- }, /* @__PURE__ */React7.createElement(DashboardFilters, null), children);
573
- }, "DashboardHeader");
574
-
575
- // src/Dashboard.tsx
576
- var DashboardContent = /* @__PURE__ */__name(({
577
- loading = false,
578
- headerChildren
579
- }) => {
580
- const {
581
- selectedTemplate
582
- } = useDashboard();
583
- return /* @__PURE__ */React8.createElement(Flex6, {
584
- sx: {
585
- flexDirection: "column",
586
- gap: "5",
587
- padding: "2",
588
- width: "100%"
589
- }
590
- }, /* @__PURE__ */React8.createElement(DashboardHeader, null, headerChildren), /* @__PURE__ */React8.createElement(Divider, null), /* @__PURE__ */React8.createElement(DashboardGrid, {
591
- loading,
592
- selectedTemplate
593
- }));
594
- }, "DashboardContent");
595
- var Dashboard = /* @__PURE__ */__name(({
596
- loading = false,
597
- templates = [],
598
- filters = [],
599
- headerChildren,
600
- onFiltersChange
601
- }) => {
602
- return /* @__PURE__ */React8.createElement(DashboardProvider, {
603
- filters,
604
- templates,
605
- onFiltersChange
606
- }, /* @__PURE__ */React8.createElement(DashboardContent, {
607
- loading,
608
- headerChildren
609
- }));
610
- }, "Dashboard");
611
- export { Dashboard, DashboardCard, DashboardFilterType, DashboardFilters, DashboardGrid, DashboardHeader, DashboardProvider, useDashboard };
package/dist/index.d.ts DELETED
@@ -1,116 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React from 'react';
3
- import ReactGridLayout from 'react-grid-layout';
4
- import { DateRange } from '@ttoss/components/DatePicker';
5
-
6
- type CardNumberType = 'number' | 'percentage' | 'currency';
7
- type CardSourceType = {
8
- source: 'meta' | 'oneclickads' | 'api';
9
- level?: 'adAccount' | 'campaign' | 'adSet' | 'ad';
10
- };
11
- type DashboardCardType = 'bigNumber' | 'pieChart' | 'barChart' | 'lineChart' | 'table' | 'list';
12
- type DashboardCardData = {
13
- meta?: {
14
- total?: number;
15
- daily?: number[];
16
- };
17
- api?: {
18
- total?: number;
19
- daily?: number[];
20
- };
21
- };
22
- type CardVariant = 'default' | 'dark' | 'light-green';
23
- type TrendIndicator = {
24
- value: number;
25
- status?: 'positive' | 'negative' | 'neutral';
26
- };
27
- type StatusIndicator = {
28
- text: string;
29
- icon?: string;
30
- };
31
- interface DashboardCard {
32
- title: string;
33
- description?: string;
34
- icon?: string;
35
- color?: string;
36
- variant?: CardVariant;
37
- numberType: CardNumberType;
38
- type: DashboardCardType;
39
- sourceType: CardSourceType[];
40
- labels?: Array<string | number>;
41
- data: DashboardCardData;
42
- trend?: TrendIndicator;
43
- additionalInfo?: string;
44
- status?: StatusIndicator;
45
- }
46
- declare const DashboardCard: (props: DashboardCard) => react_jsx_runtime.JSX.Element | null;
47
-
48
- type DashboardFilterValue = string | number | boolean | {
49
- from: Date;
50
- to: Date;
51
- };
52
- declare enum DashboardFilterType {
53
- TEXT = "text",
54
- SELECT = "select",
55
- DATE_RANGE = "date-range",
56
- NUMBER = "number",
57
- BOOLEAN = "boolean"
58
- }
59
- type DashboardFilter = {
60
- key: string;
61
- type: DashboardFilterType;
62
- label: string;
63
- placeholder?: string;
64
- value: DashboardFilterValue;
65
- onChange?: (value: DashboardFilterValue) => void;
66
- options?: {
67
- label: string;
68
- value: string | number | boolean;
69
- }[];
70
- presets?: {
71
- label: string;
72
- getValue: () => DateRange;
73
- }[];
74
- };
75
- declare const DashboardFilters: () => react_jsx_runtime.JSX.Element;
76
-
77
- type DashboardGridItem = ReactGridLayout.Layout & {
78
- card: DashboardCard;
79
- };
80
- interface DashboardTemplate {
81
- id: string;
82
- name: string;
83
- description?: string;
84
- grid: DashboardGridItem[];
85
- }
86
- declare const Dashboard: ({ loading, templates, filters, headerChildren, onFiltersChange, }: {
87
- loading?: boolean;
88
- headerChildren?: React.ReactNode;
89
- templates?: DashboardTemplate[];
90
- filters?: DashboardFilter[];
91
- onFiltersChange?: (filters: DashboardFilter[]) => void;
92
- }) => react_jsx_runtime.JSX.Element;
93
-
94
- declare const DashboardGrid: ({ loading, selectedTemplate, }: {
95
- loading: boolean;
96
- selectedTemplate?: DashboardTemplate;
97
- }) => react_jsx_runtime.JSX.Element | null;
98
-
99
- declare const DashboardHeader: ({ children, }: {
100
- children?: React.ReactNode;
101
- }) => react_jsx_runtime.JSX.Element;
102
-
103
- declare const DashboardProvider: (props: {
104
- children: React.ReactNode;
105
- filters: DashboardFilter[];
106
- templates: DashboardTemplate[];
107
- onFiltersChange?: (filters: DashboardFilter[]) => void;
108
- }) => react_jsx_runtime.JSX.Element;
109
- declare const useDashboard: () => {
110
- filters: DashboardFilter[];
111
- updateFilter: (key: string, value: DashboardFilterValue) => void;
112
- templates: DashboardTemplate[];
113
- selectedTemplate: DashboardTemplate | undefined;
114
- };
115
-
116
- export { Dashboard, DashboardCard, type DashboardFilter, DashboardFilterType, type DashboardFilterValue, DashboardFilters, DashboardGrid, type DashboardGridItem, DashboardHeader, DashboardProvider, type DashboardTemplate, useDashboard };