@quillsql/react 1.0.2 → 1.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.
- package/example/src/App.tsx +2 -1
- package/lib/BarList.d.ts +3 -0
- package/lib/BarList.js +68 -27
- package/lib/BarList.js.map +1 -1
- package/lib/Chart.js +29 -11
- package/lib/Chart.js.map +1 -1
- package/lib/Dashboard.d.ts +2 -1
- package/lib/Dashboard.js +97 -58
- package/lib/Dashboard.js.map +1 -1
- package/package.json +1 -1
- package/src/BarList.tsx +181 -57
- package/src/Chart.tsx +61 -6
- package/src/Dashboard.tsx +164 -106
- package/tailwind.config.js +4 -1
package/src/Chart.tsx
CHANGED
|
@@ -381,6 +381,7 @@ const Chart = ({ chartId, colors, containerStyle }) => {
|
|
|
381
381
|
containerStyle={containerStyle}
|
|
382
382
|
colors={colors}
|
|
383
383
|
client={client}
|
|
384
|
+
theme={theme}
|
|
384
385
|
/>
|
|
385
386
|
);
|
|
386
387
|
};
|
|
@@ -494,7 +495,10 @@ const ChartUpdater: React.FC<ChartProps> = ({
|
|
|
494
495
|
|
|
495
496
|
if (!chartConfig || loading) {
|
|
496
497
|
return (
|
|
497
|
-
<div
|
|
498
|
+
<div
|
|
499
|
+
className="flex flex-col flex-1 h-[100%]"
|
|
500
|
+
style={{ ...containerStyle, marginLeft: 25 }}
|
|
501
|
+
>
|
|
498
502
|
<Skeleton
|
|
499
503
|
count={1}
|
|
500
504
|
height={containerStyle?.height}
|
|
@@ -531,10 +535,28 @@ const ChartUpdater: React.FC<ChartProps> = ({
|
|
|
531
535
|
}
|
|
532
536
|
|
|
533
537
|
if (chartConfig?.chartType === 'bar') {
|
|
534
|
-
|
|
538
|
+
return (
|
|
539
|
+
<BarList
|
|
540
|
+
data={chartConfig.rows.map(row => {
|
|
541
|
+
const fieldKeys = chartConfig.yAxisFields.map(elem => elem.field);
|
|
542
|
+
const newRow = row;
|
|
543
|
+
for (const key of fieldKeys) {
|
|
544
|
+
newRow[key] = parseFloat(row[key]);
|
|
545
|
+
}
|
|
546
|
+
return newRow;
|
|
547
|
+
})}
|
|
548
|
+
theme={theme}
|
|
549
|
+
yAxisFields={chartConfig.yAxisFields}
|
|
550
|
+
colors={colors}
|
|
551
|
+
xAxisField={chartConfig.xAxisField}
|
|
552
|
+
xAxisLabel={chartConfig.xAxisLabel}
|
|
553
|
+
containerStyle={containerStyle}
|
|
554
|
+
/>
|
|
555
|
+
);
|
|
535
556
|
return (
|
|
536
557
|
<BarChart
|
|
537
558
|
colors={colors}
|
|
559
|
+
theme={theme}
|
|
538
560
|
yAxisFields={chartConfig.yAxisFields}
|
|
539
561
|
// @ts-ignore
|
|
540
562
|
data={chartConfig.rows.map(row => {
|
|
@@ -561,7 +583,6 @@ const ChartUpdater: React.FC<ChartProps> = ({
|
|
|
561
583
|
fontWeight: '600',
|
|
562
584
|
textOverflow: 'ellipsis',
|
|
563
585
|
margin: 0,
|
|
564
|
-
marginLeft: 0,
|
|
565
586
|
padding: 20,
|
|
566
587
|
whiteSpace: 'nowrap',
|
|
567
588
|
display: 'block',
|
|
@@ -601,9 +622,9 @@ function formatNumber(num, label) {
|
|
|
601
622
|
return num.toFixed(2) + ' ' + label;
|
|
602
623
|
}
|
|
603
624
|
if (num >= 1.0e6) {
|
|
604
|
-
return
|
|
625
|
+
return Math.round(num / 1.0e6).toLocaleString() + 'M';
|
|
605
626
|
} else {
|
|
606
|
-
return
|
|
627
|
+
return Math.round(num / 1.0e6).toLocaleString() + 'M';
|
|
607
628
|
}
|
|
608
629
|
}
|
|
609
630
|
|
|
@@ -629,6 +650,37 @@ function getDomain(data, fields) {
|
|
|
629
650
|
return [adjustedMin, adjustedMax];
|
|
630
651
|
}
|
|
631
652
|
|
|
653
|
+
const CustomizedTick = ({
|
|
654
|
+
x,
|
|
655
|
+
y,
|
|
656
|
+
payload,
|
|
657
|
+
theme,
|
|
658
|
+
}: {
|
|
659
|
+
x: number;
|
|
660
|
+
y: number;
|
|
661
|
+
payload: any;
|
|
662
|
+
theme: any;
|
|
663
|
+
}) => {
|
|
664
|
+
// const { x, y, payload } = props;
|
|
665
|
+
const maxLength = 10;
|
|
666
|
+
const value = payload.value;
|
|
667
|
+
const truncatedValue =
|
|
668
|
+
value.length > maxLength ? value.substring(0, maxLength) + '...' : value;
|
|
669
|
+
return (
|
|
670
|
+
<text
|
|
671
|
+
xlinkTitle={value}
|
|
672
|
+
fill={theme.chartLabelColor}
|
|
673
|
+
fontSize={12}
|
|
674
|
+
x={x}
|
|
675
|
+
y={y + 15}
|
|
676
|
+
width={30}
|
|
677
|
+
textAnchor="middle"
|
|
678
|
+
>
|
|
679
|
+
{truncatedValue}
|
|
680
|
+
</text>
|
|
681
|
+
);
|
|
682
|
+
};
|
|
683
|
+
|
|
632
684
|
function BarChart({
|
|
633
685
|
colors,
|
|
634
686
|
yAxisFields,
|
|
@@ -636,6 +688,7 @@ function BarChart({
|
|
|
636
688
|
containerStyle,
|
|
637
689
|
xAxisField,
|
|
638
690
|
xAxisLabel,
|
|
691
|
+
theme,
|
|
639
692
|
}: {
|
|
640
693
|
colors: string[];
|
|
641
694
|
yAxisFields: any[];
|
|
@@ -643,6 +696,7 @@ function BarChart({
|
|
|
643
696
|
containerStyle?: React.CSSProperties;
|
|
644
697
|
xAxisField: string;
|
|
645
698
|
xAxisLabel: string;
|
|
699
|
+
theme: any;
|
|
646
700
|
}) {
|
|
647
701
|
const newColors = findComplementaryAndAnalogousColors(colors[0], colors[1]);
|
|
648
702
|
return (
|
|
@@ -680,7 +734,8 @@ function BarChart({
|
|
|
680
734
|
hide={false}
|
|
681
735
|
dataKey={xAxisField}
|
|
682
736
|
// interval="preserveStartEnd"
|
|
683
|
-
tick={{ transform: 'translate(0, 6)' }}
|
|
737
|
+
tick={{ transform: 'translate(0, 6)' }}
|
|
738
|
+
//padding between labels and axis
|
|
684
739
|
style={{
|
|
685
740
|
fontSize: '12px',
|
|
686
741
|
// TODO: generalize
|
package/src/Dashboard.tsx
CHANGED
|
@@ -2,9 +2,11 @@ import React, { useContext, useEffect, useState } from 'react';
|
|
|
2
2
|
import Chart from './Chart';
|
|
3
3
|
import {
|
|
4
4
|
ClientContext,
|
|
5
|
+
DashboardContext,
|
|
5
6
|
DashboardStateContext,
|
|
6
7
|
DashboardUpdateContext,
|
|
7
8
|
DateFilterContext,
|
|
9
|
+
ThemeContext,
|
|
8
10
|
} from './Context';
|
|
9
11
|
import { startOfToday, sub } from 'date-fns';
|
|
10
12
|
import { DateRangePicker } from './DateRangePicker/index';
|
|
@@ -14,25 +16,29 @@ interface DashboardProps {
|
|
|
14
16
|
containerStyle?: React.CSSProperties;
|
|
15
17
|
maxColumnWidth?: number;
|
|
16
18
|
rowHeight?: number;
|
|
19
|
+
onClickDashboardItem?: (item: any) => void;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
const theme = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
};
|
|
22
|
+
// const theme = {
|
|
23
|
+
// fontFamily: 'Inter; Helvetica',
|
|
24
|
+
// primaryTextColor: '#212121',
|
|
25
|
+
// secondaryTextColor: '#6C727F',
|
|
26
|
+
// chartLabelColor: '#666666',
|
|
27
|
+
// chartTickColor: '#CCCCCC',
|
|
28
|
+
// chartColors: ['#6269E9', '#E14F62'],
|
|
29
|
+
// };
|
|
27
30
|
|
|
28
31
|
export default function Dashboard({
|
|
29
32
|
name,
|
|
30
33
|
containerStyle,
|
|
31
34
|
maxColumnWidth,
|
|
32
35
|
rowHeight,
|
|
36
|
+
onClickDashboardItem,
|
|
33
37
|
}: DashboardProps) {
|
|
34
38
|
const [dashboardSections, setDashboardSections] = useState<any>(null);
|
|
39
|
+
const { dashboard } = useContext(DashboardContext);
|
|
35
40
|
const [client, _] = useContext(ClientContext);
|
|
41
|
+
const [theme, _] = useContext(ThemeContext);
|
|
36
42
|
const { dateFilter, dateFilterDispatch } = useContext(DateFilterContext);
|
|
37
43
|
|
|
38
44
|
const setGlobalDateFilter = (startDate, endDate) => {
|
|
@@ -78,12 +84,18 @@ export default function Dashboard({
|
|
|
78
84
|
});
|
|
79
85
|
}, []);
|
|
80
86
|
|
|
87
|
+
const handleOnClickDashboardItem = id => {
|
|
88
|
+
if (dashboard[id]) {
|
|
89
|
+
onClickDashboardItem(dashboard[id]);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
81
93
|
if (!dashboardSections) {
|
|
82
94
|
return null;
|
|
83
95
|
}
|
|
84
96
|
return (
|
|
85
97
|
<div style={containerStyle}>
|
|
86
|
-
<div style={{ width: 420,
|
|
98
|
+
<div style={{ width: 420, marginBottom: 25, marginLeft: 25 }}>
|
|
87
99
|
<DateRangePicker
|
|
88
100
|
// change to be set on the dashboard / section as default date range
|
|
89
101
|
defaultValue={[undefined, undefined, '90d']}
|
|
@@ -110,7 +122,7 @@ export default function Dashboard({
|
|
|
110
122
|
<h1
|
|
111
123
|
style={{
|
|
112
124
|
fontSize: 22,
|
|
113
|
-
|
|
125
|
+
color: theme.primaryTextColor,
|
|
114
126
|
fontFamily: theme.fontFamily,
|
|
115
127
|
fontWeight: 'bold',
|
|
116
128
|
// fontWeight: theme.headerFontWeight,
|
|
@@ -124,61 +136,60 @@ export default function Dashboard({
|
|
|
124
136
|
</h1>
|
|
125
137
|
)}
|
|
126
138
|
</div>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// onClick={() => handleEditDashboardItem(elem)}
|
|
165
|
-
// className="shadow"
|
|
166
|
-
style={{
|
|
167
|
-
// background: theme.elevatedCardColor,
|
|
168
|
-
// borderRadius: theme.borderRadius,
|
|
169
|
-
// boxShadow: theme.boxShadow,
|
|
170
|
-
height: '100%',
|
|
171
|
-
cursor: 'pointer',
|
|
172
|
-
width: '100%',
|
|
173
|
-
}}
|
|
174
|
-
>
|
|
139
|
+
{dashboardSections[section].filter(
|
|
140
|
+
elem => elem.chartType === 'metric'
|
|
141
|
+
).length ? (
|
|
142
|
+
<div
|
|
143
|
+
style={{
|
|
144
|
+
width: `100%`,
|
|
145
|
+
listStyleType: 'none',
|
|
146
|
+
marginBottom: 50,
|
|
147
|
+
display: 'grid',
|
|
148
|
+
gridGap: 25,
|
|
149
|
+
gridTemplateColumns: `repeat(auto-fill,minmax(${
|
|
150
|
+
maxColumnWidth || 400
|
|
151
|
+
}px, 1fr))`,
|
|
152
|
+
// gridTemplateRows: `repeat(${170}px)`,
|
|
153
|
+
}}
|
|
154
|
+
>
|
|
155
|
+
{dashboardSections[section]
|
|
156
|
+
.filter(elem => elem.chartType === 'metric')
|
|
157
|
+
.map(
|
|
158
|
+
(
|
|
159
|
+
elem: {
|
|
160
|
+
name:
|
|
161
|
+
| string
|
|
162
|
+
| number
|
|
163
|
+
| boolean
|
|
164
|
+
| React.ReactElement<
|
|
165
|
+
any,
|
|
166
|
+
string | React.JSXElementConstructor<any>
|
|
167
|
+
>
|
|
168
|
+
| React.ReactFragment
|
|
169
|
+
| null
|
|
170
|
+
| undefined;
|
|
171
|
+
_id: string | undefined;
|
|
172
|
+
},
|
|
173
|
+
index: string
|
|
174
|
+
) => {
|
|
175
|
+
return (
|
|
175
176
|
<div
|
|
177
|
+
onClick={() => handleOnClickDashboardItem(elem._id)}
|
|
178
|
+
className="hover:bg-zinc-50"
|
|
179
|
+
key={elem.name + '' + index}
|
|
176
180
|
style={{
|
|
177
|
-
|
|
181
|
+
// background: theme.elevatedCardColor,
|
|
182
|
+
// borderRadius: theme.borderRadius,
|
|
183
|
+
// boxShadow: theme.boxShadow,
|
|
184
|
+
paddingTop: 12,
|
|
185
|
+
borderRadius: 8,
|
|
178
186
|
height: '100%',
|
|
187
|
+
cursor: 'pointer',
|
|
188
|
+
width: '100%',
|
|
179
189
|
}}
|
|
180
190
|
>
|
|
181
191
|
<div
|
|
192
|
+
// className="group-hover:bg-black"
|
|
182
193
|
style={{
|
|
183
194
|
width: '100%',
|
|
184
195
|
height: '100%',
|
|
@@ -186,68 +197,94 @@ export default function Dashboard({
|
|
|
186
197
|
>
|
|
187
198
|
<div
|
|
188
199
|
style={{
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
justifyContent: 'space-between',
|
|
200
|
+
width: '100%',
|
|
201
|
+
height: '100%',
|
|
192
202
|
}}
|
|
193
203
|
>
|
|
194
204
|
<div
|
|
195
205
|
style={{
|
|
196
206
|
display: 'flex',
|
|
197
|
-
flexDirection: '
|
|
207
|
+
flexDirection: 'column',
|
|
198
208
|
justifyContent: 'space-between',
|
|
199
|
-
// alignItems: 'center',
|
|
200
|
-
// paddingLeft: theme.padding,
|
|
201
|
-
// paddingRight: theme.padding,
|
|
202
|
-
// paddingTop: theme.padding,
|
|
203
209
|
}}
|
|
204
210
|
>
|
|
205
211
|
<div
|
|
212
|
+
// className="group-hover:bg-black"
|
|
206
213
|
style={{
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
//
|
|
214
|
-
textOverflow: 'ellipsis',
|
|
215
|
-
margin: 0,
|
|
216
|
-
marginLeft: 25,
|
|
217
|
-
padding: 0,
|
|
218
|
-
whiteSpace: 'nowrap',
|
|
219
|
-
display: 'block',
|
|
220
|
-
maxWidth: '100%',
|
|
221
|
-
overflow: 'hidden',
|
|
214
|
+
display: 'flex',
|
|
215
|
+
flexDirection: 'row',
|
|
216
|
+
justifyContent: 'space-between',
|
|
217
|
+
// alignItems: 'center',
|
|
218
|
+
// paddingLeft: theme.padding,
|
|
219
|
+
paddingRight: 25,
|
|
220
|
+
// paddingTop: theme.padding,
|
|
222
221
|
}}
|
|
223
222
|
>
|
|
224
|
-
|
|
223
|
+
<div
|
|
224
|
+
title={elem.name}
|
|
225
|
+
style={{
|
|
226
|
+
fontFamily: theme.fontFamily,
|
|
227
|
+
color: theme.primaryTextColor,
|
|
228
|
+
// TODO: FIX SIZE
|
|
229
|
+
fontSize: 18,
|
|
230
|
+
// TODO: FIX WEIGHT
|
|
231
|
+
fontWeight: '500',
|
|
232
|
+
// fontSize: theme.headerFontSize,
|
|
233
|
+
// color: theme.fontColor,
|
|
234
|
+
// fontWeight: theme.headerFontWeight,
|
|
235
|
+
textOverflow: 'ellipsis',
|
|
236
|
+
// margin: 0,
|
|
237
|
+
marginLeft: 25,
|
|
238
|
+
padding: 0,
|
|
239
|
+
whiteSpace: 'nowrap',
|
|
240
|
+
display: 'block',
|
|
241
|
+
maxWidth: '100%',
|
|
242
|
+
overflow: 'hidden',
|
|
243
|
+
}}
|
|
244
|
+
>
|
|
245
|
+
{elem.name}
|
|
246
|
+
</div>
|
|
247
|
+
<div
|
|
248
|
+
// className="hover:bg-black"
|
|
249
|
+
style={{
|
|
250
|
+
fontFamily: theme.fontFamily,
|
|
251
|
+
color: theme.primaryTextColor,
|
|
252
|
+
fontWeight: '500',
|
|
253
|
+
fontSize: 14,
|
|
254
|
+
minWidth: 14 * 7,
|
|
255
|
+
// background: 'red',
|
|
256
|
+
display: 'flex',
|
|
257
|
+
alignItems: 'center',
|
|
258
|
+
justifyContent: 'flex-end',
|
|
259
|
+
}}
|
|
260
|
+
>
|
|
261
|
+
{'view report →'}
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
{/* <div style={{ height: 20 }} /> */}
|
|
265
|
+
<div style={{ padding: 0 }}>
|
|
266
|
+
<Chart
|
|
267
|
+
containerStyle={{
|
|
268
|
+
display: 'flex',
|
|
269
|
+
width: '100%',
|
|
270
|
+
height: 120,
|
|
271
|
+
marginBottom: 50,
|
|
272
|
+
marginTop: 20,
|
|
273
|
+
}}
|
|
274
|
+
chartId={elem._id}
|
|
275
|
+
colors={['#6269E9', '#E14F62']}
|
|
276
|
+
// updateDashboard={updateDashboard}
|
|
277
|
+
/>
|
|
225
278
|
</div>
|
|
226
|
-
{/* <Arrow fill={theme.fontColor} /> */}
|
|
227
|
-
</div>
|
|
228
|
-
{/* <div style={{ height: 20 }} /> */}
|
|
229
|
-
<div style={{ padding: 0 }}>
|
|
230
|
-
<Chart
|
|
231
|
-
containerStyle={{
|
|
232
|
-
display: 'flex',
|
|
233
|
-
width: '100%',
|
|
234
|
-
height: 120,
|
|
235
|
-
marginBottom: 50,
|
|
236
|
-
marginTop: 20,
|
|
237
|
-
}}
|
|
238
|
-
chartId={elem._id}
|
|
239
|
-
colors={['#6269E9', '#E14F62']}
|
|
240
|
-
// updateDashboard={updateDashboard}
|
|
241
|
-
/>
|
|
242
279
|
</div>
|
|
243
280
|
</div>
|
|
244
281
|
</div>
|
|
245
282
|
</div>
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
)}
|
|
286
|
+
</div>
|
|
287
|
+
) : null}
|
|
251
288
|
<div
|
|
252
289
|
style={{
|
|
253
290
|
width: `100%`,
|
|
@@ -282,6 +319,8 @@ export default function Dashboard({
|
|
|
282
319
|
) => {
|
|
283
320
|
return (
|
|
284
321
|
<div
|
|
322
|
+
onClick={() => handleOnClickDashboardItem(elem._id)}
|
|
323
|
+
className="hover:bg-zinc-50"
|
|
285
324
|
// className="shadow-md"
|
|
286
325
|
key={elem.name + '' + index}
|
|
287
326
|
// onClick={() => handleEditDashboardItem(elem)}
|
|
@@ -293,6 +332,9 @@ export default function Dashboard({
|
|
|
293
332
|
height: '100%',
|
|
294
333
|
cursor: 'pointer',
|
|
295
334
|
width: '100%',
|
|
335
|
+
paddingRight: 25,
|
|
336
|
+
borderRadius: 8,
|
|
337
|
+
paddingTop: 20,
|
|
296
338
|
}}
|
|
297
339
|
>
|
|
298
340
|
<div
|
|
@@ -328,14 +370,14 @@ export default function Dashboard({
|
|
|
328
370
|
<div
|
|
329
371
|
style={{
|
|
330
372
|
fontFamily: theme.fontFamily,
|
|
331
|
-
color:
|
|
373
|
+
color: theme.primaryTextColor,
|
|
332
374
|
fontSize: 18,
|
|
333
375
|
fontWeight: '500',
|
|
334
376
|
// fontSize: theme.headerFontSize,
|
|
335
377
|
// color: theme.fontColor,
|
|
336
378
|
// fontWeight: theme.headerFontWeight,
|
|
337
379
|
textOverflow: 'ellipsis',
|
|
338
|
-
margin: 0,
|
|
380
|
+
// margin: 0,
|
|
339
381
|
marginLeft: 25,
|
|
340
382
|
padding: 0,
|
|
341
383
|
whiteSpace: 'nowrap',
|
|
@@ -346,6 +388,22 @@ export default function Dashboard({
|
|
|
346
388
|
>
|
|
347
389
|
{elem.name}
|
|
348
390
|
</div>
|
|
391
|
+
<div
|
|
392
|
+
// className="hover:bg-black"
|
|
393
|
+
style={{
|
|
394
|
+
fontFamily: theme.fontFamily,
|
|
395
|
+
color: theme.primaryTextColor,
|
|
396
|
+
fontWeight: '500',
|
|
397
|
+
fontSize: 14,
|
|
398
|
+
minWidth: 14 * 7,
|
|
399
|
+
// background: 'red',
|
|
400
|
+
display: 'flex',
|
|
401
|
+
alignItems: 'center',
|
|
402
|
+
justifyContent: 'flex-end',
|
|
403
|
+
}}
|
|
404
|
+
>
|
|
405
|
+
{'view report →'}
|
|
406
|
+
</div>
|
|
349
407
|
{/* <Arrow fill={theme.fontColor} /> */}
|
|
350
408
|
</div>
|
|
351
409
|
{/* <div style={{ height: 20 }} /> */}
|