@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
@@ -1,1213 +0,0 @@
1
- // @ts-nocheck
2
- import React, { useContext, useMemo, useEffect, useState } from 'react';
3
- import { ClientContext, SchemaContext, ThemeContext } from './Context';
4
- import BigModal from './components/BigModal/BigModal';
5
- import { Formik, Form, Field } from 'formik';
6
- import {
7
- differenceInDays,
8
- differenceInHours,
9
- differenceInMonths,
10
- differenceInYears,
11
- startOfDay,
12
- startOfHour,
13
- startOfMonth,
14
- startOfYear,
15
- } from 'date-fns';
16
- import axios from 'axios';
17
- import Chart from './Chart';
18
- import { XMarkIcon } from '@heroicons/react/20/solid';
19
- import { QuillTheme } from './QuillProvider';
20
-
21
- function convertPostgresColumn(column) {
22
- let format;
23
-
24
- switch (column.dataTypeID) {
25
- case 20: // int8
26
- case 21: // int2
27
- case 23: // int4
28
- format = 'whole_number';
29
- break;
30
- case 700: // float4
31
- case 701: // float8
32
- case 1700: // numeric
33
- format = 'two_decimal_places';
34
- break;
35
- case 1082: // date
36
- case 1083: // time
37
- case 1184: // timestamptz
38
- case 1114: // timestamp
39
- format = 'MMM_dd_yyyy';
40
- break;
41
- case 1043: // varchar
42
- default:
43
- format = 'string';
44
- }
45
-
46
- return {
47
- label: column.name,
48
- field: column.name,
49
- format: format,
50
- };
51
- }
52
-
53
- export default function AddToDashboardModal({
54
- isOpen,
55
- setIsOpen,
56
- SelectComponent,
57
- TextInputComponent,
58
- ButtonComponent,
59
- SecondaryButtonComponent,
60
- rows,
61
- columns,
62
- query,
63
- ModalComponent,
64
- formHeaderStyle,
65
- formLabelStyle,
66
- }) {
67
- const [theme] =
68
- useContext<[QuillTheme, (theme: QuillTheme) => void]>(ThemeContext);
69
- const [client] = useContext(ClientContext);
70
- const [schema, setSchema] = useContext(SchemaContext);
71
-
72
- useEffect(() => {
73
- let isSubscribed = true;
74
- async function getSchema() {
75
- const { publicKey, environment } = client;
76
- if (!schema.length) {
77
- const response3 = await axios.get(
78
- `https://quill-344421.uc.r.appspot.com/schema2/${publicKey}/`,
79
- {
80
- headers: {
81
- Authorization: `Bearer `,
82
- environment: environment || undefined,
83
- },
84
- }
85
- );
86
- if (isSubscribed) {
87
- setSchema(response3.data.tables);
88
- }
89
- }
90
- }
91
- if (isSubscribed) {
92
- getSchema();
93
- }
94
- return () => {
95
- isSubscribed = false;
96
- };
97
- }, [schema]);
98
-
99
- const editChart = async ({ report, values, yAxisFields, columns, query }) => {
100
- const { publicKey, orgId, authToken, queryEndpoint, queryHeaders } = client;
101
- const {
102
- xAxisLabel,
103
- yAxisLabel,
104
- chartName,
105
- chartType,
106
- xAxisField,
107
- xAxisFormat,
108
- dashboardName,
109
- dateFieldTable,
110
- dateField,
111
- } = values;
112
-
113
- if (!chartName) {
114
- alert('Please enter a chart name');
115
- return;
116
- }
117
-
118
- // if (!dashboardName) {
119
- // alert("Please choose a dashboard name");
120
- // return;
121
- // }
122
-
123
- // if (!xAxisLabel && chartType !== "pie" && chartType !== "table") {
124
- // alert("Please enter a label for the x-axis");
125
- // return;
126
- // }
127
-
128
- // if (!yAxisLabel && chartType !== "pie" && chartType !== "table") {
129
- // alert("Please enter a label for the y-axis");
130
- // return;
131
- // }
132
-
133
- for (let i = 0; i < yAxisFields.length; i++) {
134
- if (!yAxisFields[i].label && chartType !== 'pie') {
135
- alert(`Please enter a label for column '${yAxisFields[i].field}'`);
136
- return;
137
- }
138
- }
139
-
140
- if (!client || !organization) {
141
- return;
142
- }
143
-
144
- let response;
145
- if (queryEndpoint) {
146
- response = await axios.post(
147
- queryEndpoint,
148
- {
149
- metadata: {
150
- name: chartName,
151
- xAxisField,
152
- yAxisFields,
153
- xAxisLabel,
154
- xAxisFormat,
155
- yAxisLabel,
156
- chartType,
157
- dashboardName,
158
- columns,
159
- dateField: { table: dateFieldTable, field: dateField },
160
- query: query,
161
- task: 'create',
162
- },
163
- },
164
- { headers: queryHeaders }
165
- );
166
- } else {
167
- response = await axios.post(
168
- `https://quill-344421.uc.r.appspot.com/dashedit/${publicKey}/${orgId}/`,
169
- {
170
- name: chartName,
171
- xAxisField,
172
- yAxisFields,
173
- xAxisLabel,
174
- xAxisFormat,
175
- yAxisLabel,
176
- chartType,
177
- dashboardName,
178
- columns,
179
- dateField: { table: dateFieldTable, field: dateField },
180
- query: query,
181
- },
182
- {
183
- headers: {
184
- Authorization: `Bearer ${authToken}`,
185
- environment: environment || undefined,
186
- },
187
- }
188
- );
189
- }
190
- if (!response.data) {
191
- return;
192
- }
193
- // setDashboard((dashboard) => {
194
- // return {
195
- // ...dashboard,
196
- // [response.data._id]: { ...existingVisualization, ...response.data }
197
- // }
198
- // })
199
- setIsOpen(false);
200
- // TODO: fire callback instead so user can customize action
201
- // navigate("/dashboards");
202
- };
203
- return (
204
- // <BigModal theme={theme} showModal={isOpen} setShowModal={setIsOpen}>
205
- <ModalComponent
206
- isOpen={isOpen}
207
- title={'Add to dashboard'}
208
- onClose={() => setIsOpen(false)}
209
- >
210
- <ChartForm
211
- editChart={editChart}
212
- theme={theme}
213
- schema={schema}
214
- data={rows}
215
- fields={columns}
216
- // leave null for now
217
- report={null}
218
- query={query}
219
- // organizationName={organization?.name}
220
- SelectComponent={SelectComponent}
221
- TextInputComponent={TextInputComponent}
222
- ButtonComponent={ButtonComponent}
223
- SecondaryButtonComponent={SecondaryButtonComponent}
224
- formHeaderStyle={formHeaderStyle}
225
- formLabelStyle={formLabelStyle}
226
- />
227
- </ModalComponent>
228
- // </BigModal>
229
- );
230
- }
231
-
232
- function ChartForm({
233
- data,
234
- fields,
235
- theme,
236
- saveVisualization,
237
- report,
238
- editChart,
239
- schema,
240
- query,
241
- // organizationName,
242
- SelectComponent,
243
- TextInputComponent,
244
- ButtonComponent,
245
- SecondaryButtonComponent,
246
- formHeaderStyle,
247
- formLabelStyle,
248
- }) {
249
- const fieldOptions = Object.keys(data[0]).map(field => ({
250
- value: field,
251
- label: field,
252
- }));
253
- const [dateFieldOptions, setDateFieldOptions] = useState([]);
254
-
255
- useEffect(() => {
256
- const fetchReferencedTables = async () => {
257
- const result = await getReferencedTables(query, 'PostgresQL', schema);
258
- setDateFieldOptions(result);
259
- };
260
-
261
- fetchReferencedTables();
262
- }, [query, schema]);
263
-
264
- return (
265
- <Formik
266
- initialValues={{
267
- xAxisField: report?.xAxisField || fieldOptions[0].value,
268
- xAxisLabel: report?.xAxisLabel || '',
269
- xAxisFormat: report?.xAxisFormat || FORMAT_OPTIONS[0].value,
270
- yAxisLabel: report?.yAxisLabel || '',
271
- chartName: report?.name,
272
- chartType: report?.chartType || 'bar',
273
- xAxisFieldLabel: '',
274
- dashboardName: report?.dashboardName || '',
275
- dateFieldTable:
276
- (dateFieldOptions.length && dateFieldOptions[0].name) || '',
277
- dateField:
278
- (dateFieldOptions.length && dateFieldOptions[0].columns[0].name) ||
279
- '',
280
- template: report?.template || false,
281
- }}
282
- onSubmit={() => {}}
283
- >
284
- {({ values, isSubmitting, setFieldValue }) => (
285
- <FormikForm
286
- values={values}
287
- isSubmitting={isSubmitting}
288
- data={data}
289
- fieldOptions={fieldOptions}
290
- dateFieldOptions={dateFieldOptions}
291
- theme={theme}
292
- saveVisualization={saveVisualization}
293
- report={report}
294
- editChart={editChart}
295
- fields={fields}
296
- query={query}
297
- setFieldValue={setFieldValue}
298
- // organizationName={organizationName}
299
- SelectComponent={SelectComponent}
300
- TextInputComponent={TextInputComponent}
301
- ButtonComponent={ButtonComponent}
302
- SecondaryButtonComponent={SecondaryButtonComponent}
303
- formHeaderStyle={formHeaderStyle}
304
- formLabelStyle={formLabelStyle}
305
- />
306
- )}
307
- </Formik>
308
- );
309
- }
310
-
311
- export function isValidDate(d) {
312
- return d instanceof Date && !isNaN(d);
313
- }
314
-
315
- export const isArrayOfValidDates = (arr, field) =>
316
- arr.every(
317
- d => new Date(d[field]) instanceof Date && !isNaN(new Date(d[field]))
318
- );
319
-
320
- export function formatDateBuckets(startDate, endDate) {
321
- // Calculate the distance in hours
322
- const distanceInHours = Math.abs(differenceInHours(endDate, startDate));
323
-
324
- // Check if the distance is less than or equal to one hour
325
- if (distanceInHours <= 1) {
326
- return {
327
- unit: 'hour',
328
- format: 'h a',
329
- startOf: startOfHour,
330
- };
331
- }
332
-
333
- // Calculate the distance in days
334
- const distanceInDays = Math.abs(differenceInDays(endDate, startDate));
335
-
336
- // Check if the distance is less than or equal to one day
337
- if (distanceInDays <= 1) {
338
- return {
339
- unit: 'day',
340
- format: 'MMM d',
341
- startOf: startOfDay,
342
- };
343
- }
344
-
345
- // Calculate the distance in months
346
- const distanceInMonths = Math.abs(differenceInMonths(endDate, startDate));
347
-
348
- // Check if the distance is less than or equal to one month
349
- if (distanceInMonths <= 1) {
350
- return {
351
- unit: 'month',
352
- format: 'MMM yyyy',
353
- startOf: startOfMonth,
354
- };
355
- }
356
-
357
- // Calculate the distance in years
358
- const distanceInYears = Math.abs(differenceInYears(endDate, startDate));
359
-
360
- // Check if the distance is less than or equal to one year
361
- if (distanceInYears <= 1) {
362
- return {
363
- unit: 'year',
364
- format: 'yyyy',
365
- startOf: startOfYear,
366
- };
367
- }
368
-
369
- // Otherwise, the distance is more than one year
370
- return {
371
- unit: 'year',
372
- format: 'yyyy',
373
- startOf: startOfYear,
374
- };
375
- }
376
-
377
- const FormTextInput = ({ field, form, ...props }) => {
378
- const { theme, wider } = props;
379
- return (
380
- <input
381
- className={`px-[12px] text-sm h-[38px] py-1.5 shadow-sm w-[245px] border-[#E7E7E7] ${'text-[#212121]'} border-[1px] bg-[white] rounded-md`}
382
- type="text"
383
- {...field}
384
- {...props}
385
- />
386
- );
387
- };
388
-
389
- const POSTGRES_DATE_TYPES = [
390
- 'timestamp',
391
- 'date',
392
- 'timestamptz',
393
- 'time',
394
- 'timetz',
395
- ];
396
-
397
- async function getReferencedTables(sqlQuery, databaseType, dbTables) {
398
- // const parser = new Parser();
399
- let tables = [];
400
- let withAliases = [];
401
-
402
- const response = await axios.post(
403
- 'https://quill-344421.uc.r.appspot.com/astify',
404
- { query: sqlQuery }
405
- );
406
- let ast = response.data.ast;
407
- ast = ast.length ? ast[0] : ast;
408
-
409
- if (ast.with && ast.with.length) {
410
- for (let i = 0; i < ast.with.length; i++) {
411
- withAliases.push(ast.with[i].name.value);
412
- for (let j = 0; j < ast.with[i].stmt.from.length; j++)
413
- tables.push(ast.with[i].stmt.from[j].table);
414
- }
415
- }
416
- const tablesInQuery = [...tables, ...ast.from.map(elem => elem.table)].filter(
417
- elem => !withAliases.includes(elem)
418
- );
419
- return dbTables
420
- .filter(table => tablesInQuery.includes(table.displayName))
421
- .map(table => {
422
- return {
423
- name: table.displayName,
424
- columns: table.columns.filter(column =>
425
- POSTGRES_DATE_TYPES.includes(column.fieldType)
426
- ),
427
- };
428
- })
429
- .filter(table => table.columns.length > 0);
430
- }
431
-
432
- const FORMAT_OPTIONS = [
433
- { value: 'whole_number', label: 'whole number' },
434
- { value: 'one_decimal_place', label: 'one decimal place' },
435
- { value: 'dollar_amount', label: 'dollar amount' },
436
- { value: 'MMM_yyyy', label: 'month' },
437
- { value: 'MMM_dd-MMM_dd', label: 'week' },
438
- { value: 'MMM_dd_yyyy', label: 'day' },
439
- { value: 'MMM_dd_hh:mm_ap_pm', label: 'day and time' },
440
- { value: 'hh_ap_pm', label: 'hour' },
441
- { value: 'percent', label: 'percent' },
442
- { value: 'string', label: 'string' },
443
- ];
444
-
445
- function FormikForm({
446
- values,
447
- isSubmitting,
448
- data,
449
- fieldOptions,
450
- dateFieldOptions,
451
- theme,
452
- report,
453
- editChart,
454
- fields,
455
- query,
456
- SelectComponent,
457
- TextInputComponent,
458
- ButtonComponent,
459
- SecondaryButtonComponent,
460
- setFieldValue,
461
- organizationName,
462
- formHeaderStyle,
463
- formLabelStyle,
464
- }) {
465
- const [chartConfig, setChartConfig] = useState({});
466
- const [yAxisFields, setYAxisFields] = useState(
467
- report
468
- ? report.yAxisFields
469
- : [
470
- {
471
- field:
472
- fieldOptions.length > 1
473
- ? fieldOptions[1].value
474
- : fieldOptions[0].value,
475
- label: '',
476
- format: 'whole_number',
477
- },
478
- ]
479
- );
480
- const [columns, setColumns] = useState(
481
- report && report.columns.length
482
- ? report.columns
483
- : fields?.length
484
- ? fields.map(field => convertPostgresColumn(field))
485
- : []
486
- );
487
-
488
- const handleAddYAxisField = () => {
489
- setYAxisFields([
490
- ...yAxisFields,
491
- { label: '', field: '', format: 'whole_number' },
492
- ]);
493
- };
494
-
495
- const handleDeleteYAxisField = index => {
496
- setYAxisFields(yAxisFields => yAxisFields.filter((_, i) => index !== i));
497
- };
498
-
499
- const handleYAxisFieldChange = (index, value) => {
500
- const newYAxisFields = [...yAxisFields];
501
- newYAxisFields[index] = { ...newYAxisFields[index], field: value };
502
- setYAxisFields(newYAxisFields);
503
- };
504
-
505
- const handleYAxisFieldFormatChange = (index, value) => {
506
- const newYAxisFields = [...yAxisFields];
507
- newYAxisFields[index] = { ...newYAxisFields[index], format: value };
508
- setYAxisFields(newYAxisFields);
509
- };
510
-
511
- const handleYAxisFieldLabelChange = (index, value) => {
512
- const newYAxisFields = [...yAxisFields];
513
- newYAxisFields[index] = { ...newYAxisFields[index], label: value };
514
- setYAxisFields(newYAxisFields);
515
- };
516
-
517
- const handleColumnFieldChange = (index, value) => {
518
- const newColumns = [...columns];
519
- newColumns[index] = { ...newColumns[index], field: value };
520
- setColumns(newColumns);
521
- };
522
-
523
- const handleColumnFormatChange = (index, value) => {
524
- const newColumns = [...columns];
525
- newColumns[index] = { ...newColumns[index], format: value };
526
- setColumns(newColumns);
527
- };
528
-
529
- const handleColumnLabelChange = (index, value) => {
530
- const newColumns = [...columns];
531
- newColumns[index] = { ...newColumns[index], label: value };
532
- setColumns(newColumns);
533
- };
534
-
535
- useEffect(() => {
536
- setChartConfig({ ...values, yAxisFields: yAxisFields, rows: data });
537
- }, [values, yAxisFields]);
538
-
539
- // console.log('VIBE: ', { report, values, yAxisFields, columns, query });
540
-
541
- return (
542
- <Form style={{ display: 'inline-block' }}>
543
- <div style={{ display: 'flex', flexDirection: 'column' }}>
544
- <div
545
- style={{
546
- display: 'flex',
547
- flexDirection: 'column',
548
- }}
549
- >
550
- {/* <div
551
- style={{
552
- fontFamily: theme.fontFamily,
553
- color: theme.primaryTextColor,
554
- fontSize: 20,
555
- fontWeight: 600,
556
- }}
557
- >
558
- {report ? 'Edit chart' : 'Add to dashboard'}
559
- </div> */}
560
- <div style={{ height: 20 }} />
561
- <div style={{ marginLeft: -25 }}>
562
- {Object.keys(chartConfig).length > 0 && (
563
- <Chart
564
- chartId="646e37a660feef000be67a93"
565
- config={chartConfig} //TODO: resolve; this might be a problem
566
- colors={theme.chartColors}
567
- containerStyle={{
568
- width: '100%',
569
- height: 300,
570
- }}
571
- />
572
- )}
573
- </div>
574
- <div style={{ height: 20 }} />
575
- <div
576
- style={
577
- formHeaderStyle || {
578
- fontFamily: theme.fontFamily,
579
- color: theme.primaryTextColor,
580
- fontSize: theme.fontSize + 2,
581
- fontWeight: 600,
582
- marginTop: 20,
583
- }
584
- }
585
- >
586
- {'Chart'}
587
- </div>
588
- <div
589
- style={{
590
- display: 'flex',
591
- flexDirection: 'row',
592
- alignItems: 'center',
593
- }}
594
- >
595
- <div style={{ display: 'flex', flexDirection: 'column' }}>
596
- <div
597
- style={
598
- formLabelStyle || {
599
- fontSize: '14px',
600
- marginBottom: '6px',
601
- fontWeight: '600',
602
- marginTop: 8,
603
- color: theme.secondaryTextColor,
604
- fontFamily: theme?.fontFamily,
605
- }
606
- }
607
- >
608
- Name
609
- </div>
610
- <div style={{ minWidth: 200 }}>
611
- <Field
612
- name="chartName"
613
- component={TextInputComponent}
614
- theme={theme}
615
- wider
616
- />
617
- </div>
618
- </div>
619
- <div style={{ width: 20 }} />
620
- <div style={{ display: 'flex', flexDirection: 'column' }}>
621
- <div
622
- style={
623
- formLabelStyle || {
624
- fontFamily: theme.fontFamily,
625
- color: theme.secondaryTextColor,
626
- fontSize: theme.fontSize,
627
- fontWeight: theme.labelFontWeight,
628
- marginTop: 8,
629
- marginBottom: 6,
630
- }
631
- }
632
- >
633
- Dashboard name
634
- </div>
635
- <div style={{ minWidth: 200 }}>
636
- <Field
637
- name="dashboardName"
638
- component={TextInputComponent}
639
- theme={theme}
640
- wider
641
- />
642
- </div>
643
- </div>
644
- <div style={{ width: 20 }} />
645
- <div style={{ display: 'flex', flexDirection: 'column' }}>
646
- <div
647
- style={
648
- formLabelStyle || {
649
- fontFamily: theme.fontFamily,
650
- color: theme.secondaryTextColor,
651
- fontSize: theme.fontSize,
652
- fontWeight: theme.labelFontWeight,
653
- marginTop: 8,
654
- }
655
- }
656
- >
657
- Chart type
658
- </div>
659
- <div style={{ minWidth: 200 }}>
660
- <Field
661
- name="chartType"
662
- component={SelectComponent}
663
- theme={theme}
664
- options={[
665
- { label: 'bar', value: 'bar' },
666
- { label: 'line', value: 'line' },
667
- { label: 'column', value: 'column' },
668
- { label: 'pie', value: 'pie' },
669
- { label: 'metric', value: 'metric' },
670
- { label: 'table', value: 'table' },
671
- ]}
672
- />
673
- </div>
674
- </div>
675
- </div>
676
- </div>
677
- <div
678
- style={{
679
- display: 'flex',
680
- flexDirection: 'row',
681
- alignItems: 'center',
682
- // justifyContent: 'space-between',
683
- marginTop: 20,
684
- }}
685
- >
686
- {values.chartType !== 'table' && (
687
- <div style={{ display: 'flex', flexDirection: 'column' }}>
688
- <div
689
- style={
690
- formLabelStyle || {
691
- fontFamily: theme.fontFamily,
692
- color: theme.secondaryTextColor,
693
- fontSize: theme.fontSize,
694
- fontWeight: theme.labelFontWeight,
695
- }
696
- }
697
- >
698
- {values.chartType === 'pie'
699
- ? 'Category column'
700
- : 'x-axis column'}
701
- </div>
702
- <div style={{ height: 6 }} />
703
- <div
704
- style={{
705
- display: 'flex',
706
- flexDirection: 'row',
707
- alignItems: 'center',
708
- }}
709
- >
710
- <div style={{ minWidth: 200 }}>
711
- <Field
712
- name="xAxisField"
713
- component={SelectComponent}
714
- theme={theme}
715
- options={fieldOptions}
716
- />
717
- </div>
718
- {/* {fieldOptions.map((option) => (
719
- <option key={option.value} value={option.value}>
720
- {option.label}
721
- </option>
722
- ))}
723
- </Field> */}
724
- <div style={{ width: 20 }} />
725
- <div style={{ minWidth: 200 }}>
726
- <Field
727
- name="xAxisLabel"
728
- component={TextInputComponent}
729
- theme={theme}
730
- />
731
- </div>
732
- <div style={{ width: 20 }} />
733
- <div style={{ minWidth: 200 }}>
734
- <Field
735
- name="xAxisFormat"
736
- component={SelectComponent}
737
- theme={theme}
738
- options={FORMAT_OPTIONS}
739
- />
740
- </div>
741
- {/* {FORMAT_OPTIONS.map((option) => (
742
- <option key={option.value} value={option.value}>
743
- {option.label}
744
- </option>
745
- ))}
746
- </Field> */}
747
- </div>
748
- </div>
749
- )}
750
- </div>
751
- <div
752
- style={{
753
- display: 'flex',
754
- flexDirection: 'row',
755
- alignItems: 'flex-start',
756
- // justifyContent: 'space-between',
757
- marginTop: 20,
758
- }}
759
- >
760
- <div style={{ display: 'flex', flexDirection: 'column' }}>
761
- <div
762
- style={
763
- formLabelStyle || {
764
- fontFamily: theme.fontFamily,
765
- color: theme.secondaryTextColor,
766
- fontSize: theme.fontSize,
767
- fontWeight: theme.labelFontWeight,
768
- minWidth: 200,
769
- }
770
- }
771
- >
772
- {values.chartType === 'table'
773
- ? 'Columns'
774
- : values.chartType === 'pie'
775
- ? 'Quantity column'
776
- : 'y-axis columns'}
777
- </div>
778
- <div
779
- style={{
780
- display: 'flex',
781
- flexDirection: 'column',
782
- }}
783
- >
784
- {yAxisFields.map((yAxisField, index) => (
785
- <div
786
- key={`yAxisField-${index}`}
787
- style={{
788
- display: 'flex',
789
- flexDirection: 'row',
790
- alignItems: 'center',
791
- marginTop: index === 0 ? 6 : 10,
792
- }}
793
- >
794
- <div style={{ minWidth: 200 }}>
795
- <Field
796
- name={`yAxisField-${index}`}
797
- component={SelectComponent}
798
- theme={theme}
799
- value={yAxisField.field}
800
- onChange={option => handleYAxisFieldChange(index, option)}
801
- options={fieldOptions}
802
- />
803
- </div>
804
- </div>
805
- ))}
806
- {values.chartType !== 'pie' && (
807
- <div style={{ marginTop: 12 }}>
808
- <SecondaryButtonComponent
809
- onClick={handleAddYAxisField}
810
- label="Add column +"
811
- />
812
- </div>
813
- )}
814
- <div style={{ height: 10 }} />
815
- </div>
816
- </div>
817
- <div style={{ width: 20 }} />
818
- <div
819
- style={{
820
- display: 'flex',
821
- flexDirection: 'column',
822
- justifyContent: 'flex-start',
823
- }}
824
- >
825
- <div
826
- style={
827
- formLabelStyle || {
828
- fontFamily: theme.fontFamily,
829
- color: 'transparent',
830
- fontSize: theme.fontSize,
831
- fontWeight: theme.labelFontWeight,
832
- minWidth: 200,
833
- // marginBottom: 10,
834
- }
835
- }
836
- >
837
- y-axis label
838
- </div>
839
- {values.chartType !== 'pie' &&
840
- yAxisFields.map((yAxisField, index) => (
841
- <div
842
- key={`yAxisField-${index}`}
843
- style={{
844
- display: 'flex',
845
- flexDirection: 'row',
846
- alignItems: 'center',
847
- marginTop: index === 0 ? 6 : 10,
848
- }}
849
- >
850
- <div style={{ minWidth: 200 }}>
851
- <Field
852
- name={`yAxisField-${index}`}
853
- component={TextInputComponent}
854
- theme={theme}
855
- placeholder="Enter column label"
856
- value={yAxisField.label}
857
- onChange={event =>
858
- handleYAxisFieldLabelChange(index, event.target.value)
859
- }
860
- />
861
- </div>
862
- <div style={{ width: 20 }} />
863
- <div style={{ minWidth: 200 }}>
864
- <Field
865
- name={`yAxisFieldFormat-${index}`}
866
- component={SelectComponent}
867
- theme={theme}
868
- value={yAxisField.format}
869
- onChange={option =>
870
- handleYAxisFieldFormatChange(index, option)
871
- }
872
- options={FORMAT_OPTIONS}
873
- />
874
- </div>
875
- <div
876
- onClick={() =>
877
- index > 0 ? handleDeleteYAxisField(index) : undefined
878
- }
879
- style={{
880
- cursor: index > 0 ? 'pointer' : undefined,
881
- paddingLeft: 6,
882
- paddingTop: 12,
883
- paddingBottom: 12,
884
- paddingRight: 6,
885
- maxHeight: 38,
886
- display: 'flex',
887
- alignItems: 'center',
888
- justifyContent: 'center',
889
- }}
890
- >
891
- <XMarkIcon
892
- style={{
893
- height: '20px',
894
- width: '20px',
895
- color:
896
- index > 0
897
- ? theme?.secondaryTextColor
898
- : 'rgba(0,0,0,0)',
899
- }}
900
- aria-hidden="true"
901
- />
902
- </div>
903
- </div>
904
- ))}
905
- </div>
906
- </div>
907
- <div style={{ height: 20 }} />
908
- <div
909
- style={
910
- formHeaderStyle || {
911
- fontFamily: theme.fontFamily,
912
- color: theme.primaryTextColor,
913
- fontSize: theme.fontSize + 2,
914
- fontWeight: 600,
915
- }
916
- }
917
- >
918
- {'Table'}
919
- </div>
920
- <div
921
- style={{
922
- display: 'flex',
923
- flexDirection: 'row',
924
- alignItems: 'flex-start',
925
- // justifyContent: 'space-between',
926
- // marginTop: 8,
927
- }}
928
- >
929
- <div style={{ display: 'flex', flexDirection: 'column' }}>
930
- <div
931
- style={
932
- formLabelStyle || {
933
- fontFamily: theme.fontFamily,
934
- color: theme.secondaryTextColor,
935
- fontSize: theme.fontSize,
936
- fontWeight: theme.labelFontWeight,
937
- }
938
- }
939
- >
940
- {'Columns'}
941
- </div>
942
- <div
943
- style={{
944
- display: 'flex',
945
- flexDirection: 'column',
946
- }}
947
- >
948
- {columns.map((yAxisField, index) => (
949
- <div
950
- key={`column-${index}`}
951
- style={{
952
- display: 'flex',
953
- flexDirection: 'row',
954
- alignItems: 'center',
955
- marginTop: index === 0 ? 6 : 10,
956
- }}
957
- >
958
- <div style={{ minWidth: 200 }}>
959
- <Field
960
- name={`column-${index}`}
961
- component={SelectComponent}
962
- theme={theme}
963
- value={yAxisField.field}
964
- onChange={option =>
965
- handleColumnFieldChange(index, option)
966
- }
967
- options={fieldOptions}
968
- />
969
- </div>
970
- </div>
971
- ))}
972
- <div style={{ height: 10 }} />
973
- </div>
974
- </div>
975
- <div style={{ width: 20 }} />
976
- <div
977
- style={{
978
- display: 'flex',
979
- flexDirection: 'column',
980
- justifyContent: 'flex-start',
981
- }}
982
- >
983
- <div
984
- style={
985
- formLabelStyle || {
986
- fontFamily: theme.fontFamily,
987
- color: 'transparent',
988
- fontSize: theme.fontSize,
989
- fontWeight: theme.labelFontWeight,
990
- minWidth: 200,
991
- // marginBottom: 10,
992
- }
993
- }
994
- >
995
- label
996
- </div>
997
- {columns.map((yAxisField, index) => (
998
- <div
999
- key={`column-${index}`}
1000
- style={{
1001
- display: 'flex',
1002
- flexDirection: 'row',
1003
- alignItems: 'center',
1004
- marginTop: index === 0 ? 6 : 10,
1005
- }}
1006
- >
1007
- <div style={{ minWidth: 200 }}>
1008
- <Field
1009
- name={`columnlabel-${index}`}
1010
- component={TextInputComponent}
1011
- theme={theme}
1012
- placeholder="Enter column label"
1013
- value={yAxisField.label}
1014
- onChange={event =>
1015
- handleColumnLabelChange(index, event.target.value)
1016
- }
1017
- />
1018
- </div>
1019
- <div style={{ width: 20 }} />
1020
- <div style={{ minWidth: 200 }}>
1021
- <Field
1022
- name={`columnFormat-${index}`}
1023
- component={SelectComponent}
1024
- theme={theme}
1025
- value={yAxisField.format}
1026
- onChange={option => handleColumnFormatChange(index, option)}
1027
- options={FORMAT_OPTIONS}
1028
- />
1029
- </div>
1030
- {/* <div
1031
- style={{
1032
- cursor: index > 0 ? 'pointer' : undefined,
1033
- paddingLeft: 6,
1034
- paddingTop: 12,
1035
- paddingBottom: 12,
1036
- paddingRight: 6,
1037
- maxHeight: 38,
1038
- display: 'flex',
1039
- alignItems: 'center',
1040
- justifyContent: 'center',
1041
- }}
1042
- >
1043
- <XMarkIcon
1044
- style={{
1045
- height: '20px',
1046
- width: '20px',
1047
- color:
1048
- index > 0 ? theme?.secondaryTextColor : 'rgba(0,0,0,0)',
1049
- }}
1050
- aria-hidden="true"
1051
- />
1052
- </div> */}
1053
- </div>
1054
- ))}
1055
- </div>
1056
- </div>
1057
- <div style={{ height: 20 }} />
1058
- {/* <div
1059
- style={
1060
- formHeaderStyle || {
1061
- fontFamily: theme.fontFamily,
1062
- color: theme.primaryTextColor,
1063
- fontSize: theme.fontSize + 2,
1064
- fontWeight: 600,
1065
- // marginTop: 20,
1066
- }
1067
- }
1068
- >
1069
- {'Filters'}
1070
- </div>
1071
- <div
1072
- style={{
1073
- display: 'flex',
1074
- flexDirection: 'row',
1075
- alignItems: 'center',
1076
- }}
1077
- >
1078
- <div style={{ display: 'flex', flexDirection: 'column' }}>
1079
- <div
1080
- style={
1081
- formLabelStyle || {
1082
- fontFamily: theme.fontFamily,
1083
- color: theme.secondaryTextColor,
1084
- fontSize: theme.fontSize,
1085
- fontWeight: theme.labelFontWeight,
1086
- marginTop: 8,
1087
- marginBottom: 6,
1088
- }
1089
- }
1090
- >
1091
- Date field table
1092
- </div>
1093
- <div style={{ minWidth: 200 }}>
1094
- <Field
1095
- name="dateFieldTable"
1096
- component={SelectComponent}
1097
- theme={theme}
1098
- options={dateFieldOptions.map(elem => {
1099
- return { label: elem.name, value: elem.name };
1100
- })}
1101
- />
1102
- </div>
1103
- </div>
1104
- <div style={{ width: 20 }} />
1105
- <div style={{ display: 'flex', flexDirection: 'column' }}>
1106
- <div
1107
- style={
1108
- formLabelStyle || {
1109
- fontFamily: theme.fontFamily,
1110
- color: theme.secondaryTextColor,
1111
- fontSize: theme.fontSize,
1112
- fontWeight: theme.labelFontWeight,
1113
- marginTop: 8,
1114
- marginBottom: 6,
1115
- }
1116
- }
1117
- >
1118
- Date field
1119
- </div>
1120
- <div style={{ minWidth: 200 }}>
1121
- <Field
1122
- name="dateField"
1123
- component={SelectComponent}
1124
- theme={theme}
1125
- options={
1126
- dateFieldOptions.filter(
1127
- elem => elem.name === values.dateFieldTable
1128
- ).length
1129
- ? dateFieldOptions
1130
- .filter(elem => elem.name === values.dateFieldTable)[0]
1131
- .columns.map(elem => {
1132
- return { label: elem.name, value: elem.name };
1133
- })
1134
- : []
1135
- }
1136
- />
1137
- </div>
1138
- </div>
1139
- </div> */}
1140
- {/* <div
1141
- style={{
1142
- display: "flex",
1143
- flexDirection: "column",
1144
- // alignItems: "center",
1145
- // justifyContent: "space-between",
1146
- marginTop: 10,
1147
- marginBottom: 20,
1148
- }}
1149
- >
1150
- <div
1151
- style={{
1152
- fontFamily: theme.fontFamily,
1153
- color: theme.primaryTextColor,
1154
- fontSize: theme.fontSize + 2,
1155
- fontWeight: 600,
1156
- marginTop: 20,
1157
- marginBottom: 12,
1158
- }}
1159
- >
1160
- {"Access Control"}
1161
- </div>
1162
- <Tab.Group
1163
- className={`px-1 flex flex-row text-sm font-medium py-1 h-[38px] w-[500px] border-[#E7E7E7] ${"text-[#212121]"} bg-[#212121]/[0.03] rounded-md`}
1164
- selectedIndex={values.template === true ? 1 : 0}
1165
- onChange={(index) => {
1166
- if (index === 0) {
1167
- setFieldValue("template", false);
1168
- } else {
1169
- setFieldValue("template", true);
1170
- }
1171
- }}
1172
- >
1173
- <Tab.List>
1174
- <Tab
1175
- className={({ selected }) =>
1176
- classNames(
1177
- "w-full rounded-md py-1 text-sm font-medium leading-5 text-[#212121]",
1178
- "ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-400 focus:outline-none focus:ring-2",
1179
- selected
1180
- ? "bg-white shadow"
1181
- : "hover:bg-white/[0.12] text-[#212121]/[.3]"
1182
- )
1183
- }
1184
- >
1185
- {`This Organization (${organizationName})`}
1186
- </Tab>
1187
- <Tab
1188
- className={({ selected }) =>
1189
- classNames(
1190
- "w-full rounded-md py-1 text-sm font-medium leading-5 text-[#212121]",
1191
- "ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-400 focus:outline-none focus:ring-2",
1192
- selected
1193
- ? "bg-white shadow"
1194
- : "hover:bg-white/[0.12] text-[#212121]/[.3]"
1195
- )
1196
- }
1197
- >
1198
- {"Global (All Organizations)"}
1199
- </Tab>
1200
- </Tab.List>
1201
- </Tab.Group>
1202
- </div> */}
1203
- <div style={{ height: 20 }} />
1204
- <ButtonComponent
1205
- onClick={() =>
1206
- editChart({ report, values, yAxisFields, columns, query })
1207
- }
1208
- label={report ? 'Save changes' : 'Add to dashboard'}
1209
- />
1210
- </div>
1211
- </Form>
1212
- );
1213
- }