@quillsql/react 1.6.6 → 1.6.7

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.
@@ -33,8 +33,9 @@ export interface QuillTheme {
33
33
  chartTickColor: string;
34
34
  chartColors: string[];
35
35
  borderColor: string;
36
- primaryButtonColor: string;
36
+ primaryButtonColor?: string;
37
37
  borderWidth: number;
38
+ buttonFontWeight?: number;
38
39
  }
39
40
 
40
41
  const defaultTheme = {
@@ -1,7 +1,6 @@
1
1
  import React, { useState, useContext, useCallback, useEffect } from 'react';
2
2
  // import './nightOwlLight.css';
3
3
  import axios from 'axios';
4
- import { TailSpin } from 'react-loader-spinner';
5
4
  import { ClientContext, SchemaContext, ThemeContext } from './Context';
6
5
  import {
7
6
  ChevronDownIcon,
@@ -55,14 +54,40 @@ interface ReportBuilderProps {
55
54
  onChangeColumns: (columns: object[]) => void;
56
55
  onChangeLoading: (loading: boolean) => void;
57
56
  onError: (error: string) => void;
58
- SelectComponent: (props: SelectComponentProps) => JSX.Element;
59
- ButtonComponent: (props: ButtonComponentProps) => JSX.Element;
60
- ModalComponent: (props: ModalComponentProps) => JSX.Element;
61
- ModalTriggerComponent: (props: ModalTriggerComponentProps) => JSX.Element;
62
- TextInputComponent: (props: TextInputComponentProps) => JSX.Element;
57
+ SelectComponent?: (props: SelectComponentProps) => JSX.Element;
58
+ ButtonComponent?: (props: ButtonComponentProps) => JSX.Element;
59
+ ModalComponent?: (props: ModalComponentProps) => JSX.Element;
60
+ ModalTriggerComponent?: (props: ModalTriggerComponentProps) => JSX.Element;
61
+ TextInputComponent?: (props: TextInputComponentProps) => JSX.Element;
63
62
  tagStyle: React.CSSProperties;
64
63
  }
65
64
 
65
+ function QuillModal({ children, isOpen, onClose, title, theme }) {
66
+ if (!isOpen) {
67
+ return null;
68
+ }
69
+ return (
70
+ <div
71
+ style={{
72
+ position: 'absolute',
73
+ top: 45,
74
+ minWidth: 300,
75
+ left: 0,
76
+ backgroundColor: theme.backgroundColor || 'white',
77
+ padding: '20px',
78
+ zIndex: '1000',
79
+ borderRadius: 8,
80
+ boxShadow: '0 1px 8px 0 rgba(0,0,0,.09)',
81
+ borderWidth: theme.borderWidth,
82
+ borderStyle: 'solid',
83
+ borderColor: theme.borderColor,
84
+ }}
85
+ >
86
+ {children}
87
+ </div>
88
+ );
89
+ }
90
+
66
91
  export default function ReportBuilder({
67
92
  onChangeQuery,
68
93
  onChangeData,
@@ -193,11 +218,152 @@ export default function ReportBuilder({
193
218
  schema={schema}
194
219
  onChangeQuery={onChangeQuery}
195
220
  runQuery={runQuery}
196
- SelectComponent={SelectComponent}
197
- ButtonComponent={ButtonComponent}
198
- ModalComponent={ModalComponent}
199
- ModalTriggerComponent={ModalTriggerComponent}
200
- TextInputComponent={TextInputComponent}
221
+ SelectComponent={
222
+ SelectComponent
223
+ ? SelectComponent
224
+ : ({ onChange, value, options }: SelectComponentProps) => {
225
+ return (
226
+ <select
227
+ onChange={event => onChange(event.target.value)}
228
+ value={value}
229
+ id={'reportbuilderdropdown'}
230
+ style={{
231
+ width: '100%',
232
+ minWidth: 230,
233
+ outline: 'none',
234
+ textAlign: 'left',
235
+ whiteSpace: 'nowrap',
236
+ overflow: 'hidden',
237
+ textOverflow: 'ellipsis',
238
+ borderRadius: 6,
239
+ paddingLeft: 12,
240
+ paddingRight: 12,
241
+ height: 38,
242
+ borderWidth: theme.borderWidth,
243
+ borderColor: theme.borderColor,
244
+ background: theme.backgroundColor,
245
+ color: theme.primaryTextColor,
246
+ boxShadow: '0 1px 2px 0 rgba(0,0,0,.05)',
247
+ fontFamily: theme.fontFamily,
248
+ }}
249
+ >
250
+ {options.map((option, index) => (
251
+ <option key={option.label + index} value={option.value}>
252
+ {option.label}
253
+ </option>
254
+ ))}
255
+ </select>
256
+ );
257
+ }
258
+ }
259
+ ButtonComponent={
260
+ ButtonComponent
261
+ ? ButtonComponent
262
+ : ({ onClick, label }: ButtonComponentProps) => {
263
+ return (
264
+ <div
265
+ style={{
266
+ height: 32,
267
+ background: theme.primaryButtonColor,
268
+ borderWidth: theme.borderWidth,
269
+ borderColor: theme.borderColor,
270
+ color: theme.backgroundColor,
271
+ display: 'flex',
272
+ borderRadius: 6,
273
+ alignItems: 'center',
274
+ justifyContent: 'center',
275
+ outline: 'none',
276
+ cursor: 'pointer',
277
+ fontFamily: theme.fontFamily,
278
+ fontWeight: theme.buttonFontWeight || 600,
279
+ }}
280
+ onClick={onClick}
281
+ >
282
+ {label}
283
+ </div>
284
+ );
285
+ }
286
+ }
287
+ ModalComponent={
288
+ ModalComponent
289
+ ? ModalComponent
290
+ : ({ children, isOpen, onClose, title }: ModalComponentProps) => {
291
+ return (
292
+ <QuillModal
293
+ isOpen={isOpen}
294
+ theme={theme}
295
+ onClose={onClose}
296
+ title={title}
297
+ >
298
+ {children}
299
+ </QuillModal>
300
+ );
301
+ }
302
+ }
303
+ ModalTriggerComponent={
304
+ ModalTriggerComponent
305
+ ? ModalTriggerComponent
306
+ : ({ onClick, label }: ModalTriggerComponentProps) => {
307
+ return (
308
+ <div
309
+ style={{
310
+ height: 32,
311
+ background: theme.backgroundColor,
312
+ borderWidth: theme.borderWidth,
313
+ borderColor: theme.borderColor,
314
+ borderStyle: 'solid',
315
+ outline: 'none',
316
+ cursor: 'pointer',
317
+ display: 'flex',
318
+ borderRadius: 6,
319
+ alignItems: 'center',
320
+ justifyContent: 'center',
321
+ boxShadow: '0 1px 2px 0 rgba(0,0,0,.05)',
322
+ paddingRight: 12,
323
+ paddingLeft: 12,
324
+ fontSize: 14,
325
+ color: theme.primaryTextColor,
326
+ fontWeight: theme.buttonFontWeight || 600,
327
+ fontFamily: theme.fontFamily,
328
+ }}
329
+ onClick={onClick}
330
+ >
331
+ {label}
332
+ </div>
333
+ );
334
+ }
335
+ }
336
+ TextInputComponent={
337
+ TextInputComponent
338
+ ? TextInputComponent
339
+ : ({ onChange, value, id }: TextInputComponentProps) => {
340
+ return (
341
+ <input
342
+ style={{
343
+ outline: 'none',
344
+ textAlign: 'left',
345
+ whiteSpace: 'nowrap',
346
+ overflow: 'hidden',
347
+ textOverflow: 'ellipsis',
348
+ borderRadius: 6,
349
+ paddingLeft: 12,
350
+ paddingRight: 12,
351
+ height: 38,
352
+ borderWidth: theme.borderWidth,
353
+ borderColor: theme.borderColor,
354
+ borderStyle: 'solid',
355
+ background: theme.backgroundColor,
356
+ color: theme.primaryTextColor,
357
+ boxShadow: '0 1px 2px 0 rgba(0,0,0,.05)',
358
+ fontFamily: theme.fontFamily,
359
+ }}
360
+ id={id}
361
+ onChange={onChange}
362
+ value={value}
363
+ />
364
+ );
365
+ }
366
+ }
201
367
  tagStyle={tagStyle}
202
368
  />
203
369
  );
@@ -694,7 +860,7 @@ function ReportingTool({
694
860
  // USE EFFECT HOOK THAT TRANSFORMS "FILTERS ARRAY INTO AST"
695
861
  useEffect(() => {
696
862
  if (filters.length || groupBys.length || aggregations.length) {
697
- let newAST = {
863
+ const newAST = {
698
864
  with: null,
699
865
  type: 'select',
700
866
  options: null,
@@ -1301,13 +1467,11 @@ const SortByModal = ({
1301
1467
  return (
1302
1468
  <div style={{ display: 'flex', flexDirection: 'column', marginTop: 12 }}>
1303
1469
  <div
1304
- style={
1305
- {
1306
- // position: 'relative',
1307
- // display: 'inline-block',
1308
- // textAlign: 'left',
1309
- }
1310
- }
1470
+ style={{
1471
+ position: 'relative',
1472
+ display: 'inline-block',
1473
+ textAlign: 'left',
1474
+ }}
1311
1475
  >
1312
1476
  <div
1313
1477
  style={{
@@ -1318,7 +1482,7 @@ const SortByModal = ({
1318
1482
  >
1319
1483
  <ModalTriggerComponent
1320
1484
  onClick={() => setIsOpen(isOpen => !isOpen)}
1321
- label="Add sort +"
1485
+ label="Sort"
1322
1486
  />
1323
1487
  <div
1324
1488
  style={{
@@ -1467,173 +1631,183 @@ const GroupByModal2 = ({
1467
1631
  <div style={{ display: 'flex', flexDirection: 'column' }}>
1468
1632
  <div
1469
1633
  style={{
1470
- display: 'flex',
1471
- flexDirection: 'row',
1472
- alignItems: 'center',
1634
+ position: 'relative',
1635
+ display: 'inline-block',
1636
+ textAlign: 'left',
1473
1637
  }}
1474
1638
  >
1475
- <ModalTriggerComponent
1476
- onClick={() => setIsOpen(isOpen => !isOpen)}
1477
- label="Add group by +"
1478
- />
1479
1639
  <div
1480
1640
  style={{
1481
- overflowX: 'scroll',
1482
1641
  display: 'flex',
1483
1642
  flexDirection: 'row',
1484
1643
  alignItems: 'center',
1485
1644
  }}
1486
1645
  >
1487
- {groupBys.map((elem, index) => (
1488
- <FilterTag
1489
- id="group-tag"
1490
- label={elem.tag}
1491
- removeFilter={removeGroupBy}
1492
- selectFilter={selectGroupBy}
1493
- setIsOpen={setIsOpen}
1494
- index={index}
1495
- theme={theme}
1496
- tagStyle={tagStyle}
1497
- key={'groupby' + index}
1498
- />
1499
- ))}
1646
+ <ModalTriggerComponent
1647
+ onClick={() => setIsOpen(isOpen => !isOpen)}
1648
+ label="Group by"
1649
+ />
1650
+ <div
1651
+ style={{
1652
+ overflowX: 'scroll',
1653
+ display: 'flex',
1654
+ flexDirection: 'row',
1655
+ alignItems: 'center',
1656
+ }}
1657
+ >
1658
+ {groupBys.map((elem, index) => (
1659
+ <FilterTag
1660
+ id="group-tag"
1661
+ label={elem.tag}
1662
+ removeFilter={removeGroupBy}
1663
+ selectFilter={selectGroupBy}
1664
+ setIsOpen={setIsOpen}
1665
+ index={index}
1666
+ theme={theme}
1667
+ tagStyle={tagStyle}
1668
+ key={'groupby' + index}
1669
+ />
1670
+ ))}
1671
+ </div>
1500
1672
  </div>
1501
- </div>
1502
- <ModalComponent
1503
- isOpen={isOpen}
1504
- onClose={() => setIsOpen(false)}
1505
- title="Add group by"
1506
- >
1507
- <div style={{ display: 'flex', flexDirection: 'column' }}>
1673
+ <ModalComponent
1674
+ isOpen={isOpen}
1675
+ onClose={() => setIsOpen(false)}
1676
+ title="Add group by"
1677
+ >
1508
1678
  <div style={{ display: 'flex', flexDirection: 'column' }}>
1509
- {/* select column */}
1510
- <div
1511
- style={{
1512
- fontSize: '14px',
1513
- marginBottom: '6px',
1514
- fontWeight: '600',
1515
- fontFamily: theme?.fontFamily,
1516
- color: theme.secondaryTextColor,
1517
- }}
1518
- >
1519
- Column
1520
- </div>
1521
- <SelectComponent
1522
- label="Column"
1523
- value={selectedGroupByColumn.name}
1524
- onChange={e => {
1525
- const column = selectedTable.columns.find(c => c.name === e);
1526
- setSelectedGroupByColumn(column);
1527
- }}
1528
- options={selectedTable.columns.map(elem => {
1529
- return { label: elem.name, value: elem.name };
1530
- })}
1531
- />
1532
- </div>
1533
- {groupByColumnType === 'date' && (
1534
- <div
1535
- style={{
1536
- display: 'flex',
1537
- flexDirection: 'column',
1538
- // marginLeft: 12,
1539
- }}
1540
- >
1679
+ <div style={{ display: 'flex', flexDirection: 'column' }}>
1680
+ {/* select column */}
1541
1681
  <div
1542
1682
  style={{
1543
1683
  fontSize: '14px',
1544
1684
  marginBottom: '6px',
1545
1685
  fontWeight: '600',
1546
- color: theme.secondaryTextColor,
1547
1686
  fontFamily: theme?.fontFamily,
1548
- marginTop: 20,
1687
+ color: theme.secondaryTextColor,
1549
1688
  }}
1550
1689
  >
1551
- Bucket
1690
+ Column
1552
1691
  </div>
1553
1692
  <SelectComponent
1554
- label="Bucket"
1555
- value={dateBucket}
1693
+ label="Column"
1694
+ value={selectedGroupByColumn.name}
1556
1695
  onChange={e => {
1557
- setDateBucket(e);
1696
+ const column = selectedTable.columns.find(c => c.name === e);
1697
+ setSelectedGroupByColumn(column);
1558
1698
  }}
1559
- options={[
1560
- { label: 'month', value: 'month' },
1561
- { label: 'day', value: 'day' },
1562
- { label: 'week', value: 'week' },
1563
- ]}
1699
+ options={selectedTable.columns.map(elem => {
1700
+ return { label: elem.name, value: elem.name };
1701
+ })}
1564
1702
  />
1565
1703
  </div>
1566
- )}
1567
- {/* Select bucket (if date) */}
1704
+ {groupByColumnType === 'date' && (
1705
+ <div
1706
+ style={{
1707
+ display: 'flex',
1708
+ flexDirection: 'column',
1709
+ // marginLeft: 12,
1710
+ }}
1711
+ >
1712
+ <div
1713
+ style={{
1714
+ fontSize: '14px',
1715
+ marginBottom: '6px',
1716
+ fontWeight: '600',
1717
+ color: theme.secondaryTextColor,
1718
+ fontFamily: theme?.fontFamily,
1719
+ marginTop: 20,
1720
+ }}
1721
+ >
1722
+ Bucket
1723
+ </div>
1724
+ <SelectComponent
1725
+ label="Bucket"
1726
+ value={dateBucket}
1727
+ onChange={e => {
1728
+ setDateBucket(e);
1729
+ }}
1730
+ options={[
1731
+ { label: 'month', value: 'month' },
1732
+ { label: 'day', value: 'day' },
1733
+ { label: 'week', value: 'week' },
1734
+ ]}
1735
+ />
1736
+ </div>
1737
+ )}
1738
+ {/* Select bucket (if date) */}
1568
1739
 
1569
- {/* Select aggregations */}
1570
- <div
1571
- style={{
1572
- fontSize: 14,
1573
- marginBottom: '6px',
1574
- fontWeight: '600',
1575
- marginTop: 20,
1576
- color: theme.secondaryTextColor,
1577
- fontFamily: theme?.fontFamily,
1578
- }}
1579
- >
1580
- Aggregations
1581
- </div>
1582
- {/* select column */}
1583
- {aggregations.map((aggregation, index) => (
1584
- // setAggregationType
1740
+ {/* Select aggregations */}
1585
1741
  <div
1586
- key={'agg' + index}
1587
1742
  style={{
1588
- display: 'flex',
1589
- flexDirection: 'row',
1590
- alignItems: 'center',
1743
+ fontSize: 14,
1744
+ marginBottom: '6px',
1745
+ fontWeight: '600',
1746
+ marginTop: 20,
1747
+ color: theme.secondaryTextColor,
1748
+ fontFamily: theme?.fontFamily,
1591
1749
  }}
1592
1750
  >
1593
- <SelectComponent
1594
- value={aggregation.column?.name}
1595
- onChange={e => {
1596
- const column = selectedTable.columns.find(c => c.name === e);
1597
- setAggregationColumn(column, index);
1598
- }}
1599
- options={selectedTable.columns.map(elem => {
1600
- return { label: elem.name, value: elem.name };
1601
- })}
1602
- />
1603
- <div style={{ width: 16 }} />
1604
- <SelectComponent
1605
- value={aggregation.aggregationType}
1606
- onChange={e => {
1607
- setAggregationType(e, index);
1608
- }}
1609
- options={[
1610
- { label: 'sum', value: 'sum' },
1611
- { label: 'average', value: 'average' },
1612
- { label: 'count', value: 'count' },
1613
- ]}
1614
- />
1751
+ Aggregations
1615
1752
  </div>
1616
- ))}
1617
- <div style={{ height: 20 }} />
1618
- <ButtonComponent
1619
- id="custom-button"
1620
- onClick={() => {
1621
- if (groupByIndexBeingEdited > -1) {
1622
- updateGroupBy(groupByIndexBeingEdited);
1753
+ {/* select column */}
1754
+ {aggregations.map((aggregation, index) => (
1755
+ // setAggregationType
1756
+ <div
1757
+ key={'agg' + index}
1758
+ style={{
1759
+ display: 'flex',
1760
+ flexDirection: 'row',
1761
+ alignItems: 'center',
1762
+ }}
1763
+ >
1764
+ <SelectComponent
1765
+ value={aggregation.column?.name}
1766
+ onChange={e => {
1767
+ const column = selectedTable.columns.find(
1768
+ c => c.name === e
1769
+ );
1770
+ setAggregationColumn(column, index);
1771
+ }}
1772
+ options={selectedTable.columns.map(elem => {
1773
+ return { label: elem.name, value: elem.name };
1774
+ })}
1775
+ />
1776
+ <div style={{ width: 16 }} />
1777
+ <SelectComponent
1778
+ value={aggregation.aggregationType}
1779
+ onChange={e => {
1780
+ setAggregationType(e, index);
1781
+ }}
1782
+ options={[
1783
+ { label: 'sum', value: 'sum' },
1784
+ { label: 'average', value: 'average' },
1785
+ { label: 'count', value: 'count' },
1786
+ ]}
1787
+ />
1788
+ </div>
1789
+ ))}
1790
+ <div style={{ height: 20 }} />
1791
+ <ButtonComponent
1792
+ id="custom-button"
1793
+ onClick={() => {
1794
+ if (groupByIndexBeingEdited > -1) {
1795
+ updateGroupBy(groupByIndexBeingEdited);
1796
+ setIsOpen(false);
1797
+ // close();
1798
+ return;
1799
+ }
1800
+ addGroupBy();
1623
1801
  setIsOpen(false);
1624
1802
  // close();
1625
- return;
1803
+ }}
1804
+ label={
1805
+ groupByIndexBeingEdited > -1 ? 'Edit group by' : 'Add group by'
1626
1806
  }
1627
- addGroupBy();
1628
- setIsOpen(false);
1629
- // close();
1630
- }}
1631
- label={
1632
- groupByIndexBeingEdited > -1 ? 'Edit group by' : 'Add group by'
1633
- }
1634
- />
1635
- </div>
1636
- </ModalComponent>
1807
+ />
1808
+ </div>
1809
+ </ModalComponent>
1810
+ </div>
1637
1811
  </div>
1638
1812
  );
1639
1813
  };
@@ -1688,7 +1862,7 @@ const AddFilterModal2 = ({
1688
1862
  >
1689
1863
  <ModalTriggerComponent
1690
1864
  onClick={() => setIsOpen(isOpen => !isOpen)}
1691
- label="Add filter +"
1865
+ label="Filter"
1692
1866
  />
1693
1867
  <div
1694
1868
  style={{