@quillsql/react 1.7.5 → 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 (73) hide show
  1. package/lib/ReportBuilder.js +1 -0
  2. package/lib/ReportBuilder.js.map +1 -1
  3. package/lib/SQLEditor.js +3 -3
  4. package/lib/SQLEditor.js.map +1 -1
  5. package/lib/Table.js +1 -1
  6. package/lib/Table.js.map +1 -1
  7. package/lib/components/BigModal/BigModal.js +1 -0
  8. package/lib/components/BigModal/BigModal.js.map +1 -1
  9. package/lib/components/Modal/Modal.js +1 -0
  10. package/lib/components/Modal/Modal.js.map +1 -1
  11. package/lib/hooks/useQuill.js +1 -0
  12. package/lib/hooks/useQuill.js.map +1 -1
  13. package/package.json +11 -4
  14. package/.eslintrc.json +0 -19
  15. package/.prettierrc +0 -11
  16. package/.vscode/settings.json +0 -10
  17. package/src/AddToDashboardModal.tsx +0 -1220
  18. package/src/BarList.tsx +0 -580
  19. package/src/Chart.tsx +0 -1337
  20. package/src/Context.tsx +0 -252
  21. package/src/Dashboard.tsx +0 -820
  22. package/src/DateRangePicker/Calendar.tsx +0 -442
  23. package/src/DateRangePicker/DateRangePicker.tsx +0 -261
  24. package/src/DateRangePicker/DateRangePickerButton.tsx +0 -250
  25. package/src/DateRangePicker/dateRangePickerUtils.tsx +0 -480
  26. package/src/DateRangePicker/index.ts +0 -4
  27. package/src/PieChart.tsx +0 -845
  28. package/src/QuillProvider.tsx +0 -81
  29. package/src/ReportBuilder.tsx +0 -2208
  30. package/src/SQLEditor.tsx +0 -1093
  31. package/src/Table.tsx +0 -1074
  32. package/src/TableChart.tsx +0 -428
  33. package/src/assets/ArrowDownHeadIcon.tsx +0 -11
  34. package/src/assets/ArrowDownIcon.tsx +0 -14
  35. package/src/assets/ArrowDownRightIcon.tsx +0 -14
  36. package/src/assets/ArrowLeftHeadIcon.tsx +0 -11
  37. package/src/assets/ArrowRightHeadIcon.tsx +0 -11
  38. package/src/assets/ArrowRightIcon.tsx +0 -14
  39. package/src/assets/ArrowUpHeadIcon.tsx +0 -11
  40. package/src/assets/ArrowUpIcon.tsx +0 -14
  41. package/src/assets/ArrowUpRightIcon.tsx +0 -14
  42. package/src/assets/CalendarIcon.tsx +0 -14
  43. package/src/assets/DoubleArrowLeftHeadIcon.tsx +0 -18
  44. package/src/assets/DoubleArrowRightHeadIcon.tsx +0 -20
  45. package/src/assets/ExclamationFilledIcon.tsx +0 -14
  46. package/src/assets/LoadingSpinner.tsx +0 -11
  47. package/src/assets/SearchIcon.tsx +0 -14
  48. package/src/assets/XCircleIcon.tsx +0 -14
  49. package/src/assets/index.ts +0 -16
  50. package/src/components/BigModal/BigModal.tsx +0 -108
  51. package/src/components/Dropdown/Dropdown.tsx +0 -169
  52. package/src/components/Dropdown/DropdownItem.tsx +0 -68
  53. package/src/components/Dropdown/index.ts +0 -2
  54. package/src/components/Modal/Modal.tsx +0 -132
  55. package/src/components/Modal/index.ts +0 -1
  56. package/src/components/selectUtils.ts +0 -60
  57. package/src/contexts/BaseColorContext.tsx +0 -5
  58. package/src/contexts/HoveredValueContext.tsx +0 -12
  59. package/src/contexts/RootStylesContext.tsx +0 -5
  60. package/src/contexts/SelectedValueContext.tsx +0 -13
  61. package/src/contexts/index.ts +0 -4
  62. package/src/hooks/index.ts +0 -4
  63. package/src/hooks/useInternalState.tsx +0 -18
  64. package/src/hooks/useOnClickOutside.tsx +0 -23
  65. package/src/hooks/useOnWindowResize.tsx +0 -17
  66. package/src/hooks/useQuill.ts +0 -138
  67. package/src/hooks/useSelectOnKeyDown.tsx +0 -80
  68. package/src/index.ts +0 -9
  69. package/src/lib/font.ts +0 -14
  70. package/src/lib/index.ts +0 -3
  71. package/src/lib/inputTypes.ts +0 -81
  72. package/src/lib/utils.tsx +0 -46
  73. package/tsconfig.json +0 -22
package/src/SQLEditor.tsx DELETED
@@ -1,1093 +0,0 @@
1
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
- // @ts-ignore
3
- import React, { useState, useContext, useMemo, useEffect } from 'react';
4
- import MonacoEditor from '@monaco-editor/react';
5
- // import './nightOwlLight.css';
6
- import axios from 'axios';
7
- import { ClientContext, SchemaContext, ThemeContext } from './Context';
8
- import {
9
- ChevronDownIcon,
10
- ChevronRightIcon,
11
- SparklesIcon,
12
- MagnifyingGlassIcon,
13
- } from '@heroicons/react/20/solid';
14
- import { QuillTheme } from './QuillProvider';
15
- import { SpecialTable } from './Table';
16
-
17
- export function convertPostgresColumn(column) {
18
- let format;
19
-
20
- switch (column.dataTypeID) {
21
- case 20: // int8
22
- case 21: // int2
23
- case 23: // int4
24
- format = 'whole_number';
25
- break;
26
- case 700: // float4
27
- case 701: // float8
28
- case 1700: // numeric
29
- format = 'two_decimal_places';
30
- break;
31
- case 1082: // date
32
- case 1083: // time
33
- case 1184: // timestamptz
34
- case 1114: // timestamp
35
- format = 'MMM_dd_yyyy';
36
- break;
37
- case 1043: // varchar
38
- default:
39
- format = 'string';
40
- }
41
-
42
- return {
43
- label: column.name,
44
- field: column.name,
45
- format: format,
46
- };
47
- }
48
-
49
- function defineEditorTheme(monaco, theme) {
50
- monaco.editor.defineTheme('onedark', {
51
- base: theme.darkMode ? 'vs-dark' : 'vs',
52
- inherit: true,
53
- rules: [
54
- {
55
- token: 'comment',
56
- foreground: '#5d7988',
57
- fontStyle: 'italic',
58
- },
59
- { token: 'constant', foreground: '#e06c75' },
60
- ],
61
- colors: {
62
- 'editor.background': '#F9F9F9',
63
- },
64
- });
65
- }
66
- function setEditorTheme(editor, monaco) {
67
- try {
68
- monaco.editor.setTheme('onedark');
69
- } catch (e) {
70
- console.log('ERROR: ', e);
71
- }
72
- }
73
-
74
- interface ButtonComponentProps {
75
- onClick: () => void;
76
- label: string;
77
- }
78
-
79
- interface SQLEditorProps {
80
- containerStyle: React.CSSProperties;
81
- ButtonComponent?: (props: ButtonComponentProps) => JSX.Element;
82
- SecondaryButtonComponent?: (props: ButtonComponentProps) => JSX.Element;
83
- TextInputComponent?: (props: TextInputComponentProps) => JSX.Element;
84
- TableComponent?: (props: TableComponentProps) => JSX.Element;
85
- AddToDashboardButton?: (props: AddToDashboardButtonProps) => JSX.Element;
86
- LoadingComponent?: () => JSX.Element;
87
- }
88
-
89
- interface AddToDashboardButtonProps {
90
- rows: any[];
91
- columns: any[];
92
- query: string;
93
- }
94
-
95
- interface TableComponentProps {
96
- rows: any[];
97
- columns: any[];
98
- height: string;
99
- }
100
-
101
- interface TextInputComponentProps {
102
- onChange: (e: any) => void;
103
- value: string;
104
- id: string;
105
- placeholder?: string;
106
- }
107
-
108
- const QuillButton = ({
109
- onClick,
110
- label,
111
- theme,
112
- secondary,
113
- }: {
114
- onClick: () => void;
115
- label: string;
116
- theme?: any;
117
- secondary?: boolean;
118
- }) => (
119
- <button
120
- style={{
121
- borderRadius: '6px',
122
- backgroundColor: secondary
123
- ? theme?.secondaryButtonColor || '#FFFFFF'
124
- : theme?.primaryButtonColor,
125
- opacity: 1,
126
- paddingLeft: '16px',
127
- paddingRight: '16px',
128
- paddingTop: '10px',
129
- paddingBottom: '10px',
130
- fontSize: '14px',
131
- fontWeight: 600,
132
- color: secondary ? theme?.primaryTextColor : '#FFFFFF',
133
- cursor: 'pointer',
134
- outline: 'none',
135
- border: 'none',
136
- fontFamily: theme?.fontFamily,
137
- }}
138
- onClick={onClick}
139
- >
140
- {label}
141
- </button>
142
- );
143
-
144
- const QuillTextInput = ({
145
- onChange,
146
- value,
147
- id,
148
- placeholder,
149
- theme,
150
- }: {
151
- onChange: (e: any) => void;
152
- value: string;
153
- id: string;
154
- placeholder?: string;
155
- theme?: any;
156
- }) => {
157
- return (
158
- <input
159
- style={{
160
- display: 'flex',
161
- flexDirection: 'row',
162
- alignItems: 'center',
163
- paddingLeft: '12px',
164
- paddingRight: '12px',
165
- fontWeight: 'medium',
166
- height: 36,
167
- boxShadow: 'rgba(0, 0, 0, 0.1) 0px 1px 5px 0px',
168
- width: '445px',
169
- backgroundColor: theme?.backgroundColor || 'white',
170
- color: theme?.primaryTextColor,
171
- borderWidth: '1px',
172
- borderColor: theme?.borderColor || '#E7E7E7',
173
- borderStyle: 'solid',
174
- borderRadius: '6px',
175
- }}
176
- id={id}
177
- onChange={onChange}
178
- value={value}
179
- placeholder={placeholder}
180
- />
181
- );
182
- };
183
-
184
- export default function QueryEditor({
185
- containerStyle = { height: '100vh' },
186
- ButtonComponent,
187
- SecondaryButtonComponent,
188
- TextInputComponent,
189
- TableComponent,
190
- AddToDashboardButton,
191
- LoadingComponent,
192
- }: SQLEditorProps) {
193
- const [sqlPrompt, setSqlPrompt] = useState('');
194
-
195
- const [isOpen, setIsOpen] = useState(false);
196
-
197
- const [client] = useContext(ClientContext);
198
- const [theme] =
199
- useContext<[QuillTheme, (theme: QuillTheme) => void]>(ThemeContext);
200
- const [query, setQuery] = useState('');
201
- const [rows, setRows] = useState([]);
202
- const [columns, setColumns] = useState([]);
203
- const [fields, setFields] = useState([]);
204
- const [schema, setSchema] = useContext(SchemaContext);
205
- const [errorMessage, setErrorMessage] = useState('');
206
- const [sqlResponseLoading, setSqlResponseLoading] = useState(false);
207
- const [sqlQueryLoading, setSqlQueryLoading] = useState(false);
208
- const [schemaLoading, setSchemaLoading] = useState(false);
209
-
210
- useEffect(() => {
211
- let isSubscribed = true;
212
- async function getSchema() {
213
- const { publicKey, environment } = client;
214
- setSchemaLoading(true);
215
- const response3 = await axios.get(
216
- `https://quill-344421.uc.r.appspot.com/schema2/${publicKey}/`,
217
- {
218
- headers: {
219
- Authorization: `Bearer `,
220
- environment: environment || undefined,
221
- },
222
- }
223
- );
224
- if (isSubscribed) {
225
- setSchema(response3.data.tables);
226
- setSchemaLoading(false);
227
- }
228
- }
229
- if (isSubscribed) {
230
- getSchema();
231
- }
232
- return () => {
233
- isSubscribed = false;
234
- };
235
- }, []);
236
-
237
- const handleRunSqlPrompt = async () => {
238
- const { publicKey, environment } = client;
239
- setSqlResponseLoading(true);
240
- const response = await axios.post(
241
- `https://quill-344421.uc.r.appspot.com/quillai`,
242
- {
243
- initialQuestion: sqlPrompt,
244
- publicKey: publicKey,
245
- },
246
- {
247
- headers: {
248
- Authorization: `Bearer `,
249
- environment: environment || undefined,
250
- },
251
- }
252
- );
253
- setQuery(response.data.message);
254
- setSqlResponseLoading(false);
255
- };
256
-
257
- const handleRunQuery = async () => {
258
- const {
259
- publicKey,
260
- customerId,
261
- environment,
262
- queryEndpoint,
263
- queryHeaders,
264
- withCredentials,
265
- } = client;
266
- try {
267
- let response;
268
- setSqlQueryLoading(true);
269
- if (queryEndpoint) {
270
- response = await axios.post(
271
- queryEndpoint,
272
- { metadata: { query, task: 'query' } },
273
- { headers: queryHeaders, withCredentials }
274
- );
275
- } else {
276
- response = await axios.post(
277
- `https://quill-344421.uc.r.appspot.com/dashquery`,
278
- {
279
- query,
280
- },
281
- {
282
- params: {
283
- orgId: customerId,
284
- publicKey: publicKey,
285
- },
286
- headers: {
287
- Authorization: `Bearer `,
288
- environment: environment || undefined,
289
- },
290
- }
291
- );
292
- }
293
- if (response && response.data && response.data.errorMessage) {
294
- setSqlQueryLoading(false);
295
- setErrorMessage(
296
- 'Failed to run SQL query: ' + response.data.errorMessage
297
- );
298
- setRows([]);
299
- setColumns([]);
300
- setFields([]);
301
- return;
302
- }
303
- setSqlQueryLoading(false);
304
- setErrorMessage('');
305
- setRows(
306
- response.data.rows && response.data.rows.length
307
- ? response.data.rows
308
- : []
309
- );
310
- setColumns(response.data.fields.map(elem => convertPostgresColumn(elem)));
311
- setFields(response.data.fields);
312
- } catch (e) {
313
- console.log('ERROR: ', e);
314
- return;
315
- }
316
- };
317
-
318
- const handleAddToDashboard = () => {
319
- setIsOpen(true);
320
- };
321
-
322
- /* all your useState and useContext calls and your useEffect hooks */
323
-
324
- const downloadCSV = () => {
325
- // report.rows
326
- if (!rows.length) {
327
- return;
328
- }
329
- const json = rows; // JSON data passed as a prop
330
- const fields = Object.keys(json[0]); // Assumes all objects have same keys
331
- const csvRows = [];
332
-
333
- // Header row
334
- csvRows.push(fields.join(','));
335
-
336
- // Data rows
337
- for (const row of json) {
338
- const values = fields.map(field => JSON.stringify(row[field] || ''));
339
- csvRows.push(values.join(','));
340
- }
341
-
342
- // Create CSV string and create a 'blob' with it
343
- const csvString = csvRows.join('\r\n');
344
- const csvBlob = new Blob([csvString], { type: 'text/csv' });
345
-
346
- // Create a download link and click it
347
- const downloadLink = document.createElement('a');
348
- downloadLink.download = `${query}.csv`;
349
- downloadLink.href = URL.createObjectURL(csvBlob);
350
- downloadLink.style.display = 'none';
351
-
352
- document.body.appendChild(downloadLink);
353
- downloadLink.click();
354
- document.body.removeChild(downloadLink);
355
- };
356
-
357
- /* rest of your methods */
358
-
359
- return (
360
- <div style={containerStyle}>
361
- <div
362
- style={{
363
- height: 'calc(100%)',
364
- display: 'flex',
365
- flexDirection: 'column',
366
- padding: 0,
367
- }}
368
- >
369
- <div
370
- style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
371
- >
372
- <div
373
- style={{
374
- width: '100%',
375
- display: 'flex',
376
- height: '100%',
377
- flexDirection: 'row',
378
- }}
379
- >
380
- <SchemaListComponent
381
- schema={schema}
382
- theme={theme}
383
- LoadingComponent={LoadingComponent}
384
- loading={schemaLoading}
385
- />
386
-
387
- <div
388
- style={{
389
- display: 'flex',
390
- flexDirection: 'column',
391
- width: 'calc(100% - 250px)',
392
- }}
393
- >
394
- <div
395
- style={{
396
- // TODO: change color
397
- height: 80,
398
- background: 'white',
399
- display: 'flex',
400
- flexDirection: 'row',
401
- alignItems: 'center',
402
- }}
403
- >
404
- {/* <div
405
- style={{
406
- display: 'flex',
407
- flexDirection: 'row',
408
- alignItems: 'center',
409
- paddingLeft: '12px',
410
- paddingRight: '12px',
411
- height: 38,
412
- boxShadow: 'rgba(0, 0, 0, 0.1) 0px 1px 5px 0px',
413
- width: '445px',
414
- // TODO: change color
415
- borderColor: theme.borderColor,
416
- color: theme.primaryTextColor,
417
- borderWidth: '1px',
418
- // TODO: change color
419
- backgroundColor: 'white',
420
- borderRadius: 6,
421
- borderStyle: 'solid',
422
- outline: 'none',
423
- fontFamily: theme?.fontFamily,
424
- }}
425
- >
426
- <MagnifyingGlassIcon
427
- style={{
428
- height: 16,
429
- width: 16,
430
- color: theme.secondaryTextColor,
431
- }}
432
- aria-hidden="true"
433
- />
434
- <input
435
- value={sqlPrompt}
436
- onChange={e => setSqlPrompt(e.target.value)}
437
- style={{
438
- outline: 'none',
439
- marginLeft: 8,
440
- width: '100%',
441
- border: 'none',
442
- outline: 'none',
443
- fontFamily: theme?.fontFamily,
444
- }}
445
- />
446
- </div> */}
447
- <div style={{ minWidth: 440, marginRight: 10 }}>
448
- {(TextInputComponent && (
449
- <TextInputComponent
450
- id="ai-search"
451
- value={sqlPrompt}
452
- onChange={e => setSqlPrompt(e.target.value)}
453
- placeholder="Ask a question..."
454
- />
455
- )) || (
456
- <QuillTextInput
457
- id="ai-search"
458
- value={sqlPrompt}
459
- onChange={e => setSqlPrompt(e.target.value)}
460
- placeholder="Ask a question..."
461
- theme={theme}
462
- />
463
- )}
464
- </div>
465
- {(ButtonComponent && (
466
- <ButtonComponent
467
- onClick={handleRunSqlPrompt}
468
- label="Ask AI"
469
- />
470
- )) || (
471
- <QuillButton
472
- theme={theme}
473
- onClick={handleRunSqlPrompt}
474
- label="Ask AI"
475
- />
476
- )}
477
- </div>
478
- <div style={{ height: 'calc(50% - 40px)' }}>
479
- <SQLEditorComponent
480
- query={query}
481
- setQuery={setQuery}
482
- handleRunQuery={handleRunQuery}
483
- theme={theme}
484
- defineEditorTheme={defineEditorTheme}
485
- setEditorTheme={setEditorTheme}
486
- ButtonComponent={ButtonComponent}
487
- loading={sqlResponseLoading}
488
- LoadingComponent={LoadingComponent}
489
- />
490
- </div>
491
- <div
492
- style={{
493
- height: 'calc(50% - 40px)',
494
- display: 'flex',
495
- flexDirection: 'column',
496
- padding: 0,
497
- margin: 0,
498
- border: 'none',
499
- outline: 'none',
500
- }}
501
- >
502
- {errorMessage && (
503
- <div
504
- style={{
505
- fontFamily: theme?.fontFamily,
506
- color: theme?.primaryTextColor,
507
- fontSize: 15,
508
- fontWeight: '400',
509
- }}
510
- >
511
- <div
512
- style={{
513
- padding: 30,
514
- // TODO: change color
515
- background: 'rgba(0,0,0,0.02)',
516
- display: 'inline-block',
517
- flex: 0,
518
- borderRadius: 6,
519
- color: theme?.primaryTextColor,
520
- fontFamily: theme?.fontFamily,
521
- }}
522
- >
523
- {errorMessage}
524
- </div>
525
- </div>
526
- )}
527
- {errorMessage
528
- ? null
529
- : (TableComponent && (
530
- <TableComponent
531
- rows={rows}
532
- columns={columns}
533
- height="calc(100% - 70px)"
534
- />
535
- )) || (
536
- <SpecialTable
537
- rows={rows}
538
- columns={columns}
539
- height="calc(100% - 70px)"
540
- LoadingComponent={LoadingComponent}
541
- loading={sqlQueryLoading}
542
- theme={theme}
543
- />
544
- )}
545
- <div
546
- style={{
547
- height: 70,
548
- // TODO: change color
549
- background: theme?.backgroundColor,
550
- }}
551
- >
552
- {rows.length ? (
553
- <div
554
- style={{
555
- display: 'flex',
556
- flexDirection: 'column',
557
- height: 70,
558
- border: 'none',
559
- }}
560
- >
561
- <div
562
- style={{
563
- height: 1,
564
- width: '100%',
565
- // TODO: change color
566
- // background: theme.borderColor,
567
- }}
568
- />
569
- <div
570
- style={{
571
- marginLeft: 0,
572
- height: 69,
573
- display: 'flex',
574
- alignItems: 'center',
575
- justifyContent: 'flex-end',
576
- paddingRight: 20,
577
- }}
578
- >
579
- {/* <button
580
- type="button"
581
- onClick={downloadCSV}
582
- style={{
583
- borderRadius: 6,
584
- // TODO: change color
585
- backgroundColor: theme.primaryButtonColor,
586
- paddingLeft: '1rem',
587
- paddingRight: '1rem',
588
- paddingTop: '0.5rem',
589
- paddingBottom: '0.5rem',
590
- fontSize: '0.875rem',
591
- fontWeight: '600',
592
- // TODO: change color
593
- color: theme.backgroundColor,
594
- fontFamily: theme.fontFamily,
595
- outline: 'none',
596
- border: 'none',
597
- cursor: 'pointer',
598
- marginTop: 14,
599
- }}
600
- >
601
- Download CSV
602
- </button> */}
603
- {(SecondaryButtonComponent && (
604
- <SecondaryButtonComponent
605
- onClick={downloadCSV}
606
- label="Download CSV"
607
- />
608
- )) || (
609
- <QuillButton
610
- theme={theme}
611
- onClick={downloadCSV}
612
- label="Download CSV"
613
- secondary
614
- />
615
- )}
616
- {AddToDashboardButton && <div style={{ width: 10 }} />}
617
- {AddToDashboardButton && (
618
- <AddToDashboardButton
619
- // @ts-ignore
620
- rows={rows}
621
- columns={columns}
622
- query={query}
623
- />
624
- )}
625
- <div />
626
- </div>
627
- </div>
628
- ) : null}
629
- </div>
630
- </div>
631
- </div>
632
- </div>
633
- </div>
634
- </div>
635
- </div>
636
- );
637
- }
638
-
639
- const SQLEditorComponent = ({
640
- query,
641
- setQuery,
642
- handleRunQuery,
643
- defineEditorTheme,
644
- setEditorTheme,
645
- ButtonComponent,
646
- theme,
647
- loading,
648
- LoadingComponent,
649
- }) => {
650
- return (
651
- <div
652
- style={{
653
- background: theme.backgroundColor,
654
- // maxHeight: 700,
655
- width: '100%',
656
- height: '100%',
657
- // minWidth: 450,
658
- // overflowY: "scroll",
659
- // padding: "20px 30px 20px 20px",
660
- // marginLeft: 20,
661
- borderTopLeftRadius: 6,
662
- borderBottomLeftRadius: 6,
663
- borderTopRightRadius: 0,
664
- borderBottomRightRadius: 0,
665
- overflow: 'hidden',
666
- }}
667
- >
668
- {loading ? (
669
- <div
670
- style={{
671
- height: 'calc(100% - 70px)',
672
- width: '100%',
673
- display: 'flex',
674
- alignItems: 'center',
675
- justifyContent: 'center',
676
- background: '#F9F9F9',
677
- }}
678
- >
679
- {LoadingComponent && <LoadingComponent />}
680
- {!LoadingComponent && (
681
- <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
682
- <defs>
683
- <linearGradient
684
- id="circleGradient"
685
- gradientUnits="objectBoundingBox"
686
- >
687
- <stop offset="0%" stop-color="#F9F9FA" />
688
- <stop offset="5%" stop-color="#F9F9FA" />
689
- <stop offset="100%" stop-color="#D1D1D1" />
690
- </linearGradient>
691
- <mask id="mask">
692
- <circle cx="12" cy="12" r="12" fill="white" />
693
- <path
694
- id="sector"
695
- fill="black"
696
- d="M15,15 L15,1.8 A13.2,13.2 0 0,1 15,1.8 Z"
697
- >
698
- <animate
699
- attributeName="d"
700
- from="M15,15 L15,1.8 A13.2,13.2 0 0,0 15,1.8 Z"
701
- to="M15,15 L15,1.8 A13.2,13.2 0 1,1 15,1.8 Z"
702
- dur="2s"
703
- repeatCount="indefinite"
704
- />
705
- </path>
706
- </mask>
707
- </defs>
708
- <g transform="rotate(0 15 15)">
709
- <animateTransform
710
- attributeName="transform"
711
- attributeType="XML"
712
- type="rotate"
713
- from="0 12 12"
714
- to="360 12 12"
715
- dur="2s"
716
- repeatCount="indefinite"
717
- />
718
- <circle
719
- cx="12"
720
- cy="12"
721
- r="12"
722
- fill="none"
723
- stroke="url(#circleGradient)"
724
- stroke-width="8"
725
- mask="url(#mask)"
726
- />
727
- </g>
728
- </svg>
729
- )}
730
- </div>
731
- ) : (
732
- <MonacoEditor
733
- height="calc(100% - 70px)"
734
- width="100%"
735
- defaultLanguage="pgsql"
736
- defaultValue=""
737
- value={query}
738
- loading={<div />}
739
- options={{
740
- wordWrap: 'on',
741
- minimap: {
742
- enabled: false,
743
- },
744
- padding: { top: 16 },
745
- }}
746
- onChange={query => setQuery(query)}
747
- beforeMount={monaco => defineEditorTheme(monaco, theme)}
748
- onMount={setEditorTheme}
749
- />
750
- )}
751
- <div
752
- style={{
753
- display: 'flex',
754
- flexDirection: 'row',
755
- alignItems: 'center',
756
- height: 70,
757
- }}
758
- >
759
- {/* <button
760
- type="button"
761
- onClick={handleRunQuery}
762
- style={{
763
- borderRadius: 8,
764
- width: '100px',
765
- // backgroundColor: "#212121",
766
- height: '32px',
767
- fontSize: 14,
768
- fontWeight: '600',
769
- backgroundColor: 'transparent',
770
- color: '#384151',
771
- border: 'none',
772
- outline: 'none',
773
- cursor: 'pointer',
774
- }}
775
- >
776
- Run query
777
- </button> */}
778
- {/* <button
779
- type="button"
780
- onClick={handleRunQuery}
781
- style={{
782
- borderRadius: 6,
783
- backgroundColor: theme.primaryButtonColor,
784
- height: 32,
785
- width: 100,
786
- marginLeft: 0,
787
- // paddingLeft: '1rem',
788
- // paddingRight: '1rem',
789
- // paddingTop: '0.5rem',
790
- // paddingBottom: '0.5rem',
791
- fontSize: '0.875rem',
792
- fontWeight: '600',
793
- color: theme.backgroundColor,
794
- fontFamily: theme.fontFamily,
795
- outline: 'none',
796
- border: 'none',
797
- cursor: 'pointer',
798
- }}
799
- >
800
- Run query
801
- </button> */}
802
- {(ButtonComponent && (
803
- <ButtonComponent onClick={handleRunQuery} label="Run query" />
804
- )) || (
805
- <QuillButton
806
- onClick={handleRunQuery}
807
- label="Run query"
808
- theme={theme}
809
- />
810
- )}
811
- </div>
812
- </div>
813
- );
814
- };
815
-
816
- const styles = {
817
- columnHeader: {
818
- boxSizing: 'border-box',
819
- flex: '150 0 auto',
820
- minWidth: '50px',
821
- width: '150px',
822
- position: 'relative',
823
- cursor: 'pointer',
824
- background: 'rgb(249, 250, 251)',
825
- borderRight: '1px solid rgb(229, 231, 235)',
826
- whiteSpace: 'nowrap',
827
- display: 'flex',
828
- alignItems: 'center',
829
- overflowX: 'visible',
830
- margin: '0px',
831
- textOverflow: 'ellipsis',
832
- minHeight: '36px',
833
- // 2.25rem * 16px = 36px
834
- },
835
- columnHeaderLabel: {
836
- fontFamily:
837
- 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"',
838
- WebkitTapHighlightColor: 'transparent',
839
- color: 'rgb(55, 65, 81)',
840
- textDecoration: 'none',
841
- fontWeight: 500,
842
- fontSize: '14px', // 0.875rem * 16px = 14px
843
- lineHeight: '20px', // 1.25rem * 16px = 20px
844
- textOverflow: 'ellipsis',
845
- whiteSpace: 'nowrap',
846
- overflow: 'hidden',
847
- },
848
- };
849
-
850
- const SchemaListComponent = ({ schema, theme, loading, LoadingComponent }) => {
851
- if (loading) {
852
- return (
853
- <div
854
- style={{
855
- background: theme.backgroundColor,
856
- // maxHeight: 700,
857
- width: 250,
858
- minWidth: 250,
859
- // overflowY: 'scroll',
860
- height: '100%',
861
- // maxHeight: "100%",
862
- paddingLeft: 20,
863
- paddingRight: 30,
864
- paddingTop: 40,
865
- display: 'flex',
866
- // alignItems: 'center',
867
- justifyContent: 'center',
868
- }}
869
- >
870
- <div style={{ height: 100 }} />
871
- {LoadingComponent && <LoadingComponent />}
872
- {!LoadingComponent && (
873
- <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
874
- <defs>
875
- <linearGradient
876
- id="circleGradient"
877
- gradientUnits="objectBoundingBox"
878
- >
879
- <stop offset="0%" stop-color="#F9F9FA" />
880
- <stop offset="5%" stop-color="#F9F9FA" />
881
- <stop offset="100%" stop-color="#D1D1D1" />
882
- </linearGradient>
883
- <mask id="mask">
884
- <circle cx="12" cy="12" r="12" fill="white" />
885
- <path
886
- id="sector"
887
- fill="black"
888
- d="M15,15 L15,1.8 A13.2,13.2 0 0,1 15,1.8 Z"
889
- >
890
- <animate
891
- attributeName="d"
892
- from="M15,15 L15,1.8 A13.2,13.2 0 0,0 15,1.8 Z"
893
- to="M15,15 L15,1.8 A13.2,13.2 0 1,1 15,1.8 Z"
894
- dur="2s"
895
- repeatCount="indefinite"
896
- />
897
- </path>
898
- </mask>
899
- </defs>
900
- <g transform="rotate(0 15 15)">
901
- <animateTransform
902
- attributeName="transform"
903
- attributeType="XML"
904
- type="rotate"
905
- from="0 12 12"
906
- to="360 12 12"
907
- dur="2s"
908
- repeatCount="indefinite"
909
- />
910
- <circle
911
- cx="12"
912
- cy="12"
913
- r="12"
914
- fill="none"
915
- stroke="url(#circleGradient)"
916
- stroke-width="8"
917
- mask="url(#mask)"
918
- />
919
- </g>
920
- </svg>
921
- )}
922
- </div>
923
- );
924
- }
925
- return (
926
- <div
927
- style={{
928
- background: theme.backgroundColor,
929
- // maxHeight: 700,
930
- width: 250,
931
- minWidth: 250,
932
- overflowY: 'scroll',
933
- height: '100%',
934
- // maxHeight: "100%",
935
- paddingLeft: 20,
936
- paddingRight: 30,
937
- }}
938
- >
939
- {schema.map((elem, index) => (
940
- <SchemaItem
941
- key={elem.displayName + index}
942
- elem={elem}
943
- theme={theme}
944
- index={index}
945
- />
946
- ))}
947
- </div>
948
- );
949
- };
950
-
951
- function SchemaItem({ elem, theme, index }) {
952
- const [isOpen, setIsOpen] = useState(index === 0);
953
-
954
- const schemaContainerStyle = {
955
- display: 'flex',
956
- flexDirection: 'column',
957
- // WebkitTouchCallout: "none",
958
- // WebkitUserSelect: "none",
959
- // KhtmlUserSelect: "none",
960
- // MozUserSelect: "none",
961
- // msUserSelect: "none",
962
- // userSelect: "none",
963
- };
964
-
965
- const schemaRowStyle = {
966
- display: 'flex',
967
- flexDirection: 'row',
968
- alignItems: 'center',
969
- width: '100%',
970
- justifyContent: 'space-between',
971
- cursor: 'pointer',
972
- };
973
-
974
- const schemaRowHoverStyle = {
975
- background: theme.selectUnderlayColor,
976
- };
977
-
978
- return (
979
- <div style={schemaContainerStyle}>
980
- <div
981
- style={{ ...schemaRowStyle, ...(isOpen && schemaRowHoverStyle) }}
982
- onClick={() => setIsOpen(!isOpen)}
983
- >
984
- <p
985
- style={{
986
- marginLeft: theme.padding,
987
- fontSize: 13,
988
- color: '#384151',
989
- fontWeight: '500',
990
- whiteSpace: 'nowrap',
991
- padding: 0,
992
- margin: 0,
993
- textOverflow: 'ellipsis',
994
- overflow: 'hidden',
995
- fontFamily: theme?.fontFamily,
996
- }}
997
- title={elem.displayName}
998
- >
999
- {elem.displayName}
1000
- </p>
1001
- <div
1002
- style={{
1003
- display: 'flex',
1004
- alignItems: 'center',
1005
- justifyContent: 'center',
1006
- // paddingRight: 25,
1007
- paddingTop: 12,
1008
- paddingBottom: 12,
1009
- paddingLeft: 0,
1010
- cursor: 'pointer',
1011
- }}
1012
- >
1013
- {/* <Arrow
1014
- fill={theme.fontColor}
1015
- style={{
1016
- transform: isOpen ? "scale(0.8) rotate(90deg)" : "scale(0.8)",
1017
- }}
1018
- /> */}
1019
- {isOpen ? (
1020
- <ChevronDownIcon
1021
- style={{ height: 13, width: 13, color: theme.secondaryTextColor }}
1022
- aria-hidden="true"
1023
- />
1024
- ) : (
1025
- <ChevronRightIcon
1026
- style={{ height: 13, width: 13, color: theme.secondaryTextColor }}
1027
- aria-hidden="true"
1028
- />
1029
- )}
1030
- </div>
1031
- </div>
1032
- {isOpen ? (
1033
- <div
1034
- style={{
1035
- paddingBottom: theme.padding,
1036
- display: 'flex',
1037
- flexDirection: 'column',
1038
- paddingLeft: theme.padding,
1039
- paddingRight: theme.padding,
1040
- }}
1041
- >
1042
- {elem.columns.map((elem, index) => (
1043
- <div
1044
- key={elem.displayName + elem.index}
1045
- style={{
1046
- paddingTop: theme.padding,
1047
- display: 'flex',
1048
- flexDirection: 'row',
1049
- alignItems: 'center',
1050
- justifyContent: 'space-between',
1051
- }}
1052
- >
1053
- <div
1054
- title={elem.displayName}
1055
- // className="text-gray-500"
1056
- style={{
1057
- fontSize: 12,
1058
- // color: theme.secondaryFontColor,
1059
- whiteSpace: 'nowrap',
1060
- color: theme.secondaryTextColor,
1061
- // color: "#6C727F",
1062
- padding: 0,
1063
- margin: 0,
1064
- textOverflow: 'ellipsis',
1065
- overflow: 'hidden',
1066
- width: 200,
1067
- maxWidth: 200,
1068
- fontFamily: theme?.fontFamily,
1069
- }}
1070
- >
1071
- {elem.displayName}
1072
- </div>
1073
- <div
1074
- // className="text-gray-500"
1075
- title={elem.displayName}
1076
- style={{
1077
- fontSize: 12,
1078
- // color: '#6C727F',
1079
- color: theme.secondaryTextColor,
1080
- padding: 0,
1081
- margin: 0,
1082
- fontFamily: theme?.fontFamily,
1083
- }}
1084
- >
1085
- {elem.fieldType}
1086
- </div>
1087
- </div>
1088
- ))}
1089
- </div>
1090
- ) : null}
1091
- </div>
1092
- );
1093
- }