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