@quillsql/react 1.7.4 → 1.7.6

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 (86) hide show
  1. package/lib/AddToDashboardModal.js +2 -2
  2. package/lib/AddToDashboardModal.js.map +1 -1
  3. package/lib/Chart.js +2 -2
  4. package/lib/Chart.js.map +1 -1
  5. package/lib/Context.d.ts +2 -1
  6. package/lib/Context.js +3 -1
  7. package/lib/Context.js.map +1 -1
  8. package/lib/Dashboard.js +2 -2
  9. package/lib/Dashboard.js.map +1 -1
  10. package/lib/QuillProvider.d.ts +2 -1
  11. package/lib/QuillProvider.js +2 -2
  12. package/lib/QuillProvider.js.map +1 -1
  13. package/lib/ReportBuilder.d.ts +1 -1
  14. package/lib/ReportBuilder.js +3 -2
  15. package/lib/ReportBuilder.js.map +1 -1
  16. package/lib/SQLEditor.js +5 -5
  17. package/lib/SQLEditor.js.map +1 -1
  18. package/lib/Table.js +1 -1
  19. package/lib/Table.js.map +1 -1
  20. package/lib/components/BigModal/BigModal.js +1 -0
  21. package/lib/components/BigModal/BigModal.js.map +1 -1
  22. package/lib/components/Modal/Modal.js +1 -0
  23. package/lib/components/Modal/Modal.js.map +1 -1
  24. package/lib/hooks/useQuill.js +3 -2
  25. package/lib/hooks/useQuill.js.map +1 -1
  26. package/package.json +11 -4
  27. package/.eslintrc.json +0 -19
  28. package/.prettierrc +0 -11
  29. package/.vscode/settings.json +0 -10
  30. package/src/AddToDashboardModal.tsx +0 -1213
  31. package/src/BarList.tsx +0 -580
  32. package/src/Chart.tsx +0 -1336
  33. package/src/Context.tsx +0 -249
  34. package/src/Dashboard.tsx +0 -819
  35. package/src/DateRangePicker/Calendar.tsx +0 -442
  36. package/src/DateRangePicker/DateRangePicker.tsx +0 -261
  37. package/src/DateRangePicker/DateRangePickerButton.tsx +0 -250
  38. package/src/DateRangePicker/dateRangePickerUtils.tsx +0 -480
  39. package/src/DateRangePicker/index.ts +0 -4
  40. package/src/PieChart.tsx +0 -845
  41. package/src/QuillProvider.tsx +0 -78
  42. package/src/ReportBuilder.tsx +0 -2202
  43. package/src/SQLEditor.tsx +0 -1087
  44. package/src/Table.tsx +0 -1074
  45. package/src/TableChart.tsx +0 -428
  46. package/src/assets/ArrowDownHeadIcon.tsx +0 -11
  47. package/src/assets/ArrowDownIcon.tsx +0 -14
  48. package/src/assets/ArrowDownRightIcon.tsx +0 -14
  49. package/src/assets/ArrowLeftHeadIcon.tsx +0 -11
  50. package/src/assets/ArrowRightHeadIcon.tsx +0 -11
  51. package/src/assets/ArrowRightIcon.tsx +0 -14
  52. package/src/assets/ArrowUpHeadIcon.tsx +0 -11
  53. package/src/assets/ArrowUpIcon.tsx +0 -14
  54. package/src/assets/ArrowUpRightIcon.tsx +0 -14
  55. package/src/assets/CalendarIcon.tsx +0 -14
  56. package/src/assets/DoubleArrowLeftHeadIcon.tsx +0 -18
  57. package/src/assets/DoubleArrowRightHeadIcon.tsx +0 -20
  58. package/src/assets/ExclamationFilledIcon.tsx +0 -14
  59. package/src/assets/LoadingSpinner.tsx +0 -11
  60. package/src/assets/SearchIcon.tsx +0 -14
  61. package/src/assets/XCircleIcon.tsx +0 -14
  62. package/src/assets/index.ts +0 -16
  63. package/src/components/BigModal/BigModal.tsx +0 -108
  64. package/src/components/Dropdown/Dropdown.tsx +0 -169
  65. package/src/components/Dropdown/DropdownItem.tsx +0 -68
  66. package/src/components/Dropdown/index.ts +0 -2
  67. package/src/components/Modal/Modal.tsx +0 -132
  68. package/src/components/Modal/index.ts +0 -1
  69. package/src/components/selectUtils.ts +0 -60
  70. package/src/contexts/BaseColorContext.tsx +0 -5
  71. package/src/contexts/HoveredValueContext.tsx +0 -12
  72. package/src/contexts/RootStylesContext.tsx +0 -5
  73. package/src/contexts/SelectedValueContext.tsx +0 -13
  74. package/src/contexts/index.ts +0 -4
  75. package/src/hooks/index.ts +0 -4
  76. package/src/hooks/useInternalState.tsx +0 -18
  77. package/src/hooks/useOnClickOutside.tsx +0 -23
  78. package/src/hooks/useOnWindowResize.tsx +0 -17
  79. package/src/hooks/useQuill.ts +0 -137
  80. package/src/hooks/useSelectOnKeyDown.tsx +0 -80
  81. package/src/index.ts +0 -9
  82. package/src/lib/font.ts +0 -14
  83. package/src/lib/index.ts +0 -3
  84. package/src/lib/inputTypes.ts +0 -81
  85. package/src/lib/utils.tsx +0 -46
  86. package/tsconfig.json +0 -22
package/src/Dashboard.tsx DELETED
@@ -1,819 +0,0 @@
1
- /* eslint-disable @typescript-eslint/ban-ts-comment */
2
- // @ts-nocheck
3
- import React, { useContext, useEffect, useState, useRef } from 'react';
4
- import Chart from './Chart';
5
- import {
6
- ClientContext,
7
- DashboardContext,
8
- ThemeContext,
9
- DashboardFiltersContext,
10
- } from './Context';
11
- import { startOfToday, sub } from 'date-fns';
12
- import { DateRangePicker } from './DateRangePicker/index';
13
- import axios from 'axios/index';
14
- import Modal from './components/Modal/Modal';
15
- import { HoveredValueContext, SelectedValueContext } from './contexts';
16
- import { DropdownItem } from './components/Dropdown';
17
- import { ArrowDownHeadIcon } from './assets';
18
- import { useInternalState, useSelectOnKeyDown } from './hooks';
19
-
20
- interface DashboardProps {
21
- name?: string;
22
- containerStyle?: React.CSSProperties;
23
- maxColumnWidth?: number;
24
- rowHeight?: number;
25
- onClickDashboardItem?: (item: any) => void;
26
- hideDateFilter?: boolean;
27
- }
28
-
29
- // const theme = {
30
- // fontFamily: 'Inter; Helvetica',
31
- // primaryTextColor: '#212121',
32
- // secondaryTextColor: '#6C727F',
33
- // chartLabelColor: '#666666',
34
- // chartTickColor: '#CCCCCC',
35
- // chartColors: ['#6269E9', '#E14F62'],
36
- // };
37
-
38
- export default function Dashboard({
39
- name,
40
- containerStyle,
41
- maxColumnWidth,
42
- rowHeight,
43
- onClickDashboardItem,
44
- hideDateFilter,
45
- }: DashboardProps) {
46
- const [dashboardSections, setDashboardSections] = useState<any>(null);
47
- const { dashboard } = useContext(DashboardContext);
48
- const [client] = useContext(ClientContext);
49
- const [theme] =
50
- useContext<[QuillTheme, (theme: QuillTheme) => void]>(ThemeContext);
51
- const { dashboardFiltersDispatch } = useContext(DashboardFiltersContext);
52
- const [configFilters, setConfigFilters] = useState([]);
53
-
54
- React.useEffect(() => {
55
- async function getDashboards() {
56
- const {
57
- publicKey,
58
- customerId,
59
- environment,
60
- queryEndpoint,
61
- queryHeaders,
62
- } = client;
63
- try {
64
- // const response = await fetch(
65
- // `https://quill-344421.uc.r.appspot.com/dashsections/${publicKey}/${customerId}/${name}`
66
- // );
67
-
68
- if (queryEndpoint) {
69
- //&& queryHeaders
70
- // @ts-ignore
71
- const response = await axios.post(
72
- queryEndpoint,
73
- {
74
- metadata: { name, task: 'config' },
75
- },
76
- {
77
- headers: queryHeaders,
78
- }
79
- );
80
-
81
- if (response.status !== 200) {
82
- throw new Error(`HTTP error! Status: ${response.status}`);
83
- }
84
-
85
- setDashboardSections(response.data.sections);
86
- setConfigFilters(response.data.filters || []);
87
- return;
88
- }
89
-
90
- const response = await axios.get(
91
- 'https://quill-344421.uc.r.appspot.com/dashconfig',
92
- {
93
- params: {
94
- publicKey: publicKey,
95
- orgId: customerId,
96
- name: name,
97
- task: 'dashconfig',
98
- },
99
- headers: {
100
- environment: environment || undefined,
101
- },
102
- }
103
- );
104
-
105
- if (response.status !== 200) {
106
- throw new Error(`HTTP error! Status: ${response.status}`);
107
- }
108
-
109
- setDashboardSections(response.data.sections);
110
- setConfigFilters(response.data.filters || []);
111
- } catch (error) {
112
- console.error('Error fetching data:', error);
113
- }
114
- }
115
- getDashboards();
116
- }, [name]);
117
-
118
- useEffect(() => {
119
- // change to be set on the dashboard / section as default date range
120
- const filter = {
121
- startDate: sub(startOfToday(), { days: 90 }),
122
- endDate: new Date(),
123
- filterType: 'DATE_RANGE',
124
- };
125
- dashboardFiltersDispatch({
126
- type: 'ADD_DASHBOARD_FILTER',
127
- id: 'date_range',
128
- data: {
129
- ...filter,
130
- },
131
- });
132
- }, []);
133
-
134
- const handleOnClickDashboardItem = id => {
135
- if (dashboard[id]) {
136
- onClickDashboardItem(dashboard[id]);
137
- }
138
- };
139
-
140
- const onChangeDateFilter = dateFilter => {
141
- setGlobalDateFilter(dateFilter[0], dateFilter[1]);
142
- };
143
-
144
- const setGlobalDateFilter = (startDate, endDate) => {
145
- const filter = {
146
- startDate: startDate,
147
- endDate: endDate,
148
- filterType: 'DATE_RANGE',
149
- };
150
- dashboardFiltersDispatch({
151
- type: 'ADD_DASHBOARD_FILTER',
152
- id: 'date_range',
153
- data: {
154
- ...filter,
155
- },
156
- });
157
- };
158
-
159
- const onChangeFilter = (value, filter) => {
160
- dashboardFiltersDispatch({
161
- type: 'ADD_DASHBOARD_FILTER',
162
- id: 'date_range',
163
- data: {
164
- ...filter,
165
- selectedValue: filter.options.find(
166
- elem => elem[removeQuotes(filter.field)] === value[2]
167
- )[removeQuotes(filter.field)],
168
- },
169
- });
170
- };
171
-
172
- if (!dashboardSections) {
173
- return null;
174
- }
175
- return (
176
- <div style={containerStyle}>
177
- <div
178
- style={{
179
- display: 'flex',
180
- boxSizing: 'content-box',
181
- flexDirection: 'row',
182
- alignItems: 'center',
183
- }}
184
- >
185
- {!hideDateFilter ? (
186
- <div style={{ width: 420, marginBottom: 25, marginLeft: 25 }}>
187
- <div
188
- style={{
189
- marginBottom: 6,
190
- fontWeight: '600',
191
- color: theme.secondaryTextColor,
192
- fontFamily: theme.fontFamily,
193
- fontSize: 14,
194
- }}
195
- >
196
- Date
197
- </div>
198
- <DateRangePicker
199
- // change to be set on the dashboard / section as default date range
200
- defaultValue={[undefined, undefined, '90d']}
201
- onValueChange={onChangeDateFilter}
202
- theme={theme}
203
- />
204
- </div>
205
- ) : null}
206
- <div style={{ width: 280, marginBottom: 25, marginLeft: 25 }}>
207
- {configFilters.map((elem, index) => (
208
- <Filter
209
- key={'filter' + configFilters.field + index}
210
- onValueChange={value => onChangeFilter(value, elem)}
211
- defaultValue={[
212
- undefined,
213
- undefined,
214
- elem.options[removeQuotes(elem.field)],
215
- ]}
216
- theme={theme}
217
- filter={elem}
218
- />
219
- ))}
220
- </div>
221
- </div>
222
- {Object.keys(dashboardSections)
223
- .sort(function (a, b) {
224
- return a.length - b.length;
225
- })
226
- .map((section, sectionIndex) => {
227
- return (
228
- <div
229
- style={{
230
- width: '100%',
231
- display: 'flex',
232
- flexDirection: 'column',
233
- }}
234
- key={section + '' + sectionIndex}
235
- >
236
- <div style={{ display: 'flex', flexDirection: 'column' }}>
237
- <div style={{ height: sectionIndex > 0 ? 25 : 0 }} />
238
- {section && (
239
- <h1
240
- style={{
241
- fontSize: 22,
242
- color: theme.primaryTextColor,
243
- fontFamily: theme.fontFamily,
244
- fontWeight: 'bold',
245
- // fontWeight: theme.headerFontWeight,
246
- marginBottom: 16,
247
- marginLeft: 25,
248
- textAlign: 'left',
249
- marginTop: 12,
250
- }}
251
- >
252
- {section}
253
- </h1>
254
- )}
255
- </div>
256
- {dashboardSections[section].filter(
257
- elem => elem.chartType === 'metric'
258
- ).length ? (
259
- <div
260
- style={{
261
- boxSizing: 'content-box',
262
- width: `100%`,
263
- listStyleType: 'none',
264
- marginBottom: 50,
265
- display: 'grid',
266
- gridGap: 25,
267
- gridTemplateColumns: `repeat(auto-fill,minmax(${
268
- maxColumnWidth || 400
269
- }px, 1fr))`,
270
- gridTemplateRows: `repeat(${170}px)`,
271
- }}
272
- >
273
- {dashboardSections[section]
274
- .filter(elem => elem.chartType === 'metric')
275
- .map(
276
- (
277
- elem: {
278
- name:
279
- | string
280
- | number
281
- | boolean
282
- | React.ReactElement<
283
- any,
284
- string | React.JSXElementConstructor<any>
285
- >
286
- | React.ReactFragment
287
- | null
288
- | undefined;
289
- _id: string | undefined;
290
- },
291
- index: string
292
- ) => {
293
- return (
294
- <div
295
- onClick={
296
- onClickDashboardItem
297
- ? () => handleOnClickDashboardItem(elem._id)
298
- : undefined
299
- }
300
- // className={
301
- // onClickDashboardItem
302
- // ? 'hover:qq-bg-zinc-50'
303
- // : undefined
304
- // }
305
- key={elem.name + '' + index}
306
- style={{
307
- // background: theme.elevatedCardColor,
308
- // borderRadius: theme.borderRadius,
309
- // boxShadow: theme.boxShadow,
310
- paddingTop: 12,
311
- boxSizing: 'content-box',
312
- borderRadius: 8,
313
- height: '100%',
314
- cursor: 'pointer',
315
- width: '100%',
316
- }}
317
- >
318
- <div
319
- // className="group-hover:bg-black"
320
- style={{
321
- width: '100%',
322
- boxSizing: 'content-box',
323
- height: '100%',
324
- }}
325
- >
326
- <div
327
- style={{
328
- width: '100%',
329
- boxSizing: 'content-box',
330
- height: '100%',
331
- }}
332
- >
333
- <div
334
- style={{
335
- display: 'flex',
336
- flexDirection: 'column',
337
- justifyContent: 'space-between',
338
- boxSizing: 'content-box',
339
- }}
340
- >
341
- <div
342
- // className="group-hover:bg-black"
343
- style={{
344
- display: 'flex',
345
- flexDirection: 'row',
346
- justifyContent: 'space-between',
347
- boxSizing: 'content-box',
348
- // alignItems: 'center',
349
- // paddingLeft: theme.padding,
350
- paddingRight: 25,
351
- // paddingTop: theme.padding,
352
- }}
353
- >
354
- <div
355
- title={elem.name}
356
- style={{
357
- fontFamily: theme.fontFamily,
358
- color: theme.primaryTextColor,
359
- boxSizing: 'content-box',
360
- // TODO: FIX SIZE
361
- fontSize: 18,
362
- // TODO: FIX WEIGHT
363
- fontWeight: '500',
364
- // fontSize: theme.headerFontSize,
365
- // color: theme.fontColor,
366
- // fontWeight: theme.headerFontWeight,
367
- textOverflow: 'ellipsis',
368
- // margin: 0,
369
- marginLeft: 25,
370
- padding: 0,
371
- whiteSpace: 'nowrap',
372
- display: 'block',
373
- maxWidth: '100%',
374
- overflow: 'hidden',
375
- }}
376
- >
377
- {elem.name}
378
- </div>
379
- {onClickDashboardItem ? (
380
- <div
381
- // className="hover:bg-black"
382
- style={{
383
- fontFamily: theme.fontFamily,
384
- boxSizing: 'content-box',
385
- color: theme.primaryTextColor,
386
- fontWeight: '500',
387
- fontSize: 14,
388
- minWidth: 14 * 7,
389
- // background: 'red',
390
- display: 'flex',
391
- alignItems: 'center',
392
- justifyContent: 'flex-end',
393
- }}
394
- >
395
- {'view report →'}
396
- </div>
397
- ) : null}
398
- </div>
399
- {/* <div style={{ height: 20 }} /> */}
400
- <div style={{ padding: 0 }}>
401
- <Chart
402
- containerStyle={{
403
- display: 'flex',
404
- // width: '100%',
405
- height: 30,
406
- // marginBottom: 50,
407
- marginTop: 20,
408
- }}
409
- dateFilter={true}
410
- chartId={elem._id}
411
- query={elem.queryString}
412
- // colors={theme.chartColors}
413
- // updateDashboard={updateDashboard}
414
- />
415
- </div>
416
- </div>
417
- </div>
418
- </div>
419
- </div>
420
- );
421
- }
422
- )}
423
- </div>
424
- ) : null}
425
- <div
426
- style={{
427
- // width: `100%`,
428
- listStyleType: 'none',
429
- display: 'grid',
430
- gridGap: 25,
431
- boxSizing: 'content-box',
432
- gridTemplateColumns: `repeat(auto-fill,minmax(${
433
- maxColumnWidth || 400
434
- }px, 1fr))`,
435
- gridTemplateRows: `repeat(auto-fill, ${rowHeight || 400}px)`,
436
- }}
437
- >
438
- {dashboardSections[section]
439
- .filter(elem => elem.chartType !== 'metric')
440
- .map(
441
- (
442
- elem: {
443
- name:
444
- | string
445
- | number
446
- | boolean
447
- | React.ReactElement<
448
- any,
449
- string | React.JSXElementConstructor<any>
450
- >
451
- | React.ReactFragment
452
- | null
453
- | undefined;
454
- _id: string | undefined;
455
- },
456
- index: string
457
- ) => {
458
- return (
459
- <div
460
- onClick={
461
- onClickDashboardItem
462
- ? () => handleOnClickDashboardItem(elem._id)
463
- : undefined
464
- }
465
- // className={
466
- // onClickDashboardItem
467
- // ? 'hover:qq-bg-zinc-50'
468
- // : undefined
469
- // }
470
- // className="qq-shadow-md"
471
- key={elem.name + '' + index}
472
- // onClick={() => handleEditDashboardItem(elem)}
473
- // className="qq-shadow"
474
- style={{
475
- // background: theme.elevatedCardColor,
476
- // borderRadius: theme.borderRadius,
477
- // boxShadow: theme.boxShadow,
478
- height: '100%',
479
- cursor: 'pointer',
480
- boxSizing: 'content-box',
481
- // width: '100%',
482
- paddingRight: 25,
483
- minHeight: rowHeight || 400,
484
- borderRadius: 8,
485
- paddingTop: 20,
486
- }}
487
- >
488
- <div
489
- style={{
490
- width: '100%',
491
- height: '100%',
492
- boxSizing: 'content-box',
493
- }}
494
- >
495
- <div
496
- style={{
497
- width: '100%',
498
- height: '100%',
499
- boxSizing: 'content-box',
500
- }}
501
- >
502
- <div
503
- style={{
504
- display: 'flex',
505
- flexDirection: 'column',
506
- justifyContent: 'space-between',
507
- height: '100%',
508
- boxSizing: 'content-box',
509
- }}
510
- >
511
- <div
512
- style={{
513
- display: 'flex',
514
- flexDirection: 'row',
515
- justifyContent: 'space-between',
516
- boxSizing: 'content-box',
517
- // alignItems: 'center',
518
- // paddingLeft: theme.padding,
519
- // paddingRight: theme.padding,
520
- // paddingTop: theme.padding,
521
- }}
522
- >
523
- <div
524
- style={{
525
- fontFamily: theme.fontFamily,
526
- color: theme.primaryTextColor,
527
- boxSizing: 'content-box',
528
- fontSize: 18,
529
- fontWeight: '500',
530
- // fontSize: theme.headerFontSize,
531
- // color: theme.fontColor,
532
- // fontWeight: theme.headerFontWeight,
533
- textOverflow: 'ellipsis',
534
- // margin: 0,
535
- marginLeft: 25,
536
- padding: 0,
537
- whiteSpace: 'nowrap',
538
- display: 'block',
539
- maxWidth: '100%',
540
- overflow: 'hidden',
541
- }}
542
- >
543
- {elem.name}
544
- </div>
545
- {onClickDashboardItem ? (
546
- <div
547
- // className="hover:bg-black"
548
- style={{
549
- fontFamily: theme.fontFamily,
550
- color: theme.primaryTextColor,
551
- boxSizing: 'content-box',
552
- fontWeight: '500',
553
- fontSize: 14,
554
- minWidth: 14 * 7,
555
- // background: 'red',
556
- display: 'flex',
557
- alignItems: 'center',
558
- justifyContent: 'flex-end',
559
- }}
560
- >
561
- {'view report →'}
562
- </div>
563
- ) : null}
564
- {/* <Arrow fill={theme.fontColor} /> */}
565
- </div>
566
- {/* <div style={{ height: 20 }} /> */}
567
- <div
568
- style={{
569
- padding: 0,
570
- height: '100%',
571
- boxSizing: 'content-box',
572
- }}
573
- >
574
- <Chart
575
- containerStyle={{
576
- display: 'flex',
577
- width: '100%',
578
- // TODO: fix fixed height
579
- height: 300,
580
- marginBottom: 50,
581
- marginTop: 30,
582
- }}
583
- isDateFilter={true}
584
- chartId={elem._id}
585
- colors={
586
- theme.chartColors?.length
587
- ? theme.chartColors
588
- : undefined
589
- }
590
- // updateDashboard={updateDashboard}
591
- />
592
- </div>
593
- </div>
594
- </div>
595
- </div>
596
- </div>
597
- );
598
- }
599
- )}
600
- </div>
601
- </div>
602
- );
603
- })}
604
- </div>
605
- );
606
- }
607
-
608
- function Filter({ defaultValue, theme, onValueChange, filter }) {
609
- //should be date as well as strings
610
- const dropdownOptions = [
611
- { value: 'popupbagelsmardens', text: 'popupbagelsmardens' },
612
- { value: 'popupbagelswestport', text: 'popupbagelswestport' },
613
- { value: 'popupbagelseasthampton', text: 'popupbagelseasthampton' },
614
- { value: 'popupbagelsgreenwich', text: 'popupbagelsgreenwich' },
615
- { value: 'popupbagelsredding', text: 'popupbagelsredding' },
616
- { value: 'popupbagelsthompson', text: 'popupbagelsthompson' },
617
- ];
618
- const dropdownRef = useRef(null);
619
- const [showDropdown, setShowDropdown] = useState(false);
620
- const [selectedValue, setSelectedValue] = useInternalState(
621
- defaultValue,
622
- undefined
623
- );
624
- const selectedDropdownValue = selectedValue ? selectedValue[2] ?? null : null;
625
-
626
- const handleDropdownOptionClick = (dropdownValue: string) => {
627
- setSelectedValue([undefined, undefined, dropdownValue]);
628
- onValueChange?.([undefined, undefined, dropdownValue]);
629
- setShowDropdown(false);
630
- };
631
-
632
- const [hoveredDropdownValue, handleDropdownKeyDown] = useSelectOnKeyDown(
633
- handleDropdownOptionClick,
634
- dropdownOptions.map((option: DateRangePickerOption) => option.value),
635
- showDropdown,
636
- setShowDropdown,
637
- selectedDropdownValue as string
638
- );
639
-
640
- return (
641
- <div style={{ position: 'relative', width: '100%' }}>
642
- <div
643
- style={{
644
- marginBottom: 6,
645
- fontWeight: '600',
646
- color: theme.secondaryTextColor,
647
- fontSize: 14,
648
- fontFamily: theme.fontFamily,
649
- }}
650
- >
651
- {filter.label}
652
- </div>
653
- <FilterDropdown
654
- showDropdown={showDropdown}
655
- setShowDropdown={setShowDropdown}
656
- handleDropdownKeyDown={handleDropdownKeyDown}
657
- dropdownRef={dropdownRef}
658
- theme={theme}
659
- selectedDropdownValue={selectedDropdownValue}
660
- dropdownOptions={filter.options}
661
- field={filter.field}
662
- label={filter.labelField}
663
- />
664
- <FilterModal
665
- showDropdown={showDropdown}
666
- setShowDropdown={setShowDropdown}
667
- dropdownRef={dropdownRef}
668
- theme={theme}
669
- hoveredDropdownValue={hoveredDropdownValue}
670
- selectedDropdownValue={selectedDropdownValue}
671
- dropdownOptions={filter.options}
672
- handleDropdownOptionClick={handleDropdownOptionClick}
673
- field={filter.field}
674
- label={filter.labelField}
675
- />
676
- </div>
677
- );
678
- }
679
-
680
- function removeQuotes(str) {
681
- if (str.startsWith('"') && str.endsWith('"')) {
682
- return str.slice(1, -1);
683
- } else {
684
- return str;
685
- }
686
- }
687
-
688
- function FilterDropdown({
689
- setShowDropdown,
690
- dropdownRef,
691
- showDropdown,
692
- handleDropdownKeyDown,
693
- theme,
694
- dropdownPlaceholder = 'Select',
695
- selectedDropdownValue,
696
- dropdownOptions,
697
- field,
698
- label,
699
- }) {
700
- const dropdownText = selectedDropdownValue
701
- ? String(
702
- dropdownOptions.find(
703
- option => option[removeQuotes(field)] === selectedDropdownValue
704
- )[removeQuotes(label)]
705
- )
706
- : dropdownPlaceholder;
707
- return (
708
- <div
709
- style={{
710
- display: 'flex',
711
- alignItems: 'center',
712
- justifyContent: 'space-between',
713
- borderRadius: '0.375rem',
714
- background: theme?.backgroundColor,
715
- fontFamily: theme?.fontFamily,
716
- boxShadow: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
717
- }}
718
- >
719
- <button
720
- type="button"
721
- style={{
722
- // fontFamily: theme?.fontFamily,
723
- borderColor: theme?.borderColor || '#E5E7EB',
724
- borderStyle: 'solid',
725
- borderWidth: 1,
726
- cursor: 'pointer',
727
- marginLeft: -1,
728
- borderRadius: '0.375rem',
729
- // width: '12rem',
730
- width: '100%',
731
- overflow: 'hidden',
732
- textOverflow: 'ellipsis',
733
- whiteSpace: 'nowrap',
734
- paddingLeft: '1rem',
735
- paddingRight: '1rem',
736
- display: 'inline-flex',
737
- minHeight: 38,
738
- justifyContent: 'space-between',
739
- alignItems: 'center',
740
- background: theme?.backgroundColor,
741
- fontSize: theme?.fontSizeSmall || '0.875rem',
742
- // fontWeight: theme?.fontWeightMedium || '800',
743
- }}
744
- ref={dropdownRef}
745
- onClick={() => setShowDropdown(!showDropdown)}
746
- onKeyDown={handleDropdownKeyDown}
747
- // disabled={disabled}
748
- >
749
- <p
750
- style={{
751
- margin: 0,
752
- fontFamily: theme?.fontFamily,
753
- color: theme?.primaryTextColor || '#364153',
754
- overflow: 'hidden',
755
- textOverflow: 'ellipsis',
756
- whiteSpace: 'nowrap',
757
- fontWeight: theme?.fontWeightMedium || '500',
758
- fontSize: theme?.fontSizeSmall || '0.875rem',
759
- }}
760
- >
761
- {dropdownText}
762
- </p>
763
- <ArrowDownHeadIcon
764
- style={{
765
- height: '1.25rem',
766
- width: '1.25rem',
767
- flex: 'none',
768
- color: theme?.secondaryTextColor,
769
- marginRight: '-0.25rem',
770
- }}
771
- aria-hidden="true"
772
- />
773
- </button>
774
- </div>
775
- );
776
- }
777
-
778
- function FilterModal({
779
- setShowDropdown,
780
- dropdownRef,
781
- showDropdown,
782
- theme,
783
- selectedDropdownValue,
784
- hoveredDropdownValue,
785
- dropdownOptions,
786
- handleDropdownOptionClick,
787
- field,
788
- label,
789
- }) {
790
- return (
791
- <Modal
792
- showModal={showDropdown}
793
- setShowModal={setShowDropdown}
794
- parentRef={dropdownRef}
795
- theme={theme}
796
- >
797
- <SelectedValueContext.Provider
798
- value={{
799
- selectedValue: selectedDropdownValue,
800
- handleValueChange: handleDropdownOptionClick,
801
- }}
802
- >
803
- <HoveredValueContext.Provider
804
- value={{ hoveredValue: hoveredDropdownValue }}
805
- >
806
- {dropdownOptions.map((row, index: number) => (
807
- <DropdownItem
808
- key={row[removeQuotes(field)]}
809
- value={row[removeQuotes(field)]}
810
- text={row[removeQuotes(label)]}
811
- theme={theme}
812
- lastItem={dropdownOptions.length - 1 === index}
813
- />
814
- ))}
815
- </HoveredValueContext.Provider>
816
- </SelectedValueContext.Provider>
817
- </Modal>
818
- );
819
- }