@quillsql/react 2.6.1 → 2.6.3

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 (56) hide show
  1. package/lib/AddToDashboardModal.js +136 -243
  2. package/lib/AddToDashboardModal.js.map +1 -1
  3. package/lib/Chart.js +106 -139
  4. package/lib/Chart.js.map +1 -1
  5. package/lib/ChartBuilder.d.ts +36 -0
  6. package/lib/ChartBuilder.js +612 -0
  7. package/lib/ChartBuilder.js.map +1 -0
  8. package/lib/ChartEditor.d.ts +20 -0
  9. package/lib/ChartEditor.js +75 -0
  10. package/lib/ChartEditor.js.map +1 -0
  11. package/lib/Dashboard.d.ts +1 -0
  12. package/lib/Dashboard.js +38 -67
  13. package/lib/Dashboard.js.map +1 -1
  14. package/lib/DateRangePicker/dateRangePickerUtils.d.ts +1 -0
  15. package/lib/DateRangePicker/dateRangePickerUtils.js +6 -1
  16. package/lib/DateRangePicker/dateRangePickerUtils.js.map +1 -1
  17. package/lib/QuillProvider.d.ts +1 -0
  18. package/lib/QuillProvider.js +1 -0
  19. package/lib/QuillProvider.js.map +1 -1
  20. package/lib/ReportBuilder.d.ts +24 -34
  21. package/lib/ReportBuilder.js +248 -893
  22. package/lib/ReportBuilder.js.map +1 -1
  23. package/lib/SQLEditor.d.ts +5 -1
  24. package/lib/SQLEditor.js +91 -163
  25. package/lib/SQLEditor.js.map +1 -1
  26. package/lib/Table.js +56 -108
  27. package/lib/Table.js.map +1 -1
  28. package/lib/assets/XIcon.d.ts +4 -0
  29. package/lib/assets/XIcon.js +6 -0
  30. package/lib/assets/XIcon.js.map +1 -0
  31. package/lib/assets/index.d.ts +4 -0
  32. package/lib/assets/index.js +9 -1
  33. package/lib/assets/index.js.map +1 -1
  34. package/lib/components/QuillCard.d.ts +5 -2
  35. package/lib/components/QuillCard.js +43 -5
  36. package/lib/components/QuillCard.js.map +1 -1
  37. package/lib/components/UiComponents.d.ts +112 -0
  38. package/lib/components/UiComponents.js +255 -0
  39. package/lib/components/UiComponents.js.map +1 -0
  40. package/lib/hooks/useQuill.d.ts +1 -0
  41. package/lib/hooks/useQuill.js +15 -59
  42. package/lib/hooks/useQuill.js.map +1 -1
  43. package/lib/index.d.ts +2 -0
  44. package/lib/index.js +5 -1
  45. package/lib/index.js.map +1 -1
  46. package/lib/internals/ReportBuilder/PivotList.d.ts +27 -3
  47. package/lib/internals/ReportBuilder/PivotList.js +49 -39
  48. package/lib/internals/ReportBuilder/PivotList.js.map +1 -1
  49. package/lib/internals/ReportBuilder/PivotModal.d.ts +33 -3
  50. package/lib/internals/ReportBuilder/PivotModal.js +318 -226
  51. package/lib/internals/ReportBuilder/PivotModal.js.map +1 -1
  52. package/lib/internals/ReportBuilder/PivotModal.spec.js +19 -0
  53. package/lib/internals/ReportBuilder/PivotModal.spec.js.map +1 -1
  54. package/lib/utils/aggregate.js +1 -0
  55. package/lib/utils/aggregate.js.map +1 -1
  56. package/package.json +6 -3
@@ -0,0 +1,612 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.numberFormatOptions = exports.snakeCaseToTitleCase = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = require("react");
9
+ const Context_1 = require("./Context");
10
+ const dataFetcher_1 = require("./utils/dataFetcher");
11
+ const ReportBuilder_1 = require("./ReportBuilder");
12
+ const PivotModal_1 = require("./internals/ReportBuilder/PivotModal");
13
+ const dateRangePickerUtils_1 = require("./DateRangePicker/dateRangePickerUtils");
14
+ const PivotList_1 = require("./internals/ReportBuilder/PivotList");
15
+ const Chart_1 = __importDefault(require("./Chart"));
16
+ const UiComponents_1 = require("./components/UiComponents");
17
+ const CHART_TYPES = ['column', 'line', 'table', 'metric', 'bar', 'pie'];
18
+ function snakeCaseToTitleCase(str) {
19
+ if (!str) {
20
+ return str;
21
+ }
22
+ return str
23
+ .toString()
24
+ .split(/_| /)
25
+ .map(word => word === 'id'
26
+ ? 'ID'
27
+ : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
28
+ .join(' ');
29
+ }
30
+ exports.snakeCaseToTitleCase = snakeCaseToTitleCase;
31
+ const POSTGRES_DATE_TYPES = [
32
+ 'timestamp',
33
+ 'date',
34
+ 'timestamptz',
35
+ 'time',
36
+ 'timetz',
37
+ ];
38
+ async function getReferencedTables(client, sqlQuery, dbTables) {
39
+ // const parser = new Parser();
40
+ const tables = [];
41
+ const withAliases = [];
42
+ const resp = await (0, dataFetcher_1.getDataFromCloud)(client, `astify`, { query: sqlQuery });
43
+ let ast = resp.ast;
44
+ ast = ast.length ? ast[0] : ast;
45
+ if (ast.with && ast.with.length) {
46
+ for (let i = 0; i < ast.with.length; i++) {
47
+ withAliases.push(ast.with[i].name.value);
48
+ for (let j = 0; j < ast.with[i].stmt.from.length; j++)
49
+ tables.push(ast.with[i].stmt.from[j].table);
50
+ }
51
+ }
52
+ const tablesInQuery = [...tables, ...ast.from.map(elem => elem.table)].filter(elem => !withAliases.includes(elem));
53
+ return dbTables
54
+ .filter(table => tablesInQuery.includes(table.displayName))
55
+ .map(table => {
56
+ return {
57
+ name: table.displayName,
58
+ columns: table.columns.filter(column => POSTGRES_DATE_TYPES.includes(column.fieldType)),
59
+ };
60
+ })
61
+ .filter(table => table.columns.length > 0);
62
+ }
63
+ const AGGREGATION_TYPES = [
64
+ { label: 'sum', value: 'sum' },
65
+ { label: 'count', value: 'count' },
66
+ { label: 'average', value: 'avg' },
67
+ ];
68
+ exports.numberFormatOptions = [
69
+ 'whole_number',
70
+ 'one_decimal_place',
71
+ 'two_decimal_places',
72
+ 'dollar_amount',
73
+ 'dollar_cents',
74
+ ];
75
+ const NUMBER_FORMAT_OPTIONS = [
76
+ { value: 'whole_number', label: 'whole number' },
77
+ { value: 'one_decimal_place', label: 'one decimal place' },
78
+ { value: 'two_decimal_places', label: 'two decimal places' },
79
+ { value: 'dollar_amount', label: 'dollar amount' },
80
+ { value: 'dollar_cents', label: 'dollar and cent amount' },
81
+ ];
82
+ const formatOptions = [
83
+ ...NUMBER_FORMAT_OPTIONS,
84
+ { value: 'MMM_yyyy', label: 'month' },
85
+ { value: 'MMM_dd-MMM_dd', label: 'week' },
86
+ { value: 'MMM_dd_yyyy', label: 'day' },
87
+ { value: 'MMM_dd_hh:mm_ap_pm', label: 'day and time' },
88
+ { value: 'hh_ap_pm', label: 'hour' },
89
+ { value: 'percent', label: 'percent' },
90
+ { value: 'string', label: 'string' },
91
+ ];
92
+ function ChartBuilder(props) {
93
+ const [theme] = (0, react_1.useContext)(Context_1.ThemeContext);
94
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: props.Modal ? ((0, jsx_runtime_1.jsx)(props.Modal, { isOpen: props.isOpen, setIsOpen: props.setIsOpen, title: 'Add to dashboard', onClose: () => props.setIsOpen(false), theme: theme, children: (0, jsx_runtime_1.jsx)(ChartBuilderForm, { ...props }) })) : ((0, jsx_runtime_1.jsx)(UiComponents_1.MemoizedModal, { setIsOpen: props.setIsOpen, isOpen: props.isOpen, onClose: () => props.setIsOpen(false), title: 'Add to dashboard', theme: theme, children: (0, jsx_runtime_1.jsx)(ChartBuilderForm, { ...props }) })) }));
95
+ }
96
+ exports.default = ChartBuilder;
97
+ function ChartBuilderForm({ TextInput = UiComponents_1.MemoizedTextInput, Select = UiComponents_1.MemoizedSelect, Button = UiComponents_1.MemoizedButton, SecondaryButton = UiComponents_1.MemoizedSecondaryButton, Header = UiComponents_1.MemoizedHeader, Label = UiComponents_1.MemoizedLabel, DeleteButton = UiComponents_1.MemoizedDeleteButton, Text = UiComponents_1.MemoizedText, Modal = UiComponents_1.MemoizedModal, Popover = UiComponents_1.MemoizedPopover, isOpen, pivot, setIsOpen, rows, columns, query, dateRange: dr, formHeaderStyle, formLabelStyle, showTableFormatOptions = false, showDateFieldOptions = false, showAccessControlOptions = false, onAddToDashboardComplete, fields: fieldsProp, dashboardItem = undefined, recommendedPivots: rp = [], createdPivots: cp = [], }) {
98
+ const dateRange = dr || (0, dateRangePickerUtils_1.getRangeFromPreset)('90d');
99
+ const [client] = (0, react_1.useContext)(Context_1.ClientContext);
100
+ const [theme] = (0, react_1.useContext)(Context_1.ThemeContext);
101
+ const [schema, setSchema] = (0, react_1.useContext)(Context_1.SchemaContext);
102
+ const [isSubmitting, setIsSubmitting] = (0, react_1.useState)(false);
103
+ const [divWidth, setDivWidth] = (0, react_1.useState)(0);
104
+ const { dispatch } = (0, react_1.useContext)(Context_1.DashboardContext);
105
+ const fields = fieldsProp?.map(field => ({
106
+ field: field.name,
107
+ type: (0, ReportBuilder_1.getPostgresBasicType)(field),
108
+ format: field.format,
109
+ label: field.name,
110
+ })) || [];
111
+ const parentRef = (0, react_1.useRef)();
112
+ const deleteRef = (0, react_1.useRef)();
113
+ const modalPadding = 20;
114
+ const deleteButtonMargin = -13;
115
+ (0, react_1.useEffect)(() => {
116
+ const calculateWidth = () => {
117
+ return (parentRef.current.offsetWidth -
118
+ (deleteRef?.current
119
+ ? deleteRef?.current.offsetWidth - deleteButtonMargin
120
+ : 0));
121
+ };
122
+ // Measure the width of the div and update state
123
+ if (parentRef.current) {
124
+ setDivWidth(calculateWidth());
125
+ }
126
+ // Optional: Handle window resize
127
+ const handleResize = () => {
128
+ if (parentRef.current) {
129
+ setDivWidth(calculateWidth());
130
+ }
131
+ };
132
+ window.addEventListener('resize', handleResize);
133
+ // Cleanup listener
134
+ return () => {
135
+ window.removeEventListener('resize', handleResize);
136
+ };
137
+ }, []);
138
+ // get schema
139
+ (0, react_1.useEffect)(() => {
140
+ let isSubscribed = true;
141
+ async function getSchema() {
142
+ if (!schema || !schema.length) {
143
+ const resp = await (0, dataFetcher_1.getDataFromCloud)(client, `schema2/${client.publicKey}/`, null, 'GET');
144
+ if (isSubscribed) {
145
+ setSchema(resp.tables);
146
+ }
147
+ }
148
+ }
149
+ if (isSubscribed) {
150
+ getSchema();
151
+ }
152
+ return () => {
153
+ isSubscribed = false;
154
+ };
155
+ }, [schema]);
156
+ // get dashboards
157
+ const [dashboardOptions, setDashboardOptions] = (0, react_1.useState)([]);
158
+ const [defaultDashboardName, setDefaultDashboardName] = (0, react_1.useState)(dashboardItem?.dashboardName || dashboardOptions[0]?.label);
159
+ (0, react_1.useEffect)(() => {
160
+ if (!dashboardItem && dashboardOptions && dashboardOptions.length) {
161
+ setDefaultDashboardName(dashboardOptions[0]?.label);
162
+ }
163
+ }, [dashboardOptions]);
164
+ (0, react_1.useEffect)(() => {
165
+ async function getDashNames() {
166
+ const resp = await (0, dataFetcher_1.getDataFromCloud)(client, `dashnames/${client.publicKey}/`, null, 'GET');
167
+ setDashboardOptions(resp.dashboardNames
168
+ .filter(elem => elem !== null)
169
+ .map(key => ({ label: key, value: key })));
170
+ }
171
+ getDashNames();
172
+ }, []);
173
+ const [showPivotPopover, setShowPivotPopover] = (0, react_1.useState)(false);
174
+ const [isEdittingPivot, setIsEdittingPivot] = (0, react_1.useState)(false);
175
+ const [selectedPivotIndex, setSelectedPivotIndex] = (0, react_1.useState)(-1);
176
+ const [tableName, setTableName] = (0, react_1.useState)(null);
177
+ const selectedTable = schema?.find(t => t.displayName === tableName);
178
+ const [pivotPopUpTitle, setPivotPopUpTitle] = (0, react_1.useState)('Add Pivot');
179
+ const [createdPivots, setCreatedPivots] = (0, react_1.useState)(pivot ? [pivot] : dashboardItem?.pivot ? [dashboardItem.pivot] : cp);
180
+ const [recommendedPivots, setRecommendedPivots] = (0, react_1.useState)(rp);
181
+ const [pivotRowField, setPivotRowField] = (0, react_1.useState)(undefined);
182
+ const [pivotColumnField, setPivotColumnField] = (0, react_1.useState)(undefined);
183
+ const [pivotValueField, setPivotValueField] = (0, react_1.useState)(undefined);
184
+ const [pivotAggregation, setPivotAggregation] = (0, react_1.useState)(undefined);
185
+ // initial state is the fields array passed in, but can eventually be changed to be the pivot fields
186
+ const [fieldOptions, setFieldOptions] = (0, react_1.useState)(fields);
187
+ const [dateFieldOptions, setDateFieldOptions] = (0, react_1.useState)([]);
188
+ (0, react_1.useEffect)(() => {
189
+ const fetchReferencedTables = async () => {
190
+ if (!query) {
191
+ return;
192
+ }
193
+ const result = await getReferencedTables(client, query, schema);
194
+ setDateFieldOptions(result);
195
+ setTableName(result[0]?.name);
196
+ if (!formData.dateField.table) {
197
+ setFormData({
198
+ ...formData,
199
+ dateField: {
200
+ table: result[0]?.name,
201
+ field: result[0]?.columns[0]?.name,
202
+ },
203
+ });
204
+ }
205
+ };
206
+ fetchReferencedTables();
207
+ }, [query, schema]);
208
+ const defaultDateField = {
209
+ table: dateFieldOptions[0]?.name,
210
+ field: dateFieldOptions[0]?.columns[0]?.name,
211
+ };
212
+ const firstNumberColumn = columns?.find(col => exports.numberFormatOptions.includes(col.format));
213
+ const formEmptyState = {
214
+ name: '',
215
+ dashboardName: dashboardOptions?.[0]?.label,
216
+ columns: columns.map(col => {
217
+ return { ...col, label: snakeCaseToTitleCase(col.label) };
218
+ }),
219
+ xAxisField: columns?.[0]?.field || '',
220
+ xAxisFormat: columns?.[0]?.format || '',
221
+ yAxisFields: [
222
+ {
223
+ field: firstNumberColumn?.field || columns?.[0]?.field || '',
224
+ label: '',
225
+ format: firstNumberColumn?.format || columns?.[0]?.field || '',
226
+ },
227
+ ],
228
+ xAxisLabel: '',
229
+ chartType: firstNumberColumn ? 'line' : 'table',
230
+ pivot: null,
231
+ dateField: defaultDateField,
232
+ template: false,
233
+ };
234
+ const pivotFormData = pivot => {
235
+ const yAxisField = pivot.columnField || pivot.valueField;
236
+ // date labels for pivots should be treated like strings since they are
237
+ // formatted in generatePivotTable
238
+ const yAxisIsDate = pivot.columnField
239
+ ? (0, PivotModal_1.isDateField)(pivot.columnFieldType)
240
+ : false;
241
+ return {
242
+ pivot,
243
+ chartType: 'column',
244
+ xAxisField: pivot.rowField,
245
+ xAxisFormat: (0, PivotModal_1.isDateField)(pivot.rowFieldType)
246
+ ? 'string'
247
+ : columns.find(col => col.field === pivot.rowField)?.format ||
248
+ 'whole_number',
249
+ xAxisLabel: '',
250
+ yAxisFields: [
251
+ {
252
+ field: yAxisField,
253
+ label: '',
254
+ format: yAxisIsDate
255
+ ? 'string'
256
+ : columns.find(col => col.field === yAxisField)?.format ||
257
+ 'whole_number',
258
+ },
259
+ ],
260
+ };
261
+ };
262
+ const [formData, setFormData] = (0, react_1.useState)(pivot
263
+ ? { ...formEmptyState, ...pivotFormData(pivot) }
264
+ : dashboardItem || formEmptyState);
265
+ const selectedPivotTable = (0, react_1.useMemo)(() => {
266
+ if (formData.pivot && rows) {
267
+ return (0, PivotModal_1.generatePivotTable)(formData.pivot, rows, dateRange);
268
+ }
269
+ else {
270
+ return {};
271
+ }
272
+ }, [formData.pivot, rows]);
273
+ const handleChange = (value, fieldName, index) => {
274
+ if (index !== undefined) {
275
+ // For dynamic array fields
276
+ const [field, subfield] = fieldName.split('.');
277
+ const updatedArray = formData[field].map((item, i) => i === index ? { ...item, [subfield]: value } : item);
278
+ setFormData({ ...formData, [field]: updatedArray });
279
+ }
280
+ else if (fieldName.includes('.')) {
281
+ // For nested fields
282
+ const [field, subfield] = fieldName.split('.');
283
+ if (field === 'pivot' && subfield !== '') {
284
+ const subfieldTypeFieldName = subfield + 'Type';
285
+ if (value.length) {
286
+ const subfieldType = fields.find(field => field.field === value).type;
287
+ setFormData({
288
+ ...formData,
289
+ [field]: {
290
+ ...formData[field],
291
+ [subfield]: value,
292
+ [subfieldTypeFieldName]: subfieldType,
293
+ },
294
+ });
295
+ return;
296
+ }
297
+ else {
298
+ setFormData({
299
+ ...formData,
300
+ [field]: {
301
+ ...formData[field],
302
+ [subfield]: '',
303
+ [subfieldTypeFieldName]: '',
304
+ },
305
+ });
306
+ return;
307
+ }
308
+ }
309
+ if (field === 'dateField' &&
310
+ subfield === 'table' &&
311
+ !formData.dateField.field) {
312
+ const field = schema?.find(elem => elem.name === value)?.columns?.[0]
313
+ ?.name;
314
+ setFormData({
315
+ ...formData,
316
+ dateField: { ...formData[field], [subfield]: value, field: field },
317
+ });
318
+ return;
319
+ }
320
+ setFormData({
321
+ ...formData,
322
+ [field]: { ...formData[field], [subfield]: value },
323
+ });
324
+ }
325
+ else {
326
+ // For simple fields
327
+ setFormData({ ...formData, [fieldName]: value });
328
+ }
329
+ };
330
+ const handleAddPivot = (pivot, index) => {
331
+ setFormData(formData => ({
332
+ ...formData,
333
+ ...pivotFormData(pivot),
334
+ }));
335
+ };
336
+ const handleDeletePivot = () => {
337
+ if (!formData.pivot) {
338
+ return;
339
+ }
340
+ setFormData({ ...formEmptyState, pivot: null });
341
+ };
342
+ const handleAddField = fieldName => {
343
+ if (fieldName === 'columns') {
344
+ setFormData({
345
+ ...formData,
346
+ columns: [...formData.columns, { label: '', field: '', format: '' }],
347
+ });
348
+ }
349
+ else if (fieldName === 'yAxisFields') {
350
+ setFormData({
351
+ ...formData,
352
+ yAxisFields: [
353
+ ...formData.yAxisFields,
354
+ { label: '', field: '', chartType: '', format: '' },
355
+ ],
356
+ });
357
+ }
358
+ else if (fieldName === 'pivot') {
359
+ setFormData({
360
+ ...formData,
361
+ pivot: {
362
+ rowField: '',
363
+ rowFieldType: '',
364
+ columnField: '',
365
+ columnFieldType: '',
366
+ valueField: '',
367
+ aggregationType: '',
368
+ },
369
+ });
370
+ }
371
+ };
372
+ const handleRemoveField = (fieldName, index) => {
373
+ if (fieldName === 'pivot') {
374
+ setFormData({
375
+ ...formData,
376
+ pivot: null,
377
+ });
378
+ return;
379
+ }
380
+ const updatedArray = formData[fieldName].filter((_, i) => i !== index);
381
+ setFormData({ ...formData, [fieldName]: updatedArray });
382
+ };
383
+ const handleSubmit = e => {
384
+ e.preventDefault();
385
+ console.log(formData);
386
+ };
387
+ const editChart = async ({}) => {
388
+ if (isSubmitting) {
389
+ return;
390
+ }
391
+ setIsSubmitting(true);
392
+ const { publicKey, customerId } = client;
393
+ if (!client) {
394
+ return;
395
+ }
396
+ const cloudBody = {
397
+ ...formData,
398
+ ...(formData.dateField?.table
399
+ ? {}
400
+ : { dateField: { ...defaultDateField } }),
401
+ ...(formData.dashboardName
402
+ ? {}
403
+ : { dashboardName: defaultDashboardName }),
404
+ ...(dashboardItem ? { dashboardItemId: dashboardItem._id } : {}),
405
+ query,
406
+ pivot: formData.pivot,
407
+ };
408
+ // add orgId: customerId if present for hostedBody
409
+ // set defaultDateField if date field not present
410
+ const hostedBody = {
411
+ metadata: {
412
+ ...cloudBody,
413
+ ...(customerId ? { orgId: customerId } : {}),
414
+ },
415
+ };
416
+ const searchParams = new URLSearchParams(customerId
417
+ ? {
418
+ clientId: publicKey,
419
+ customerId: customerId,
420
+ }
421
+ : { clientId: publicKey }).toString();
422
+ const resp = await (0, dataFetcher_1.getData)(client, `dashedit2?${searchParams}`, 'same-origin', hostedBody, cloudBody);
423
+ if (resp) {
424
+ dispatch({
425
+ type: 'UPDATE_DASHBOARD_ITEM',
426
+ id: resp._id,
427
+ data: {
428
+ ...resp,
429
+ rows,
430
+ fields,
431
+ },
432
+ });
433
+ }
434
+ setIsOpen(false);
435
+ setIsSubmitting(false);
436
+ if (onAddToDashboardComplete) {
437
+ onAddToDashboardComplete();
438
+ }
439
+ };
440
+ if (!schema) {
441
+ return;
442
+ }
443
+ return ((0, jsx_runtime_1.jsxs)("div", { id: "quill-chart-modal", style: { padding: modalPadding }, children: [(0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(Chart_1.default, { config: { ...formData, rows }, colors: theme.chartColors, containerStyle: {
444
+ width: formData.chartType === 'table' ? 640 : 'calc(100% - 24px)',
445
+ height: 300,
446
+ } }) }), (0, jsx_runtime_1.jsx)("div", { style: { height: 20 } }), (0, jsx_runtime_1.jsxs)("form", { ref: parentRef, id: "quill-chart-form", onSubmit: handleSubmit, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'row', gap: 12 }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column' }, children: [(0, jsx_runtime_1.jsx)(Label, { children: "Name" }), (0, jsx_runtime_1.jsx)(TextInput, { value: formData.name, onChange: e => handleChange(e, 'name'), placeholder: "Name" })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column' }, children: [(0, jsx_runtime_1.jsx)(Label, { children: "Dashboard" }), (0, jsx_runtime_1.jsx)(Select, { label: 'Dashboard', value: formData.dashboardName, onChange: e => handleChange(e, 'dashboardName'), options: dashboardOptions.map(elem => ({
447
+ label: elem.label,
448
+ value: elem.label,
449
+ })) })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column' }, children: [(0, jsx_runtime_1.jsx)(Label, { children: "Chart type" }), (0, jsx_runtime_1.jsx)(Select, { label: 'Chart Type', value: formData.chartType, onChange: e => handleChange(e, 'chartType'),
450
+ // filter out metric for all pivots
451
+ // filter out bar and pie for row and column pivot
452
+ options: CHART_TYPES.filter(elem => !firstNumberColumn
453
+ ? elem === 'table'
454
+ : !((formData.pivot && elem === 'metric') ||
455
+ (formData.pivot &&
456
+ formData.pivot.columnField &&
457
+ (elem === 'bar' || elem === 'pie')))).map(elem => ({ label: elem, value: elem })) })] })] }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsxs)("div", { style: {
458
+ display: 'flex',
459
+ flexDirection: 'column',
460
+ gap: 12,
461
+ marginTop: 6,
462
+ }, children: [(0, jsx_runtime_1.jsx)(Header, { children: "Pivot" }), (0, jsx_runtime_1.jsxs)("div", { style: { fontFamily: theme?.fontFamily }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
463
+ maxWidth: 200,
464
+ // marginTop: 6,
465
+ display: 'flex',
466
+ flexDirection: 'column',
467
+ }, children: (0, jsx_runtime_1.jsx)(PivotModal_1.PivotModal, { pivotRowField: pivotRowField, setPivotRowField: setPivotRowField, pivotColumnField: pivotColumnField, setPivotColumnField: setPivotColumnField, pivotValueField: pivotValueField, setPivotValueField: setPivotValueField, pivotAggregation: pivotAggregation, setPivotAggregation: setPivotAggregation, createdPivots: createdPivots, setCreatedPivots: setCreatedPivots, recommendedPivots: recommendedPivots, setRecommendedPivots: setRecommendedPivots, popUpTitle: pivotPopUpTitle, setPopUpTitle: setPivotPopUpTitle, selectedTable: selectedTable, SelectComponent: Select, ButtonComponent: Button, PopoverComponent: Popover, LabelComponent: Label, TextComponent: Text, HeaderComponent: Header, theme: theme, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEdittingPivot, setShowUpdatePivot: setIsEdittingPivot, parentRef: parentRef, data: rows, columns: columns, triggerButtonText: 'Add pivot +', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: handleDeletePivot, selectPivot: handleAddPivot, dateRange: dateRange, selectPivotOnEdit: true, showTrigger: !formData.pivot }) }), formData.pivot && ((0, jsx_runtime_1.jsx)("div", { style: {
468
+ // width: 592,
469
+ paddingRight: deleteRef?.current ? 42 : 0,
470
+ maxWidth: 750,
471
+ }, children: (0, jsx_runtime_1.jsx)("div", { style: { width: divWidth }, children: (0, jsx_runtime_1.jsx)(PivotList_1.PivotCard, { pivotTable: {
472
+ pivot: formData.pivot,
473
+ rows: selectedPivotTable?.rows,
474
+ columns: selectedPivotTable?.columns,
475
+ }, theme: theme, index: 0, onSelectPivot: () => {
476
+ setIsEdittingPivot(true);
477
+ setShowPivotPopover(true);
478
+ setPivotRowField(formData.pivot?.rowField);
479
+ setPivotColumnField(formData.pivot?.columnField);
480
+ setPivotValueField(formData.pivot?.valueField);
481
+ setPivotAggregation(formData.pivot?.aggregationType);
482
+ setPivotPopUpTitle('Edit Pivot');
483
+ }, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: Button, HeaderComponent: Header, showEdit: false, onClose: handleDeletePivot, minHeight: 180, LabelComponent: Label, TextComponent: Text }) }) }))] })] }), (0, jsx_runtime_1.jsx)("br", {}), formData.chartType !== 'table' && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { style: {
484
+ display: 'flex',
485
+ flexDirection: 'column',
486
+ gap: 6,
487
+ marginTop: 6,
488
+ }, children: [(0, jsx_runtime_1.jsx)(Header, { children: "Chart" }), (0, jsx_runtime_1.jsx)(Label, { children: "X-axis" })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'row', gap: 12 }, children: [(0, jsx_runtime_1.jsx)(Select, { label: 'X-axis Field', value: formData.xAxisField, onChange: e => handleChange(e, 'xAxisField'), disabled: formData.pivot !== null, options: fieldOptions.map(elem => ({
489
+ label: formData.pivot
490
+ ? `pivot row (${elem.field})`
491
+ : elem.field,
492
+ value: elem.field,
493
+ })) }), (0, jsx_runtime_1.jsx)(TextInput, { value: formData.xAxisLabel, placeholder: "Column Label", onChange: e => handleChange(e, 'xAxisLabel') }), (0, jsx_runtime_1.jsx)(Select, { label: 'X-axis Format', value: formData.xAxisFormat, onChange: e => handleChange(e, 'xAxisFormat'), options: formatOptions })] }, 'xAxisField0'), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(Label, { children: "Y-axis" }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexDirection: 'column', gap: 10 }, children: formData.yAxisFields.map((yAxisField, index) => ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'row', gap: 12 }, children: [(0, jsx_runtime_1.jsx)(Select, { label: 'Y-axis Field', value: yAxisField.field, onChange: e => handleChange(e, 'yAxisFields.field', index), disabled: formData.pivot !== null, options: [
494
+ { label: 'Select', value: '' },
495
+ ...fieldOptions
496
+ .filter(elem => {
497
+ return (formData.chartType === 'table' ||
498
+ formData.pivot ||
499
+ exports.numberFormatOptions.includes(columns.find(col => col.field === elem.field)
500
+ ?.format));
501
+ })
502
+ .map(elem => ({
503
+ label: formData.pivot
504
+ ? `pivot columns (${elem.field})`
505
+ : elem.field,
506
+ value: elem.field,
507
+ })),
508
+ ] }), (0, jsx_runtime_1.jsx)(TextInput, { value: yAxisField.label, placeholder: "Column Label", onChange: e => handleChange(e, 'yAxisFields.label', index) }), (0, jsx_runtime_1.jsx)(Select, { label: 'Y-axis Format', value: yAxisField.format, onChange: e => handleChange(e, 'yAxisFields.format', index), options: [{ label: 'Select', value: '' }, ...formatOptions] }), formData.pivot === null && ((0, jsx_runtime_1.jsx)("div", { ref: deleteRef, children: (0, jsx_runtime_1.jsx)(DeleteButton, { style: { marginLeft: deleteButtonMargin }, onClick: () => handleRemoveField('yAxisFields', index) }) }))] }, 'yAxisField' + index))) }), formData.pivot === null && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => handleAddField('yAxisFields'), label: "Add field +" })] })), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("br", {})] })), (showTableFormatOptions || formData.chartType === 'table') && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { style: {
509
+ display: 'flex',
510
+ flexDirection: 'column',
511
+ gap: 6,
512
+ marginTop: 6,
513
+ }, children: [(0, jsx_runtime_1.jsx)(Header, { children: "Table" }), (0, jsx_runtime_1.jsx)(Label, { children: "Columns" })] }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexDirection: 'column', gap: 10 }, children: formData.columns.map((column, index) => ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'row', gap: 12 }, children: [(0, jsx_runtime_1.jsx)(Select, { label: 'Column Field', value: column.field, onChange: e => handleChange(e, 'columns.field', index), options: [
514
+ { label: 'Select', value: '' },
515
+ ...fields.map(elem => ({
516
+ label: elem.field,
517
+ value: elem.field,
518
+ })),
519
+ ] }), (0, jsx_runtime_1.jsx)(TextInput, { name: "label", value: column.label, placeholder: "Column Label", onChange: e => handleChange(e, 'columns.label', index) }), (0, jsx_runtime_1.jsx)(Select, { label: 'Column Format', value: column.format, onChange: e => handleChange(e, 'columns.format', index), options: [{ label: 'Select', value: '' }, ...formatOptions] }), (0, jsx_runtime_1.jsx)("div", { ref: deleteRef, children: (0, jsx_runtime_1.jsx)(DeleteButton, { style: { marginLeft: deleteButtonMargin }, onClick: () => handleRemoveField('columns', index) }) })] }, 'column' + index))) }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => handleAddField('columns'), label: "Add column +" }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("br", {})] })), showDateFieldOptions && ((0, jsx_runtime_1.jsxs)("div", { style: {
520
+ display: 'flex',
521
+ flexDirection: 'column',
522
+ gap: 6,
523
+ marginTop: 6,
524
+ }, children: [(0, jsx_runtime_1.jsx)(Header, { children: "Date field" }), (0, jsx_runtime_1.jsxs)("div", { style: {
525
+ display: 'flex',
526
+ flexDirection: 'row',
527
+ gap: 12,
528
+ // lmao part 2
529
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column' }, children: [(0, jsx_runtime_1.jsx)(Label, { children: "Table" }), (0, jsx_runtime_1.jsx)(Select, { label: 'Date Table', value: formData.dateField.table, onChange: e => handleChange(e, 'dateField.table'), options: [
530
+ {
531
+ label: 'Select',
532
+ value: '',
533
+ },
534
+ ...dateFieldOptions.map(elem => ({
535
+ label: elem.name,
536
+ value: elem.name,
537
+ })),
538
+ ] })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column' }, children: [(0, jsx_runtime_1.jsx)(Label, { children: "Field" }), (0, jsx_runtime_1.jsx)(Select, { label: 'Date Field', value: formData.dateField.field, onChange: e => handleChange(e, 'dateField.field'), options: schema
539
+ ?.find(elem => elem.name === formData.dateField.table)
540
+ ?.columns?.map(elem => ({
541
+ label: elem.name,
542
+ value: elem.name,
543
+ })) || [] })] })] }), (0, jsx_runtime_1.jsx)("br", {})] })), showAccessControlOptions && ((0, jsx_runtime_1.jsxs)("div", { style: {
544
+ display: 'flex',
545
+ flexDirection: 'column',
546
+ gap: 12,
547
+ marginTop: 6,
548
+ }, children: [(0, jsx_runtime_1.jsx)(Header, { children: "Organization access" }), (0, jsx_runtime_1.jsx)(SegmentedControl, { onChange: e => handleChange(e, 'template'), value: formData.template }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("br", {})] })), (0, jsx_runtime_1.jsx)("div", { style: {
549
+ display: 'flex',
550
+ flexDirection: 'row',
551
+ justifyContent: 'flex-end',
552
+ }, children: (0, jsx_runtime_1.jsx)(Button, { onClick: editChart, label: dashboardItem ? 'Edit' : 'Add to dashboard' }) })] })] }));
553
+ }
554
+ function SegmentedControl({ onChange, value }) {
555
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
556
+ display: 'flex',
557
+ flexDirection: 'row',
558
+ alignItems: 'center',
559
+ background: '#F5F5F6',
560
+ maxWidth: 418,
561
+ padding: 4,
562
+ borderRadius: 6,
563
+ }, children: [(0, jsx_runtime_1.jsxs)("button", { className: "quill-tab", onClick: () => onChange(true), style: {
564
+ border: value === true ? '1px solid #E7E7E7' : '1px solid transparent',
565
+ outline: 'none',
566
+ width: '100%',
567
+ borderRadius: 4,
568
+ padding: 10,
569
+ boxShadow: value === true
570
+ ? '0px 1px 4px 0px rgba(56, 65, 81, 0.08)'
571
+ : undefined,
572
+ color: value === true ? 'rgba(56, 65, 81, 1)' : 'rgba(56, 65, 81, 0.85)',
573
+ fontWeight: value === true ? 600 : 500,
574
+ fontSize: 14,
575
+ }, children: [(0, jsx_runtime_1.jsx)("style", { children: `
576
+ .quill-tab {
577
+ background-color: ${value === true ? 'white' : 'transparent'};
578
+ }
579
+ .quill-tab:hover {
580
+ background-color: ${value === false ? 'rgba(56, 65, 81, 0.05)' : undefined};
581
+ }
582
+ .quill-tab:active {
583
+ background-color: "rgba(56, 65, 81, 0.15)";
584
+ }
585
+ ` }), 'All Organizations'] }), (0, jsx_runtime_1.jsxs)("button", { className: "quill-tab2", onClick: () => onChange(false), style: {
586
+ border: value === false ? '1px solid #E7E7E7' : '1px solid transparent',
587
+ boxShadow: value === false
588
+ ? '0px 1px 4px 0px rgba(56, 65, 81, 0.08)'
589
+ : undefined,
590
+ outline: 'none',
591
+ width: '100%',
592
+ borderRadius: 4,
593
+ color: value === false ? 'rgba(56, 65, 81, 1)' : 'rgba(56, 65, 81, 0.85)',
594
+ padding: 10,
595
+ fontWeight: value === false ? 600 : 500,
596
+ fontSize: 14,
597
+ }, children: [(0, jsx_runtime_1.jsx)("style", { children: `
598
+ .quill-tab2 {
599
+ background-color: ${value === false ? 'white' : 'transparent'};
600
+ }
601
+ .quill-tab2:hover {
602
+ background-color: ${value === true ? 'rgba(56, 65, 81, 0.05)' : undefined};
603
+ }
604
+ .quill-tab2:focused {
605
+ background-color: blue;
606
+ }
607
+ .quill-tab2:active {
608
+ background-color: "rgba(56, 65, 81, 0.15)";
609
+ }
610
+ ` }), 'This organization'] })] }));
611
+ }
612
+ //# sourceMappingURL=ChartBuilder.js.map