@quillsql/admin 1.0.7 → 1.0.8
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.
- package/lib/Admin.d.ts +5 -1
- package/lib/Admin.js +813 -254
- package/lib/Admin.js.map +1 -1
- package/package.json +1 -1
package/lib/Admin.js
CHANGED
|
@@ -142,7 +142,336 @@ const defaultTheme = {
|
|
|
142
142
|
labelFontWeight: "500",
|
|
143
143
|
fontSize: 14,
|
|
144
144
|
};
|
|
145
|
-
function
|
|
145
|
+
function EditFiltersModal({ isOpen, dashboardData, selectedDashboard, client, setIsOpen, filters, dateFilter, openAddFilterModal, ModalComponent, TextInputComponent, ButtonComponent, HeaderComponent, SelectComponent, selectedEditDashboard, dashNames, setSelectedEditDashboard, }) {
|
|
146
|
+
const [selectedDashboardName, setSelectedDashboardName] = (0, react_1.useState)("");
|
|
147
|
+
(0, react_1.useEffect)(() => {
|
|
148
|
+
setSelectedDashboardName(selectedDashboard);
|
|
149
|
+
}, [selectedDashboard]);
|
|
150
|
+
const [newFilters, setNewFilters] = (0, react_1.useState)([]);
|
|
151
|
+
const [newDateFilter, setNewDateFilter] = (0, react_1.useState)(null);
|
|
152
|
+
const [tables] = (0, react_1.useContext)(TablesContext);
|
|
153
|
+
const [selectedTable, setSelectedTable] = (0, react_1.useState)(null);
|
|
154
|
+
const [field, setField] = (0, react_1.useState)("");
|
|
155
|
+
(0, react_1.useEffect)(() => {
|
|
156
|
+
if (tables.length) {
|
|
157
|
+
setSelectedTable(tables[0]);
|
|
158
|
+
setField(tables[0].columns.map((elem) => elem.name)[0]);
|
|
159
|
+
}
|
|
160
|
+
}, [tables]);
|
|
161
|
+
(0, react_1.useEffect)(() => {
|
|
162
|
+
if (dashboardData && dashboardData.filters) {
|
|
163
|
+
setNewFilters(dashboardData.filters);
|
|
164
|
+
}
|
|
165
|
+
if (dashboardData && dashboardData.dateFilter) {
|
|
166
|
+
setNewDateFilter(dashboardData.dateFilter);
|
|
167
|
+
}
|
|
168
|
+
}, [dashboardData]);
|
|
169
|
+
const handleAddFilter = async () => {
|
|
170
|
+
setNewFilters([...newFilters, { label: "", field }]);
|
|
171
|
+
};
|
|
172
|
+
const handleSubmitDashboardChanges = async () => {
|
|
173
|
+
if (!selectedDashboardName ||
|
|
174
|
+
newFilters.some((filter) => !filter.label) ||
|
|
175
|
+
(newDateFilter &&
|
|
176
|
+
Object.keys(newDateFilter).length &&
|
|
177
|
+
!newDateFilter.label)) {
|
|
178
|
+
alert("Empty fields");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (newFilters.filter((elem) => !elem.field).length) {
|
|
182
|
+
alert(`no filter field for: ${newFilters.filter((elem) => !elem.field)[0].label}`);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const updatedFilters = newFilters.map((filter) => {
|
|
186
|
+
const filterType = getPostgresBasicType(selectedTable.columns.find((col) => col.name === filter.field));
|
|
187
|
+
return {
|
|
188
|
+
table: selectedTable.name,
|
|
189
|
+
field: filter.field,
|
|
190
|
+
labelField: filter.field,
|
|
191
|
+
label: filter.label,
|
|
192
|
+
filterType,
|
|
193
|
+
};
|
|
194
|
+
});
|
|
195
|
+
if (dashNames &&
|
|
196
|
+
dashNames.length > 0 &&
|
|
197
|
+
dashNames.some((dashName) => dashName.name === selectedDashboardName &&
|
|
198
|
+
selectedDashboardName !== selectedDashboard)) {
|
|
199
|
+
alert("Dashboard name already taken!");
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const fieldsSet = new Set();
|
|
203
|
+
const hasDuplicateField = updatedFilters.some((filter) => {
|
|
204
|
+
if (fieldsSet.has(filter.field)) {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
fieldsSet.add(filter.field);
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
if (hasDuplicateField ||
|
|
213
|
+
(Object.keys(newDateFilter).length > 0 &&
|
|
214
|
+
updatedFilters.some((filter) => filter.filterType === "date"))) {
|
|
215
|
+
alert("Maximum of one filter per field");
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
let allValid = true;
|
|
219
|
+
updatedFilters.forEach((filter) => {
|
|
220
|
+
if (filter.filterType !== "string" && filter.filterType !== "date") {
|
|
221
|
+
allValid = false;
|
|
222
|
+
console.error(`Invalid filterType found: ${filter.filterType}`);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
if (!allValid) {
|
|
226
|
+
alert("We only support string and filters.");
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
let responseData;
|
|
230
|
+
const url = `https://quill-344421.uc.r.appspot.com/dashfilter/${client._id}/`;
|
|
231
|
+
const body = {
|
|
232
|
+
newDashboardName: selectedDashboardName,
|
|
233
|
+
filters: updatedFilters,
|
|
234
|
+
dateFilter: newDateFilter,
|
|
235
|
+
name: selectedDashboard,
|
|
236
|
+
};
|
|
237
|
+
const headers = {
|
|
238
|
+
"Content-Type": "application/json",
|
|
239
|
+
Authorization: `Bearer `,
|
|
240
|
+
};
|
|
241
|
+
try {
|
|
242
|
+
const response = await fetch(url, {
|
|
243
|
+
method: "POST",
|
|
244
|
+
headers: headers,
|
|
245
|
+
body: JSON.stringify(body),
|
|
246
|
+
});
|
|
247
|
+
setSelectedEditDashboard(null);
|
|
248
|
+
setIsOpen(false);
|
|
249
|
+
}
|
|
250
|
+
catch (e) {
|
|
251
|
+
console.log("error");
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
// const handleDeleteFilter = async () => {
|
|
255
|
+
// const url = `https://quill-344421.uc.r.appspot.com/dashfilterdelete/${client._id}/`;
|
|
256
|
+
// const body = {
|
|
257
|
+
// name: selectedDashboard.name,
|
|
258
|
+
// filterId: "DATE_RANGE", //TODO: Change this?
|
|
259
|
+
// };
|
|
260
|
+
// const headers = {
|
|
261
|
+
// "Content-Type": "application/json",
|
|
262
|
+
// Authorization: `Bearer `,
|
|
263
|
+
// };
|
|
264
|
+
// try {
|
|
265
|
+
// const response = await fetch(url, {
|
|
266
|
+
// method: "POST",
|
|
267
|
+
// headers: headers,
|
|
268
|
+
// body: JSON.stringify(body),
|
|
269
|
+
// });
|
|
270
|
+
// if (!response.ok) {
|
|
271
|
+
// throw new Error(`HTTP error! Status: ${response.status}`);
|
|
272
|
+
// }
|
|
273
|
+
// const responseData = await response.json();
|
|
274
|
+
// if (responseData) {
|
|
275
|
+
// setIsOpen(false);
|
|
276
|
+
// return;
|
|
277
|
+
// }
|
|
278
|
+
// } catch (error) {
|
|
279
|
+
// console.error("There was a problem with the fetch operation:", error);
|
|
280
|
+
// }
|
|
281
|
+
// };
|
|
282
|
+
const handleDeleteFilter = (filter) => {
|
|
283
|
+
setNewFilters(newFilters.filter((f) => f !== filter));
|
|
284
|
+
};
|
|
285
|
+
const handleDeleteDateFilter = async () => {
|
|
286
|
+
// const response2 = await axios.post(
|
|
287
|
+
// `https://quill-344421.uc.r.appspot.com/dashfilterdelete/${client._id}/`,
|
|
288
|
+
// {
|
|
289
|
+
// name: selectedDashboard.name,
|
|
290
|
+
// filterId: "DATE_RANGE",
|
|
291
|
+
// },
|
|
292
|
+
// { headers: { Authorization: `Bearer ` } }
|
|
293
|
+
// );
|
|
294
|
+
// if (response2 && response2.data) {
|
|
295
|
+
// setIsOpen(false);
|
|
296
|
+
// return;
|
|
297
|
+
// }
|
|
298
|
+
setNewDateFilter({});
|
|
299
|
+
};
|
|
300
|
+
return ((0, jsx_runtime_1.jsx)(ModalComponent, { isOpen: isOpen, close: () => {
|
|
301
|
+
setIsOpen(false);
|
|
302
|
+
}, children: (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
303
|
+
display: "flex",
|
|
304
|
+
flexDirection: "column",
|
|
305
|
+
// alignItems: "center",
|
|
306
|
+
}, children: [(0, jsx_runtime_1.jsx)(HeaderComponent, { label: "Edit filters" }), (0, jsx_runtime_1.jsx)("div", { children: "Dashboard name" }), (0, jsx_runtime_1.jsx)(TextInputComponent, { value: selectedDashboardName, onChange: (e) => setSelectedDashboardName(e.target.value) }), (0, jsx_runtime_1.jsxs)("div", { children: [newDateFilter &&
|
|
307
|
+
Object.values(newDateFilter).length > 0 &&
|
|
308
|
+
newDateFilter.label ? (
|
|
309
|
+
// <div style={{ display: "flex", flexDirection: "row" }}>
|
|
310
|
+
// <div style={{ display: "flex", flexDirection: "column" }}>
|
|
311
|
+
// <div>Label</div>
|
|
312
|
+
// <div>{dashboardData.dateFilter.label}</div>
|
|
313
|
+
// </div>
|
|
314
|
+
// <div style={{ display: "flex", flexDirection: "column" }}>
|
|
315
|
+
// <div>Initial date range</div>
|
|
316
|
+
// <div
|
|
317
|
+
// style={{
|
|
318
|
+
// display: "flex",
|
|
319
|
+
// flexDirection: "column",
|
|
320
|
+
// alignItems: "center",
|
|
321
|
+
// }}
|
|
322
|
+
// >
|
|
323
|
+
// <div>
|
|
324
|
+
// {dashboardData.dateFilter.initialRange === "LAST_90_DAYS"
|
|
325
|
+
// ? "Last 90 days"
|
|
326
|
+
// : ""}
|
|
327
|
+
// {dashboardData.dateFilter.initialRange === "LAST_30_DAYS"
|
|
328
|
+
// ? "Last 30 days"
|
|
329
|
+
// : ""}
|
|
330
|
+
// {dashboardData.dateFilter.initialRange === "CURRENT_MONTH"
|
|
331
|
+
// ? "This month"
|
|
332
|
+
// : ""}
|
|
333
|
+
// </div>
|
|
334
|
+
// <div
|
|
335
|
+
// // onClick={handleDeleteDateFilter}
|
|
336
|
+
// style={{
|
|
337
|
+
// height: 42,
|
|
338
|
+
// width: 42,
|
|
339
|
+
// alignItems: "center",
|
|
340
|
+
// justifyContent: "center",
|
|
341
|
+
// display: "flex",
|
|
342
|
+
// }}
|
|
343
|
+
// >
|
|
344
|
+
// {/* <svg
|
|
345
|
+
// xmlns="http://www.w3.org/2000/svg"
|
|
346
|
+
// viewBox="0 0 24 24"
|
|
347
|
+
// fill="#4C5462"
|
|
348
|
+
// width="20"
|
|
349
|
+
// height="20"
|
|
350
|
+
// >
|
|
351
|
+
// <path
|
|
352
|
+
// fill-rule="evenodd"
|
|
353
|
+
// d="M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z"
|
|
354
|
+
// clip-rule="evenodd"
|
|
355
|
+
// />
|
|
356
|
+
// </svg> */}
|
|
357
|
+
// </div>
|
|
358
|
+
// </div>
|
|
359
|
+
// </div>
|
|
360
|
+
// </div>
|
|
361
|
+
(0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", flexDirection: "row" }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", flexDirection: "column" }, children: [(0, jsx_runtime_1.jsx)("h2", { children: "Date Label" }), (0, jsx_runtime_1.jsx)(TextInputComponent, { value: newDateFilter.label, onChange: (e) => {
|
|
362
|
+
setNewDateFilter({
|
|
363
|
+
...newDateFilter,
|
|
364
|
+
label: e.target.value,
|
|
365
|
+
});
|
|
366
|
+
} })] }), (0, jsx_runtime_1.jsx)("div", { onClick: () => handleDeleteDateFilter(), style: {
|
|
367
|
+
height: 42,
|
|
368
|
+
width: 42,
|
|
369
|
+
alignItems: "center",
|
|
370
|
+
justifyContent: "center",
|
|
371
|
+
display: "flex",
|
|
372
|
+
}, children: (0, jsx_runtime_1.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "#4C5462", width: "20", height: "20", children: (0, jsx_runtime_1.jsx)("path", { "fill-rule": "evenodd", d: "M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z", clipRule: "evenodd" }) }) })] })) : null, newFilters.length > 0 &&
|
|
373
|
+
newFilters.map((filter, index) => {
|
|
374
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", flexDirection: "row" }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", flexDirection: "column" }, children: [(0, jsx_runtime_1.jsx)("h2", { children: "Label" }), (0, jsx_runtime_1.jsx)(TextInputComponent, { value: filter.label, onChange: (e) => {
|
|
375
|
+
const updatedFilters = newFilters.map((otherFilter, i) => index === i
|
|
376
|
+
? { ...otherFilter, label: e.target.value }
|
|
377
|
+
: otherFilter);
|
|
378
|
+
setNewFilters(updatedFilters);
|
|
379
|
+
} })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", flexDirection: "column" }, children: [(0, jsx_runtime_1.jsx)("h4", { children: "Field" }), (0, jsx_runtime_1.jsx)("div", { style: {
|
|
380
|
+
display: "flex",
|
|
381
|
+
flexDirection: "column",
|
|
382
|
+
alignItems: "center",
|
|
383
|
+
}, children: (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
384
|
+
display: "flex",
|
|
385
|
+
flexDirection: "row",
|
|
386
|
+
alignItems: "center",
|
|
387
|
+
}, children: [(0, jsx_runtime_1.jsx)(SelectComponent, { defaultValue: "", value: filter && filter.field ? filter.field : "", options: selectedTable.columns.map((column) => {
|
|
388
|
+
return { label: column.name, value: column.name };
|
|
389
|
+
}), onChange: (e) => {
|
|
390
|
+
const updatedFilters = newFilters.map((otherFilter, i) => index === i
|
|
391
|
+
? { ...otherFilter, field: e }
|
|
392
|
+
: otherFilter);
|
|
393
|
+
setNewFilters(updatedFilters);
|
|
394
|
+
} }), (0, jsx_runtime_1.jsx)("div", { onClick: () => handleDeleteFilter(filter), style: {
|
|
395
|
+
height: 42,
|
|
396
|
+
width: 42,
|
|
397
|
+
alignItems: "center",
|
|
398
|
+
justifyContent: "center",
|
|
399
|
+
display: "flex",
|
|
400
|
+
}, children: (0, jsx_runtime_1.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "#4C5462", width: "20", height: "20", children: (0, jsx_runtime_1.jsx)("path", { "fill-rule": "evenodd", d: "M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z", clipRule: "evenodd" }) }) })] }) })] })] }));
|
|
401
|
+
})] }), (0, jsx_runtime_1.jsx)(ButtonComponent, { onClick: handleAddFilter, label: "Add new filter +" }), (0, jsx_runtime_1.jsx)(ButtonComponent, { onClick: handleSubmitDashboardChanges, label: "Submit Dashboard Changes" })] }) }));
|
|
402
|
+
}
|
|
403
|
+
function AddFilterModal({ isOpen, selectedDashboard, client, setIsOpen, ModalComponent, TextInputComponent, SelectComponent, HeaderComponent, ButtonComponent, openAddDashboardModal, }) {
|
|
404
|
+
const [tables] = (0, react_1.useContext)(TablesContext);
|
|
405
|
+
const [selectedTable, setSelectedTable] = (0, react_1.useState)(null);
|
|
406
|
+
const [name, setName] = (0, react_1.useState)("");
|
|
407
|
+
const [field, setField] = (0, react_1.useState)("");
|
|
408
|
+
const [filterType, setFilterType] = (0, react_1.useState)("string");
|
|
409
|
+
const [dateRange, setDateRange] = (0, react_1.useState)([new Date(), new Date()]);
|
|
410
|
+
(0, react_1.useEffect)(() => {
|
|
411
|
+
if (tables.length) {
|
|
412
|
+
setSelectedTable(tables[0]);
|
|
413
|
+
// setField(tables[0].columns.map((elem) => elem.name));
|
|
414
|
+
setField(tables[0].columns[0].name);
|
|
415
|
+
}
|
|
416
|
+
}, [tables]);
|
|
417
|
+
const handleAddFilter = async () => {
|
|
418
|
+
if (!selectedTable || !field) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const filterType = getPostgresBasicType(selectedTable.columns.find((col) => col.name === field));
|
|
422
|
+
if (filterType !== "string" && filterType !== "date") {
|
|
423
|
+
alert("We only support string and filters.");
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
let responseData;
|
|
427
|
+
const url = `https://quill-344421.uc.r.appspot.comdashfilter/${client._id}/`;
|
|
428
|
+
const body = {
|
|
429
|
+
name: selectedDashboard,
|
|
430
|
+
filter: {
|
|
431
|
+
table: selectedTable.name,
|
|
432
|
+
field: field,
|
|
433
|
+
labelField: field,
|
|
434
|
+
label: name,
|
|
435
|
+
filterType,
|
|
436
|
+
},
|
|
437
|
+
};
|
|
438
|
+
const headers = {
|
|
439
|
+
"Content-Type": "application/json",
|
|
440
|
+
Authorization: `Bearer `,
|
|
441
|
+
};
|
|
442
|
+
try {
|
|
443
|
+
const response = await fetch(url, {
|
|
444
|
+
method: "POST",
|
|
445
|
+
headers: headers,
|
|
446
|
+
body: JSON.stringify(body),
|
|
447
|
+
});
|
|
448
|
+
if (!response.ok) {
|
|
449
|
+
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
450
|
+
}
|
|
451
|
+
responseData = await response.json();
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
console.error("There was a problem with the fetch operation:", error);
|
|
455
|
+
}
|
|
456
|
+
if (responseData) {
|
|
457
|
+
setIsOpen(false);
|
|
458
|
+
setName("");
|
|
459
|
+
setField("");
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
if (!selectedTable) {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
return ((0, jsx_runtime_1.jsx)(ModalComponent, { isOpen: isOpen, close: () => setIsOpen(false), children: (0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", flexDirection: "column" }, children: [(0, jsx_runtime_1.jsx)(HeaderComponent, { label: "Add filter" }), (0, jsx_runtime_1.jsx)("div", { children: "Label" }), (0, jsx_runtime_1.jsx)(TextInputComponent, { value: name, onChange: (e) => setName(e.target.value) }), (0, jsx_runtime_1.jsx)("div", { children: "Table" }), (0, jsx_runtime_1.jsx)(SelectComponent, { defaultValue: "", value: selectedTable ? selectedTable : "", onChange: (e) => setSelectedTable(e.target.value), options: tables.map((table) => {
|
|
467
|
+
return { label: table.name, value: table.name };
|
|
468
|
+
}) }), (0, jsx_runtime_1.jsx)("div", { children: "Field" }), (0, jsx_runtime_1.jsx)(SelectComponent, { defaultValue: "", value: field ? field : "", options: selectedTable.columns.map((column) => {
|
|
469
|
+
return { label: column.name, value: column.name };
|
|
470
|
+
}), onChange: (e) => {
|
|
471
|
+
setField(e);
|
|
472
|
+
} }), (0, jsx_runtime_1.jsx)(ButtonComponent, { label: "Add filter", onClick: handleAddFilter })] }) }));
|
|
473
|
+
}
|
|
474
|
+
function Portal({ publicKey, queryEndpoint, theme = defaultTheme, queryHeaders, withCredentials, environment, organizationId, TextInputComponent, ButtonComponent, SecondaryButtonComponent, ModalComponent, SelectComponent, OrganizationSelectComponent, UserManagementComponent, HeaderComponent, }) {
|
|
146
475
|
return ((0, jsx_runtime_1.jsx)(ContextProvider, { children: (0, jsx_runtime_1.jsx)(Navigation, { theme: theme, publicKey: publicKey, organizationId: organizationId, queryEndpoint: queryEndpoint, queryHeaders: queryHeaders, withCredentials: withCredentials, TextInputComponent: TextInputComponent ||
|
|
147
476
|
(({ onChange, value, placeholder }) => ((0, jsx_runtime_1.jsx)("input", { style: {
|
|
148
477
|
display: "flex",
|
|
@@ -177,7 +506,13 @@ function Portal({ publicKey, queryEndpoint, theme = defaultTheme, queryHeaders,
|
|
|
177
506
|
fontSize: 14,
|
|
178
507
|
paddingLeft: 20,
|
|
179
508
|
paddingRight: 20,
|
|
180
|
-
}, onClick: onClick, children: label }))),
|
|
509
|
+
}, onClick: onClick, children: label }))), HeaderComponent: HeaderComponent ||
|
|
510
|
+
(({ label }) => ((0, jsx_runtime_1.jsx)("h1", { style: {
|
|
511
|
+
color: theme?.primaryTextColor,
|
|
512
|
+
fontFamily: theme?.fontFamily,
|
|
513
|
+
fontWeight: theme?.buttonFontWeight || 600,
|
|
514
|
+
fontSize: 16,
|
|
515
|
+
}, children: label }))), SecondaryButtonComponent: SecondaryButtonComponent ||
|
|
181
516
|
(({ onClick, label }) => ((0, jsx_runtime_1.jsx)("button", { style: {
|
|
182
517
|
height: 36,
|
|
183
518
|
background: "#F9FAFB",
|
|
@@ -195,39 +530,44 @@ function Portal({ publicKey, queryEndpoint, theme = defaultTheme, queryHeaders,
|
|
|
195
530
|
paddingLeft: 20,
|
|
196
531
|
paddingRight: 20,
|
|
197
532
|
}, onClick: onClick, children: label }))), ModalComponent: ModalComponent ||
|
|
198
|
-
(({ isOpen, close, children }) =>
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
533
|
+
(({ isOpen, close, children }) => {
|
|
534
|
+
if (!isOpen) {
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: {
|
|
538
|
+
position: "fixed",
|
|
539
|
+
top: "0",
|
|
540
|
+
right: "0",
|
|
541
|
+
bottom: "0",
|
|
542
|
+
left: "0",
|
|
543
|
+
zIndex: "50",
|
|
544
|
+
backgroundColor: "rgba(255, 255, 255, 0.8)",
|
|
545
|
+
backdropFilter: "blur(5px)",
|
|
546
|
+
}, onClick: close }), (0, jsx_runtime_1.jsx)("div", { style: {
|
|
547
|
+
// position: "absolute",
|
|
548
|
+
position: "fixed",
|
|
549
|
+
left: "50%",
|
|
550
|
+
top: "50%",
|
|
551
|
+
zIndex: "50",
|
|
552
|
+
// width: "100%",
|
|
553
|
+
// maxWidth: 1024,
|
|
554
|
+
maxHeight: "90vh",
|
|
555
|
+
display: "flex",
|
|
556
|
+
justifyContent: "center",
|
|
557
|
+
alignItems: "center",
|
|
558
|
+
transform: "translateX(-50%) translateY(-50%)",
|
|
559
|
+
background: "white",
|
|
560
|
+
borderRadius: 8,
|
|
561
|
+
borderStyle: "solid",
|
|
562
|
+
borderWidth: 1,
|
|
563
|
+
borderColor: "#e7e7e7",
|
|
564
|
+
overflow: "hidden",
|
|
565
|
+
padding: 30,
|
|
566
|
+
// zIndex: 1000,
|
|
567
|
+
}, children: children })] }));
|
|
568
|
+
}), environment: environment, OrganizationSelectComponent: OrganizationSelectComponent, UserManagementComponent: UserManagementComponent, SelectComponent: SelectComponent ||
|
|
229
569
|
(({ options, onChange, value }) => {
|
|
230
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: { position: "relative" }, children: [(0, jsx_runtime_1.jsx)("select", { style: {
|
|
570
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: { position: "relative" }, children: [(0, jsx_runtime_1.jsx)("select", { defaultValue: "", style: {
|
|
231
571
|
width: "100%",
|
|
232
572
|
minWidth: 230,
|
|
233
573
|
outline: "none",
|
|
@@ -246,7 +586,8 @@ function Portal({ publicKey, queryEndpoint, theme = defaultTheme, queryHeaders,
|
|
|
246
586
|
color: theme?.primaryTextColor,
|
|
247
587
|
boxShadow: "0 1px 2px 0 rgba(0,0,0,.05)",
|
|
248
588
|
fontFamily: theme?.fontFamily,
|
|
249
|
-
}, value: value, onChange: (event) => onChange(event.target.value), children: options.
|
|
589
|
+
}, value: value, onChange: (event) => onChange(event.target.value), children: options.length > 0 &&
|
|
590
|
+
options.map((option) => ((0, jsx_runtime_1.jsx)("option", { value: option.value, label: option.label }, option.value))) }), (0, jsx_runtime_1.jsx)(ArrowDownHeadIcon, { style: {
|
|
250
591
|
height: "20px",
|
|
251
592
|
width: "20px",
|
|
252
593
|
flex: "none",
|
|
@@ -259,7 +600,7 @@ function Portal({ publicKey, queryEndpoint, theme = defaultTheme, queryHeaders,
|
|
|
259
600
|
}
|
|
260
601
|
exports.default = Portal;
|
|
261
602
|
const ArrowDownHeadIcon = ({ ...props }) => ((0, jsx_runtime_1.jsxs)("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "24", height: "24", children: [(0, jsx_runtime_1.jsx)("path", { fill: "none", d: "M0 0h24v24H0z" }), (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M12 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z" })] }));
|
|
262
|
-
function Navigation({ TextInputComponent, ButtonComponent, SecondaryButtonComponent, ModalComponent, SelectComponent, OrganizationSelectComponent, UserManagementComponent, publicKey, organizationId, queryEndpoint, queryHeaders, environment, withCredentials, }) {
|
|
603
|
+
function Navigation({ TextInputComponent, ButtonComponent, SecondaryButtonComponent, ModalComponent, SelectComponent, OrganizationSelectComponent, UserManagementComponent, HeaderComponent, publicKey, organizationId, queryEndpoint, queryHeaders, environment, withCredentials, }) {
|
|
263
604
|
const [client, setClient] = (0, react_1.useContext)(ClientContext);
|
|
264
605
|
const [environmentContext, setEnvironmentContext] = (0, react_1.useContext)(EnvironmentContext);
|
|
265
606
|
const [tables, setTables] = (0, react_1.useContext)(TablesContext);
|
|
@@ -309,15 +650,15 @@ function Navigation({ TextInputComponent, ButtonComponent, SecondaryButtonCompon
|
|
|
309
650
|
const renderComponentBasedOnName = () => {
|
|
310
651
|
switch (activeComponent) {
|
|
311
652
|
case "Dashboards":
|
|
312
|
-
return ((0, jsx_runtime_1.jsx)(Dashboards, { TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, ModalComponent: ModalComponent, SelectComponent: SelectComponent, OrganizationSelectComponent: OrganizationSelectComponent, setReportId: setReportId, queryEndpoint: queryEndpoint,
|
|
653
|
+
return ((0, jsx_runtime_1.jsx)(Dashboards, { TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, ModalComponent: ModalComponent, SelectComponent: SelectComponent, OrganizationSelectComponent: OrganizationSelectComponent, HeaderComponent: HeaderComponent, setReportId: setReportId, queryEndpoint: queryEndpoint, organizationId: organizationId, queryHeaders: queryHeaders, withCredentials: withCredentials }));
|
|
313
654
|
case "SQL editor":
|
|
314
655
|
return ((0, jsx_runtime_1.jsx)(QueryEditor, { TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, ModalComponent: ModalComponent, SelectComponent: SelectComponent }));
|
|
315
656
|
case "Report":
|
|
316
|
-
return ((0, jsx_runtime_1.jsx)(ReportWrapper, { TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, ModalComponent: ModalComponent, SelectComponent: SelectComponent
|
|
657
|
+
return ((0, jsx_runtime_1.jsx)(ReportWrapper, { TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, ModalComponent: ModalComponent, SelectComponent: SelectComponent }));
|
|
317
658
|
case "SQL views":
|
|
318
|
-
return ((0, jsx_runtime_1.jsx)(Tables, { TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, ModalComponent: ModalComponent, SelectComponent: SelectComponent }));
|
|
659
|
+
return ((0, jsx_runtime_1.jsx)(Tables, { TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, ModalComponent: ModalComponent, SelectComponent: SelectComponent, queryEndpoint: queryEndpoint, queryHeaders: queryHeaders }));
|
|
319
660
|
default:
|
|
320
|
-
return ((0, jsx_runtime_1.jsx)(Dashboards, { TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, OrganizationSelectComponent: OrganizationSelectComponent, ModalComponent: ModalComponent, SelectComponent: SelectComponent, setReportId: setReportId, queryEndpoint: queryEndpoint,
|
|
661
|
+
return ((0, jsx_runtime_1.jsx)(Dashboards, { TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, OrganizationSelectComponent: OrganizationSelectComponent, ModalComponent: ModalComponent, SelectComponent: SelectComponent, HeaderComponent: HeaderComponent, setReportId: setReportId, queryEndpoint: queryEndpoint, organizationId: organizationId, queryHeaders: queryHeaders, withCredentials: withCredentials }));
|
|
321
662
|
}
|
|
322
663
|
};
|
|
323
664
|
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
@@ -508,17 +849,22 @@ function classNames(...classes) {
|
|
|
508
849
|
return classes.filter(Boolean).join(" ");
|
|
509
850
|
}
|
|
510
851
|
exports.classNames = classNames;
|
|
511
|
-
function Dashboards({ setReportId, TextInputComponent, ButtonComponent, SecondaryButtonComponent, OrganizationSelectComponent, ModalComponent, SelectComponent, queryEndpoint, queryHeaders, organizationId, withCredentials, }) {
|
|
852
|
+
function Dashboards({ setReportId, TextInputComponent, ButtonComponent, SecondaryButtonComponent, OrganizationSelectComponent, ModalComponent, SelectComponent, queryEndpoint, queryHeaders, organizationId, HeaderComponent, withCredentials, }) {
|
|
512
853
|
const [organizations] = (0, react_1.useContext)(OrganizationsContext);
|
|
854
|
+
const [client] = (0, react_1.useContext)(ClientContext);
|
|
855
|
+
const [organization, setOrganization] = (0, react_1.useContext)(OrganizationContext);
|
|
513
856
|
const [environment] = (0, react_1.useContext)(EnvironmentContext);
|
|
514
857
|
const [dashboards, setDashboards] = (0, react_1.useState)([]);
|
|
515
858
|
const [selectedDashboard, setSelectedDashboard] = (0, react_1.useState)("");
|
|
859
|
+
const [selectedEditDashboard, setSelectedEditDashboard] = (0, react_1.useState)("");
|
|
860
|
+
const [editDashboardData, setEditDashboardData] = (0, react_1.useState)(null);
|
|
516
861
|
const [addFilterModalIsOpen, setAddFilterModalIsOpen] = (0, react_1.useState)(false);
|
|
862
|
+
const [isAddDashboardModalOpen, setIsAddDashboardModalOpen] = (0, react_1.useState)(false);
|
|
517
863
|
const [editFilterModalIsOpen, setEditFilterModalIsOpen] = (0, react_1.useState)(false);
|
|
518
864
|
const [dashboardData, setDashboardData] = (0, react_1.useState)(null);
|
|
519
865
|
const [activeComponent, setActiveComponent] = (0, react_1.useContext)(ActiveComponentContext);
|
|
866
|
+
const [isEditDashboardModalOpen, setIsEditDashboardModalOpen] = (0, react_1.useState)(false);
|
|
520
867
|
const [isOpen, setIsOpen] = (0, react_1.useState)(false);
|
|
521
|
-
const [client] = (0, react_1.useContext)(ClientContext);
|
|
522
868
|
// const navigate = useNavigate();
|
|
523
869
|
// useEffect(() => {
|
|
524
870
|
// if (customValue.length && customValue !== id && !userTyping) {
|
|
@@ -529,28 +875,28 @@ function Dashboards({ setReportId, TextInputComponent, ButtonComponent, Secondar
|
|
|
529
875
|
// // navigate("/");
|
|
530
876
|
// // }
|
|
531
877
|
// }, [customValue, userTyping]);
|
|
878
|
+
async function getDashNames() {
|
|
879
|
+
const url = `https://quill-344421.uc.r.appspot.com/dashnames/${client._id}/`;
|
|
880
|
+
const response2 = await fetch(url, {
|
|
881
|
+
method: "GET",
|
|
882
|
+
headers: {
|
|
883
|
+
Authorization: "Bearer ",
|
|
884
|
+
environment: environment,
|
|
885
|
+
},
|
|
886
|
+
});
|
|
887
|
+
// If you need to retrieve the JSON data from the response:
|
|
888
|
+
const data = await response2.json();
|
|
889
|
+
const dashNames = data.dashboardNames.map((elem) => {
|
|
890
|
+
if (!elem) {
|
|
891
|
+
return { name: "null" };
|
|
892
|
+
}
|
|
893
|
+
return { name: elem };
|
|
894
|
+
});
|
|
895
|
+
setDashboards(dashNames);
|
|
896
|
+
setSelectedDashboard(dashNames[0].name);
|
|
897
|
+
}
|
|
532
898
|
(0, react_1.useEffect)(() => {
|
|
533
899
|
let isSubscribed = true;
|
|
534
|
-
async function getDashNames() {
|
|
535
|
-
const url = `https://quill-344421.uc.r.appspot.com/dashnames/${client._id}/`;
|
|
536
|
-
const response2 = await fetch(url, {
|
|
537
|
-
method: "GET",
|
|
538
|
-
headers: {
|
|
539
|
-
Authorization: "Bearer ",
|
|
540
|
-
environment: environment,
|
|
541
|
-
},
|
|
542
|
-
});
|
|
543
|
-
// If you need to retrieve the JSON data from the response:
|
|
544
|
-
const data = await response2.json();
|
|
545
|
-
const dashNames = data.dashboardNames.map((elem) => {
|
|
546
|
-
if (!elem) {
|
|
547
|
-
return { name: "null" };
|
|
548
|
-
}
|
|
549
|
-
return { name: elem };
|
|
550
|
-
});
|
|
551
|
-
setDashboards(dashNames);
|
|
552
|
-
setSelectedDashboard(dashNames[0].name);
|
|
553
|
-
}
|
|
554
900
|
if (isSubscribed) {
|
|
555
901
|
getDashNames();
|
|
556
902
|
}
|
|
@@ -563,11 +909,15 @@ function Dashboards({ setReportId, TextInputComponent, ButtonComponent, Secondar
|
|
|
563
909
|
// window.location.reload();
|
|
564
910
|
// }
|
|
565
911
|
// }, [id]);
|
|
912
|
+
const handleSetOrganization = (org) => {
|
|
913
|
+
setOrganization(null);
|
|
914
|
+
setTimeout(() => setOrganization(org), 50);
|
|
915
|
+
};
|
|
566
916
|
(0, react_1.useEffect)(() => {
|
|
567
|
-
async function getDashboardData() {
|
|
568
|
-
let
|
|
917
|
+
async function getDashboardData(dashboard, setData) {
|
|
918
|
+
let responseData;
|
|
569
919
|
if (queryEndpoint) {
|
|
570
|
-
|
|
920
|
+
const response = await fetch(queryEndpoint, {
|
|
571
921
|
method: "POST",
|
|
572
922
|
headers: {
|
|
573
923
|
...queryHeaders,
|
|
@@ -577,38 +927,43 @@ function Dashboards({ setReportId, TextInputComponent, ButtonComponent, Secondar
|
|
|
577
927
|
metadata: organizationId
|
|
578
928
|
? {
|
|
579
929
|
orgId: organizationId,
|
|
580
|
-
name: selectedDashboard,
|
|
581
930
|
task: "config",
|
|
931
|
+
name: dashboard,
|
|
582
932
|
}
|
|
583
|
-
: {
|
|
933
|
+
: { task: "config", name: dashboard },
|
|
584
934
|
}),
|
|
585
935
|
credentials: withCredentials ? "include" : "omit", // If withCredentials is true, set to 'include'. Otherwise, set to 'omit'.
|
|
586
936
|
});
|
|
937
|
+
responseData = await response.json(); // If the server returns JSON data
|
|
587
938
|
}
|
|
588
939
|
else {
|
|
589
|
-
const url = new URL(`https://quill-344421.uc.r.appspot.com/dashconfig
|
|
940
|
+
const url = new URL(`https://quill-344421.uc.r.appspot.com/dashconfig`);
|
|
590
941
|
// Setting the search parameters for the URL
|
|
591
942
|
url.search = new URLSearchParams({
|
|
592
943
|
orgId: organizationId ? organizationId : "",
|
|
593
944
|
publicKey: client._id,
|
|
594
|
-
name:
|
|
945
|
+
name: dashboard,
|
|
595
946
|
}).toString();
|
|
596
|
-
response2 = await fetch(url, {
|
|
947
|
+
const response2 = await fetch(url, {
|
|
597
948
|
method: "GET",
|
|
598
949
|
headers: {
|
|
599
950
|
Authorization: "Bearer ",
|
|
600
951
|
environment: environment,
|
|
601
952
|
},
|
|
602
953
|
});
|
|
954
|
+
// If you need to retrieve the JSON data from the response:
|
|
955
|
+
responseData = await response2.json();
|
|
603
956
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
957
|
+
setData(responseData);
|
|
958
|
+
}
|
|
959
|
+
if (selectedEditDashboard) {
|
|
960
|
+
getDashboardData(selectedEditDashboard, setEditDashboardData);
|
|
961
|
+
return;
|
|
607
962
|
}
|
|
608
963
|
if (selectedDashboard && client) {
|
|
609
|
-
getDashboardData();
|
|
964
|
+
getDashboardData(selectedDashboard, setDashboardData);
|
|
610
965
|
}
|
|
611
|
-
}, [selectedDashboard, organizationId, client]);
|
|
966
|
+
}, [selectedDashboard, selectedEditDashboard, organizationId, client]);
|
|
612
967
|
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
613
968
|
display: "flex",
|
|
614
969
|
flexDirection: "column",
|
|
@@ -669,16 +1024,16 @@ function Dashboards({ setReportId, TextInputComponent, ButtonComponent, Secondar
|
|
|
669
1024
|
marginBottom: "4px",
|
|
670
1025
|
fontWeight: "600",
|
|
671
1026
|
color: exports.theme.secondaryTextColor,
|
|
672
|
-
}, children: "Dashboard" }), (0, jsx_runtime_1.jsx)(SelectComponent, { options: dashboards.length
|
|
1027
|
+
}, children: "Dashboard" }), (0, jsx_runtime_1.jsx)(SelectComponent, { defaultValue: "", options: dashboards.length
|
|
673
1028
|
? dashboards.map((elem) => {
|
|
674
1029
|
return { value: elem.name, label: elem.name };
|
|
675
1030
|
})
|
|
676
|
-
: [], onChange: (e) => setSelectedDashboard(e
|
|
1031
|
+
: [], onChange: (e) => setSelectedDashboard(e), value: selectedDashboard ? selectedDashboard : "" })] }), (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
677
1032
|
minWidth: 238 - 120,
|
|
678
1033
|
gap: 12,
|
|
679
1034
|
display: "flex",
|
|
680
1035
|
flexDirection: "row",
|
|
681
|
-
}, children: (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Create report", onClick: () => setActiveComponent("SQL editor") }) })] }) })] })] }) }), (0, jsx_runtime_1.jsx)("div", { style: { paddingTop: "190px", display: "inline-block" }, children: selectedDashboard && ((0, jsx_runtime_1.jsx)(react_2.Dashboard
|
|
1036
|
+
}, children: [(0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Edit dashboards", onClick: () => setIsEditDashboardModalOpen(true) }), (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Create report", onClick: () => setActiveComponent("SQL editor") })] })] }) })] })] }) }), (0, jsx_runtime_1.jsx)("div", { style: { paddingTop: "190px", display: "inline-block" }, children: selectedDashboard && ((0, jsx_runtime_1.jsx)(react_2.Dashboard
|
|
682
1037
|
// TODO: CHANGE
|
|
683
1038
|
, {
|
|
684
1039
|
// TODO: CHANGE
|
|
@@ -692,27 +1047,259 @@ function Dashboards({ setReportId, TextInputComponent, ButtonComponent, Secondar
|
|
|
692
1047
|
}, onClickDashboardItem: (elem) => {
|
|
693
1048
|
setReportId(elem._id);
|
|
694
1049
|
setActiveComponent("Report");
|
|
695
|
-
} })) })
|
|
1050
|
+
} })) }), (0, jsx_runtime_1.jsx)(EditDashboardsModal, { clientId: client._id, isOpen: isEditDashboardModalOpen, setIsOpen: setIsEditDashboardModalOpen, ModalComponent: ModalComponent, ButtonComponent: ButtonComponent, TextInputComponent: TextInputComponent, openEditFilterModal: (dashboardName) => {
|
|
1051
|
+
setSelectedEditDashboard(dashboardName);
|
|
1052
|
+
setEditFilterModalIsOpen(true);
|
|
1053
|
+
// setIsEditDashboardModalOpen(false);
|
|
1054
|
+
}, openAddDashboardModal: () => {
|
|
1055
|
+
setIsAddDashboardModalOpen(true);
|
|
1056
|
+
// setIsEditDashboardModalOpen(false);
|
|
1057
|
+
}, HeaderComponent: HeaderComponent, setDashboardData: setDashboardData, dashboards: dashboards, getDashNames: getDashNames }), (0, jsx_runtime_1.jsx)(EditFiltersModal, { selectedDashboard: selectedEditDashboard, dashboardData: editDashboardData, isOpen: editFilterModalIsOpen, setIsOpen: setEditFilterModalIsOpen, openAddFilterModal: () => {
|
|
1058
|
+
setAddFilterModalIsOpen(true);
|
|
1059
|
+
// setEditFilterModalIsOpen(false);
|
|
1060
|
+
}, client: client, ModalComponent: ModalComponent, ButtonComponent: ButtonComponent, TextInputComponent: TextInputComponent, HeaderComponent: HeaderComponent, SelectComponent: SelectComponent, dashNames: dashboards, setSelectedEditDashboard: setSelectedEditDashboard }), (0, jsx_runtime_1.jsx)(AddFilterModal, { selectedDashboard: selectedEditDashboard, isOpen: addFilterModalIsOpen, setIsOpen: setAddFilterModalIsOpen, client: client, ModalComponent: ModalComponent, TextInputComponent: TextInputComponent, SelectComponent: SelectComponent, HeaderComponent: HeaderComponent, ButtonComponent: ButtonComponent, openAddDashboardModal: () => {
|
|
1061
|
+
setIsAddDashboardModalOpen(true);
|
|
1062
|
+
// setAddFilterModalIsOpen(false);
|
|
1063
|
+
} }), (0, jsx_runtime_1.jsx)(AddDashboardModal, { selectedDashboard: selectedDashboard, isOpen: isAddDashboardModalOpen, setIsOpen: setIsAddDashboardModalOpen, client: client, ModalComponent: ModalComponent, TextInputComponent: TextInputComponent, SelectComponent: SelectComponent, HeaderComponent: HeaderComponent, ButtonComponent: ButtonComponent, dashNames: dashboards, openAddFilterModal: () => {
|
|
1064
|
+
setAddFilterModalIsOpen(true);
|
|
1065
|
+
// setIsAddDashboardModalOpen(false);
|
|
1066
|
+
}, organizationId: organizationId, getDashNames: getDashNames })] }));
|
|
696
1067
|
}
|
|
697
|
-
function
|
|
698
|
-
const [
|
|
1068
|
+
function AddDashboardModal({ selectedDashboard, isOpen, setIsOpen, client, ModalComponent, TextInputComponent, SelectComponent, HeaderComponent, ButtonComponent, dashNames, getDashNames, organizationId, }) {
|
|
1069
|
+
const [selectedDashboardName, setSelectedDashboardName] = (0, react_1.useState)(selectedDashboard.name);
|
|
1070
|
+
const [tables] = (0, react_1.useContext)(TablesContext);
|
|
1071
|
+
const [selectedTable, setSelectedTable] = (0, react_1.useState)(null);
|
|
1072
|
+
const [name, setName] = (0, react_1.useState)("");
|
|
1073
|
+
const [field, setField] = (0, react_1.useState)("");
|
|
1074
|
+
const [filterType, setFilterType] = (0, react_1.useState)("string");
|
|
1075
|
+
const [dateRange, setDateRange] = (0, react_1.useState)([new Date(), new Date()]);
|
|
1076
|
+
const [newFilters, setNewFilters] = (0, react_1.useState)([]);
|
|
1077
|
+
const [newDateFilter, setNewDateFilter] = (0, react_1.useState)(null);
|
|
699
1078
|
(0, react_1.useEffect)(() => {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
1079
|
+
if (tables.length) {
|
|
1080
|
+
setSelectedTable(tables[0]);
|
|
1081
|
+
// setField(tables[0].columns.map((elem) => elem.name));
|
|
1082
|
+
setField(tables[0].columns[0].name);
|
|
1083
|
+
}
|
|
1084
|
+
}, [tables]);
|
|
1085
|
+
const handleDeleteFilter = async (filter) => {
|
|
1086
|
+
setNewFilters(newFilters.filter((f) => f !== filter));
|
|
1087
|
+
};
|
|
1088
|
+
const handleAddDashboardSubmit = async () => {
|
|
1089
|
+
if (!selectedDashboardName ||
|
|
1090
|
+
newFilters.some((filter) => !filter.label) ||
|
|
1091
|
+
(newDateFilter && newDateFilter.label)) {
|
|
1092
|
+
alert("Empty labels");
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
if (newFilters.some((filter) => !filter.field)) {
|
|
1096
|
+
alert("Empty fields");
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
if (!selectedTable || !field) {
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
if (dashNames &&
|
|
1103
|
+
dashNames.length > 0 &&
|
|
1104
|
+
dashNames.some((dashName) => dashName.name === selectedDashboardName)) {
|
|
1105
|
+
alert("Dashboard name already taken!");
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
let updatedFilters = newFilters.map((filter) => {
|
|
1109
|
+
const filterType = getPostgresBasicType(selectedTable.columns.find((col) => col.name === filter.field));
|
|
1110
|
+
return {
|
|
1111
|
+
table: selectedTable.name,
|
|
1112
|
+
field: filter.field,
|
|
1113
|
+
labelField: filter.field,
|
|
1114
|
+
label: filter.label,
|
|
1115
|
+
filterType,
|
|
1116
|
+
};
|
|
1117
|
+
});
|
|
1118
|
+
const fieldsSet = new Set();
|
|
1119
|
+
const hasDuplicateField = updatedFilters.some((filter) => {
|
|
1120
|
+
if (fieldsSet.has(filter.field)) {
|
|
1121
|
+
return true;
|
|
1122
|
+
}
|
|
1123
|
+
else {
|
|
1124
|
+
fieldsSet.add(filter.field);
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
});
|
|
1128
|
+
if (hasDuplicateField) {
|
|
1129
|
+
alert("Maximum of one filter per field");
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
let allValid = true;
|
|
1133
|
+
updatedFilters.forEach((filter) => {
|
|
1134
|
+
if (filter.filterType !== "string" && filter.filterType !== "date") {
|
|
1135
|
+
allValid = false;
|
|
1136
|
+
console.error(`Invalid filterType found: ${filter.filterType}`);
|
|
1137
|
+
}
|
|
1138
|
+
});
|
|
1139
|
+
if (!allValid) {
|
|
1140
|
+
alert("We only support string and filters.");
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
1143
|
+
if (updatedFilters.filter((filter) => filter.filterType === "date").length > 1) {
|
|
1144
|
+
alert("More than one date filter");
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
let responseData;
|
|
1148
|
+
const url = `https://quill-344421.uc.r.appspot.com/newdash/${client._id}/`;
|
|
1149
|
+
const body = newDateFilter && Object.keys(newDateFilter).length
|
|
1150
|
+
? {
|
|
1151
|
+
dateFilter: newDateFilter,
|
|
1152
|
+
newDashboardName: selectedDashboardName,
|
|
1153
|
+
filters: updatedFilters,
|
|
1154
|
+
organizationId,
|
|
1155
|
+
}
|
|
1156
|
+
: {
|
|
1157
|
+
newDashboardName: selectedDashboardName,
|
|
1158
|
+
filters: updatedFilters,
|
|
1159
|
+
organizationId,
|
|
1160
|
+
};
|
|
1161
|
+
const headers = {
|
|
1162
|
+
"Content-Type": "application/json",
|
|
1163
|
+
Authorization: `Bearer `,
|
|
1164
|
+
};
|
|
1165
|
+
try {
|
|
1166
|
+
const response = await fetch(url, {
|
|
1167
|
+
method: "POST",
|
|
1168
|
+
headers: headers,
|
|
1169
|
+
body: JSON.stringify(body),
|
|
707
1170
|
});
|
|
708
|
-
|
|
709
|
-
|
|
1171
|
+
if (!response.ok) {
|
|
1172
|
+
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
1173
|
+
}
|
|
1174
|
+
responseData = await response.json();
|
|
1175
|
+
}
|
|
1176
|
+
catch (e) {
|
|
1177
|
+
console.log("error");
|
|
1178
|
+
}
|
|
1179
|
+
if (responseData) {
|
|
1180
|
+
setIsOpen(false);
|
|
1181
|
+
setName("");
|
|
1182
|
+
setSelectedDashboardName("");
|
|
1183
|
+
setNewFilters([]);
|
|
1184
|
+
setNewDateFilter(null);
|
|
1185
|
+
getDashNames();
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
};
|
|
1189
|
+
if (!selectedTable) {
|
|
1190
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
|
|
1191
|
+
}
|
|
1192
|
+
const handleAddFilter = async () => {
|
|
1193
|
+
setNewFilters([...newFilters, { label: "", field }]);
|
|
1194
|
+
};
|
|
1195
|
+
return ((0, jsx_runtime_1.jsx)(ModalComponent, { isOpen: isOpen, close: () => setIsOpen(false), children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(TextInputComponent, { placeholder: "Enter Dashboard Name...", onChange: (e) => setSelectedDashboardName(e.target.value), value: selectedDashboardName }), (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1196
|
+
display: "flex",
|
|
1197
|
+
flexDirection: "column",
|
|
1198
|
+
alignItems: "center",
|
|
1199
|
+
}, children: [newFilters.map((filter, index) => {
|
|
1200
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", flexDirection: "row" }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", flexDirection: "column" }, children: [(0, jsx_runtime_1.jsx)("h2", { children: "Label" }), (0, jsx_runtime_1.jsx)(TextInputComponent, { value: filter.label, onChange: (e) => {
|
|
1201
|
+
const updatedFilters = newFilters.map((otherFilter, i) => index === i
|
|
1202
|
+
? { ...otherFilter, label: e.target.value }
|
|
1203
|
+
: otherFilter);
|
|
1204
|
+
setNewFilters(updatedFilters);
|
|
1205
|
+
} })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", flexDirection: "column" }, children: [(0, jsx_runtime_1.jsx)("h4", { children: "Field" }), (0, jsx_runtime_1.jsx)("div", { style: {
|
|
1206
|
+
display: "flex",
|
|
1207
|
+
flexDirection: "column",
|
|
1208
|
+
alignItems: "center",
|
|
1209
|
+
}, children: (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1210
|
+
display: "flex",
|
|
1211
|
+
flexDirection: "row",
|
|
1212
|
+
alignItems: "center",
|
|
1213
|
+
}, children: [(0, jsx_runtime_1.jsx)(SelectComponent, { defaultValue: "", value: filter && filter.field ? filter.field : "", options: selectedTable.columns.map((column) => {
|
|
1214
|
+
return { label: column.name, value: column.name };
|
|
1215
|
+
}), onChange: (e) => {
|
|
1216
|
+
const updatedFilters = newFilters.map((otherFilter, i) => index === i
|
|
1217
|
+
? { ...otherFilter, field: e }
|
|
1218
|
+
: otherFilter);
|
|
1219
|
+
setNewFilters(updatedFilters);
|
|
1220
|
+
} }), (0, jsx_runtime_1.jsx)("div", { onClick: () => handleDeleteFilter(filter), style: {
|
|
1221
|
+
height: 42,
|
|
1222
|
+
width: 42,
|
|
1223
|
+
alignItems: "center",
|
|
1224
|
+
justifyContent: "center",
|
|
1225
|
+
display: "flex",
|
|
1226
|
+
}, children: (0, jsx_runtime_1.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "#4C5462", width: "20", height: "20", children: (0, jsx_runtime_1.jsx)("path", { fillRule: "evenodd", d: "M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z", clipRule: "evenodd" }) }) })] }) })] })] }, filter.field + index));
|
|
1227
|
+
}), (0, jsx_runtime_1.jsx)(ButtonComponent, { onClick: handleAddFilter, label: "Add new filter +" }), (0, jsx_runtime_1.jsx)(ButtonComponent, { onClick: handleAddDashboardSubmit, label: "Add Dashboard +" })] })] }) }));
|
|
1228
|
+
}
|
|
1229
|
+
function EditDashboardsModal({ ModalComponent, TextInputComponent, isOpen, setIsOpen, clientId, ButtonComponent, openEditFilterModal, openAddDashboardModal, HeaderComponent, setDashboardData, dashboards, getDashNames, }) {
|
|
1230
|
+
// const [dashboards, setDashboards] = useState([]);
|
|
1231
|
+
// useEffect(() => {
|
|
1232
|
+
// async function getDashboards(clientId) {
|
|
1233
|
+
// const url = `https://quill-344421.uc.r.appspot.com/dashnames/${clientId}/`;
|
|
1234
|
+
// const response2 = await fetch(url, {
|
|
1235
|
+
// method: "GET",
|
|
1236
|
+
// headers: {
|
|
1237
|
+
// Authorization: "Bearer ", // Ensure you append your token after 'Bearer ' if needed
|
|
1238
|
+
// },
|
|
1239
|
+
// });
|
|
1240
|
+
// // If you need to retrieve the JSON data from the response:
|
|
1241
|
+
// const data = await response2.json();
|
|
1242
|
+
// setDashboards(data);
|
|
1243
|
+
// }
|
|
1244
|
+
// if (clientId) {
|
|
1245
|
+
// getDashboards(clientId);
|
|
1246
|
+
// }
|
|
1247
|
+
// }, [clientId]);
|
|
1248
|
+
async function handleDeleteDashboard(dashboardName) {
|
|
1249
|
+
const url = `https://quill-344421.uc.r.appspot.com/dashdelete/${clientId}/`;
|
|
1250
|
+
const body = {
|
|
1251
|
+
name: dashboardName,
|
|
1252
|
+
};
|
|
1253
|
+
const headers = {
|
|
1254
|
+
"Content-Type": "application/json",
|
|
1255
|
+
Authorization: `Bearer `,
|
|
1256
|
+
};
|
|
1257
|
+
try {
|
|
1258
|
+
const response = await fetch(url, {
|
|
1259
|
+
method: "POST",
|
|
1260
|
+
headers: headers,
|
|
1261
|
+
body: JSON.stringify(body),
|
|
1262
|
+
});
|
|
1263
|
+
if (!response.ok) {
|
|
1264
|
+
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
1265
|
+
}
|
|
1266
|
+
const responseData = await response.json();
|
|
1267
|
+
if (responseData) {
|
|
1268
|
+
getDashNames();
|
|
1269
|
+
return;
|
|
1270
|
+
}
|
|
710
1271
|
}
|
|
711
|
-
|
|
712
|
-
|
|
1272
|
+
catch (e) {
|
|
1273
|
+
console.log("error", e);
|
|
713
1274
|
}
|
|
714
|
-
}
|
|
715
|
-
return ((0, jsx_runtime_1.jsx)(ModalComponent, { isOpen: isOpen, close: () => setIsOpen(false), children: (0, jsx_runtime_1.
|
|
1275
|
+
}
|
|
1276
|
+
return ((0, jsx_runtime_1.jsx)(ModalComponent, { isOpen: isOpen, close: () => setIsOpen(false), children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { style: {
|
|
1277
|
+
display: "flex",
|
|
1278
|
+
flexDirection: "column",
|
|
1279
|
+
}, children: dashboards &&
|
|
1280
|
+
dashboards.map((dashboardName, index) => {
|
|
1281
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1282
|
+
display: "flex",
|
|
1283
|
+
flexDirection: "row",
|
|
1284
|
+
}, children: [(0, jsx_runtime_1.jsx)("div", { style: {
|
|
1285
|
+
display: "flex",
|
|
1286
|
+
flexDirection: "column",
|
|
1287
|
+
}, children: (0, jsx_runtime_1.jsx)("div", { style: {
|
|
1288
|
+
marginRight: 12,
|
|
1289
|
+
}, children: dashboardName.name }) }), (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1290
|
+
display: "flex",
|
|
1291
|
+
flexDirection: "column",
|
|
1292
|
+
}, children: [" ", (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1293
|
+
display: "flex",
|
|
1294
|
+
flexDirection: "row",
|
|
1295
|
+
alignItems: "flex-end",
|
|
1296
|
+
}, children: [(0, jsx_runtime_1.jsx)(ButtonComponent, { onClick: () => openEditFilterModal(dashboardName.name), label: "Edit" }), (0, jsx_runtime_1.jsx)(ButtonComponent, { onClick: () => handleDeleteDashboard(dashboardName.name), label: "Delete" })] })] })] }, dashboardName + index));
|
|
1297
|
+
}) }), (0, jsx_runtime_1.jsx)("div", { style: {
|
|
1298
|
+
display: "flex",
|
|
1299
|
+
flexDirection: "column",
|
|
1300
|
+
alignItems: "center",
|
|
1301
|
+
justifyContent: "center",
|
|
1302
|
+
}, children: (0, jsx_runtime_1.jsx)(ButtonComponent, { onClick: openAddDashboardModal, label: "Create new dashboard" }) })] }) }));
|
|
716
1303
|
}
|
|
717
1304
|
function DropdownMenu({ items, setSelected, selected, filterKey }) {
|
|
718
1305
|
return ((0, jsx_runtime_1.jsx)("select", { onChange: (e) => {
|
|
@@ -720,32 +1307,7 @@ function DropdownMenu({ items, setSelected, selected, filterKey }) {
|
|
|
720
1307
|
}, value: selected ? selected.name : "", children: items.slice(0, 50).map((item) => ((0, jsx_runtime_1.jsx)("option", { value: item.name, children: item.name }, item.name))) }));
|
|
721
1308
|
}
|
|
722
1309
|
exports.DropdownMenu = DropdownMenu;
|
|
723
|
-
function
|
|
724
|
-
monaco.editor.defineTheme("onedark", {
|
|
725
|
-
base: theme.darkMode ? "vs-dark" : "vs",
|
|
726
|
-
inherit: true,
|
|
727
|
-
rules: [
|
|
728
|
-
{
|
|
729
|
-
token: "comment",
|
|
730
|
-
foreground: "#5d7988",
|
|
731
|
-
fontStyle: "italic",
|
|
732
|
-
},
|
|
733
|
-
{ token: "constant", foreground: "#e06c75" },
|
|
734
|
-
],
|
|
735
|
-
colors: {
|
|
736
|
-
"editor.background": "#F9F9F9",
|
|
737
|
-
},
|
|
738
|
-
});
|
|
739
|
-
}
|
|
740
|
-
function setEditorTheme(editor, monaco) {
|
|
741
|
-
try {
|
|
742
|
-
monaco.editor.setTheme("onedark");
|
|
743
|
-
}
|
|
744
|
-
catch (e) {
|
|
745
|
-
console.log("ERROR: ", e);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
function Tables({ TextInputComponent, ButtonComponent, SecondaryButtonComponent, ModalComponent, SelectComponent, }) {
|
|
1310
|
+
function Tables({ TextInputComponent, ButtonComponent, SecondaryButtonComponent, ModalComponent, SelectComponent, queryEndpoint, queryHeaders, withCredentials, }) {
|
|
749
1311
|
const [tables, setTables] = (0, react_1.useState)([]);
|
|
750
1312
|
const [modalIsOpen, setIsOpen] = (0, react_1.useState)(false);
|
|
751
1313
|
const [editModalIsOpen, setEditModalIsOpen] = (0, react_1.useState)(false);
|
|
@@ -755,7 +1317,6 @@ function Tables({ TextInputComponent, ButtonComponent, SecondaryButtonComponent,
|
|
|
755
1317
|
const [editName, setEditName] = (0, react_1.useState)("");
|
|
756
1318
|
const [editViewQuery, setEditViewQuery] = (0, react_1.useState)("");
|
|
757
1319
|
const [client] = (0, react_1.useContext)(ClientContext);
|
|
758
|
-
const [code, setCode] = (0, react_1.useState)(``);
|
|
759
1320
|
const [tableToBeDeleted, setTableToBeDeleted] = (0, react_1.useState)("");
|
|
760
1321
|
const [deleteName, setDeleteName] = (0, react_1.useState)("");
|
|
761
1322
|
const [deleteModalIsOpen, setDeleteModalIsOpen] = (0, react_1.useState)(false);
|
|
@@ -764,7 +1325,7 @@ function Tables({ TextInputComponent, ButtonComponent, SecondaryButtonComponent,
|
|
|
764
1325
|
};
|
|
765
1326
|
const openModal = () => {
|
|
766
1327
|
setIsOpen(true);
|
|
767
|
-
|
|
1328
|
+
setEditViewQuery("");
|
|
768
1329
|
};
|
|
769
1330
|
const closeModal = () => {
|
|
770
1331
|
setIsOpen(false);
|
|
@@ -781,21 +1342,47 @@ function Tables({ TextInputComponent, ButtonComponent, SecondaryButtonComponent,
|
|
|
781
1342
|
setEditName(table.name);
|
|
782
1343
|
setEditViewQuery(table.viewQuery);
|
|
783
1344
|
setEditViewId(table._id);
|
|
784
|
-
setCode(table.viewQuery);
|
|
785
1345
|
};
|
|
786
1346
|
const handleDeleteTable = async () => {
|
|
787
1347
|
if (deleteName !== tableToBeDeleted) {
|
|
788
1348
|
alert("Table names must match");
|
|
789
1349
|
return;
|
|
790
1350
|
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
1351
|
+
if (!editViewId) {
|
|
1352
|
+
console.log("No view id found");
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1355
|
+
let response;
|
|
1356
|
+
if (queryEndpoint) {
|
|
1357
|
+
response = await fetch(queryEndpoint, {
|
|
1358
|
+
method: "POST",
|
|
1359
|
+
headers: {
|
|
1360
|
+
"Content-Type": "application/json",
|
|
1361
|
+
...queryHeaders,
|
|
1362
|
+
},
|
|
1363
|
+
body: JSON.stringify({
|
|
1364
|
+
metadata: {
|
|
1365
|
+
task: "view",
|
|
1366
|
+
id: editViewId,
|
|
1367
|
+
deleted: true,
|
|
1368
|
+
},
|
|
1369
|
+
}),
|
|
1370
|
+
credentials: withCredentials ? "include" : "omit", // If withCredentials is true, set to 'include'. Otherwise, set to 'omit'.
|
|
1371
|
+
});
|
|
1372
|
+
}
|
|
1373
|
+
else {
|
|
1374
|
+
response = await fetch(`https://quill-344421.uc.r.appspot.com/table/${client._id}/`, {
|
|
1375
|
+
method: "POST",
|
|
1376
|
+
headers: {
|
|
1377
|
+
"Content-Type": "application/json",
|
|
1378
|
+
Authorization: `Bearer `,
|
|
1379
|
+
},
|
|
1380
|
+
body: JSON.stringify({
|
|
1381
|
+
id: editViewId,
|
|
1382
|
+
deleted: true,
|
|
1383
|
+
}),
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
799
1386
|
const data = await response.json();
|
|
800
1387
|
if (data) {
|
|
801
1388
|
setDeleteName("");
|
|
@@ -836,38 +1423,47 @@ function Tables({ TextInputComponent, ButtonComponent, SecondaryButtonComponent,
|
|
|
836
1423
|
alert("Please enter a table query.");
|
|
837
1424
|
return;
|
|
838
1425
|
}
|
|
839
|
-
if (
|
|
840
|
-
|
|
1426
|
+
if (!editViewId) {
|
|
1427
|
+
alert("Could not save.");
|
|
1428
|
+
return;
|
|
1429
|
+
}
|
|
1430
|
+
let response;
|
|
1431
|
+
if (queryEndpoint) {
|
|
1432
|
+
response = await fetch(queryEndpoint, {
|
|
1433
|
+
method: "POST",
|
|
1434
|
+
headers: {
|
|
1435
|
+
"Content-Type": "application/json",
|
|
1436
|
+
...queryHeaders,
|
|
1437
|
+
},
|
|
1438
|
+
body: JSON.stringify({
|
|
1439
|
+
metadata: {
|
|
1440
|
+
query: editViewQuery[editViewQuery.length - 1] === ";"
|
|
1441
|
+
? editViewQuery.slice(0, -1)
|
|
1442
|
+
: editViewQuery,
|
|
1443
|
+
name: editName,
|
|
1444
|
+
task: "view",
|
|
1445
|
+
id: editViewId,
|
|
1446
|
+
},
|
|
1447
|
+
}),
|
|
1448
|
+
credentials: withCredentials ? "include" : "omit", // If withCredentials is true, set to 'include'. Otherwise, set to 'omit'.
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
else {
|
|
1452
|
+
response = await fetch(`https://quill-344421.uc.r.appspot.com/table/${client._id}/`, {
|
|
841
1453
|
method: "POST",
|
|
842
1454
|
headers: {
|
|
843
1455
|
"Content-Type": "application/json",
|
|
844
1456
|
Authorization: `Bearer `,
|
|
845
1457
|
},
|
|
846
1458
|
body: JSON.stringify({
|
|
847
|
-
viewQuery: editViewQuery.
|
|
1459
|
+
viewQuery: editViewQuery[editViewQuery.length - 1] === ";"
|
|
1460
|
+
? editViewQuery.slice(0, -1)
|
|
1461
|
+
: editViewQuery,
|
|
848
1462
|
name: editName,
|
|
849
1463
|
id: editViewId,
|
|
850
1464
|
}),
|
|
851
1465
|
});
|
|
852
|
-
const data = await response.json();
|
|
853
|
-
if (data) {
|
|
854
|
-
closeEditModal();
|
|
855
|
-
getTables();
|
|
856
|
-
}
|
|
857
|
-
return;
|
|
858
1466
|
}
|
|
859
|
-
const response = await fetch(`https://quill-344421.uc.r.appspot.com/table/${client._id}/`, {
|
|
860
|
-
method: "POST",
|
|
861
|
-
headers: {
|
|
862
|
-
"Content-Type": "application/json",
|
|
863
|
-
Authorization: `Bearer `,
|
|
864
|
-
},
|
|
865
|
-
body: JSON.stringify({
|
|
866
|
-
viewQuery: editViewQuery,
|
|
867
|
-
name: editName,
|
|
868
|
-
id: editViewId,
|
|
869
|
-
}),
|
|
870
|
-
});
|
|
871
1467
|
const data = await response.json();
|
|
872
1468
|
if (data) {
|
|
873
1469
|
closeEditModal();
|
|
@@ -879,40 +1475,45 @@ function Tables({ TextInputComponent, ButtonComponent, SecondaryButtonComponent,
|
|
|
879
1475
|
alert("Please enter a table name.");
|
|
880
1476
|
return;
|
|
881
1477
|
}
|
|
882
|
-
if (!
|
|
1478
|
+
if (!editViewQuery.length) {
|
|
883
1479
|
alert("Please enter a table query.");
|
|
884
1480
|
return;
|
|
885
1481
|
}
|
|
886
|
-
|
|
887
|
-
|
|
1482
|
+
let response;
|
|
1483
|
+
if (queryEndpoint) {
|
|
1484
|
+
response = await fetch(queryEndpoint, {
|
|
1485
|
+
method: "POST",
|
|
1486
|
+
headers: {
|
|
1487
|
+
"Content-Type": "application/json",
|
|
1488
|
+
...queryHeaders,
|
|
1489
|
+
},
|
|
1490
|
+
body: JSON.stringify({
|
|
1491
|
+
metadata: {
|
|
1492
|
+
query: editViewQuery[editViewQuery.length - 1] === ";"
|
|
1493
|
+
? editViewQuery.slice(0, -1)
|
|
1494
|
+
: editViewQuery,
|
|
1495
|
+
name: name,
|
|
1496
|
+
task: "view",
|
|
1497
|
+
},
|
|
1498
|
+
}),
|
|
1499
|
+
credentials: withCredentials ? "include" : "omit", // If withCredentials is true, set to 'include'. Otherwise, set to 'omit'.
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
else {
|
|
1503
|
+
response = await fetch(`https://quill-344421.uc.r.appspot.com/table/${client._id}/`, {
|
|
888
1504
|
method: "POST",
|
|
889
1505
|
headers: {
|
|
890
1506
|
"Content-Type": "application/json",
|
|
891
1507
|
Authorization: `Bearer `,
|
|
892
1508
|
},
|
|
893
1509
|
body: JSON.stringify({
|
|
894
|
-
viewQuery:
|
|
1510
|
+
viewQuery: editViewQuery[editViewQuery.length - 1] === ";"
|
|
1511
|
+
? editViewQuery.slice(0, -1)
|
|
1512
|
+
: editViewQuery,
|
|
895
1513
|
name: name,
|
|
896
1514
|
}),
|
|
897
1515
|
});
|
|
898
|
-
const data = await response.json();
|
|
899
|
-
if (data) {
|
|
900
|
-
closeModal();
|
|
901
|
-
getTables();
|
|
902
|
-
}
|
|
903
|
-
return;
|
|
904
1516
|
}
|
|
905
|
-
const response = await fetch(`https://quill-344421.uc.r.appspot.com/table/${client._id}/`, {
|
|
906
|
-
method: "POST",
|
|
907
|
-
headers: {
|
|
908
|
-
"Content-Type": "application/json",
|
|
909
|
-
Authorization: `Bearer `,
|
|
910
|
-
},
|
|
911
|
-
body: JSON.stringify({
|
|
912
|
-
viewQuery: code,
|
|
913
|
-
name: name,
|
|
914
|
-
}),
|
|
915
|
-
});
|
|
916
1517
|
const data = await response.json();
|
|
917
1518
|
if (data) {
|
|
918
1519
|
closeModal();
|
|
@@ -949,13 +1550,13 @@ function Tables({ TextInputComponent, ButtonComponent, SecondaryButtonComponent,
|
|
|
949
1550
|
borderTopRightRadius: 0,
|
|
950
1551
|
borderBottomRightRadius: 0,
|
|
951
1552
|
overflow: "hidden",
|
|
952
|
-
}, children: (0, jsx_runtime_1.jsx)(react_3.default, { height: "500px", width: "100%", defaultLanguage: "pgsql", defaultValue: "", value:
|
|
1553
|
+
}, children: (0, jsx_runtime_1.jsx)(react_3.default, { height: "500px", width: "100%", defaultLanguage: "pgsql", defaultValue: "", value: editViewQuery, loading: (0, jsx_runtime_1.jsx)("div", {}), options: {
|
|
953
1554
|
wordWrap: "on",
|
|
954
1555
|
minimap: {
|
|
955
1556
|
enabled: false,
|
|
956
1557
|
},
|
|
957
1558
|
padding: { top: 16 },
|
|
958
|
-
}, onChange: (query) =>
|
|
1559
|
+
}, onChange: (query) => setEditViewQuery(query), beforeMount: (monaco) => defineEditorTheme(monaco, exports.theme), onMount: setEditorTheme }) }), (0, jsx_runtime_1.jsx)(ButtonComponent, { label: "Add view +", onClick: handleAddTable })] }) }), (0, jsx_runtime_1.jsx)(ModalComponent, { isOpen: editModalIsOpen, close: closeEditModal, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col p-[6px]", children: [(0, jsx_runtime_1.jsxs)("div", { style: {
|
|
959
1560
|
display: "flex",
|
|
960
1561
|
flexDirection: "row",
|
|
961
1562
|
alignItems: "center",
|
|
@@ -999,13 +1600,13 @@ function Tables({ TextInputComponent, ButtonComponent, SecondaryButtonComponent,
|
|
|
999
1600
|
borderTopRightRadius: 0,
|
|
1000
1601
|
borderBottomRightRadius: 0,
|
|
1001
1602
|
overflow: "hidden",
|
|
1002
|
-
}, children: (0, jsx_runtime_1.jsx)(react_3.default, { height: "300px", width: "520px", defaultLanguage: "pgsql", defaultValue: "", value:
|
|
1603
|
+
}, children: (0, jsx_runtime_1.jsx)(react_3.default, { height: "300px", width: "520px", defaultLanguage: "pgsql", defaultValue: "", value: editViewQuery, loading: (0, jsx_runtime_1.jsx)("div", {}), options: {
|
|
1003
1604
|
wordWrap: "on",
|
|
1004
1605
|
minimap: {
|
|
1005
1606
|
enabled: false,
|
|
1006
1607
|
},
|
|
1007
1608
|
padding: { top: 16 },
|
|
1008
|
-
}, onChange: (query) =>
|
|
1609
|
+
}, onChange: (query) => setEditViewQuery(query), beforeMount: (monaco) => defineEditorTheme(monaco, exports.theme), onMount: setEditorTheme }) }), (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1009
1610
|
display: "flex",
|
|
1010
1611
|
flexDirection: "row",
|
|
1011
1612
|
alignItems: "center",
|
|
@@ -1065,7 +1666,7 @@ function Modal({ isOpen, onRequestClose, children }) {
|
|
|
1065
1666
|
// zIndex: 1000,
|
|
1066
1667
|
}, children: children })] }));
|
|
1067
1668
|
}
|
|
1068
|
-
function TableCell({ table, clickTableCell }) {
|
|
1669
|
+
function TableCell({ table, clickTableCell, key }) {
|
|
1069
1670
|
const handleClickTableCell = () => {
|
|
1070
1671
|
clickTableCell(table);
|
|
1071
1672
|
};
|
|
@@ -1085,7 +1686,7 @@ function TableCell({ table, clickTableCell }) {
|
|
|
1085
1686
|
maxWidth: 520,
|
|
1086
1687
|
// lineHeight: "1.3em",
|
|
1087
1688
|
// height: "1.3em",
|
|
1088
|
-
}, children: tokens.map((line, i) => ((0, jsx_runtime_1.jsx)("div", { ...getLineProps({ line, key: i }), children: line.map((token, key) => ((0, jsx_runtime_1.jsx)("span", { ...getTokenProps({ token, key }) }, key))) }, i))) })) })] }));
|
|
1689
|
+
}, children: tokens.map((line, i) => ((0, jsx_runtime_1.jsx)("div", { ...getLineProps({ line, key: i }), children: line.map((token, key) => ((0, jsx_runtime_1.jsx)("span", { ...getTokenProps({ token, key }) }, key))) }, i))) })) })] }, table.displayName));
|
|
1089
1690
|
}
|
|
1090
1691
|
function QueryEditor({ TextInputComponent, ButtonComponent, SecondaryButtonComponent, ModalComponent, SelectComponent, }) {
|
|
1091
1692
|
const [customerId, setCustomerId] = (0, react_1.useState)("");
|
|
@@ -1149,75 +1750,6 @@ function QueryEditor({ TextInputComponent, ButtonComponent, SecondaryButtonCompo
|
|
|
1149
1750
|
};
|
|
1150
1751
|
}, [environment]);
|
|
1151
1752
|
// const navigate = useNavigate();
|
|
1152
|
-
const editChart = async ({ report, values, yAxisFields, columns, query }) => {
|
|
1153
|
-
const { publicKey, customerId, authToken } = client;
|
|
1154
|
-
const { xAxisLabel, yAxisLabel, chartName, chartType, xAxisField, xAxisFormat, dashboardName, dateFieldTable, dateField, } = values;
|
|
1155
|
-
if (!chartName) {
|
|
1156
|
-
alert("Please enter a chart name");
|
|
1157
|
-
return;
|
|
1158
|
-
}
|
|
1159
|
-
for (let i = 0; i < yAxisFields.length; i++) {
|
|
1160
|
-
if (!yAxisFields[i].label && chartType !== "pie") {
|
|
1161
|
-
alert(`Please enter a label for column '${yAxisFields[i].field}'`);
|
|
1162
|
-
return;
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
if (!client || !organization) {
|
|
1166
|
-
return;
|
|
1167
|
-
}
|
|
1168
|
-
const response = await fetch(`https://quill-344421.uc.r.appspot.com/dashedit/${client._id}/${organization.id}/`, {
|
|
1169
|
-
method: "POST",
|
|
1170
|
-
headers: {
|
|
1171
|
-
"Content-Type": "application/json",
|
|
1172
|
-
Authorization: `Bearer ${authToken}`,
|
|
1173
|
-
environment: environment || undefined,
|
|
1174
|
-
},
|
|
1175
|
-
body: JSON.stringify({
|
|
1176
|
-
name: chartName,
|
|
1177
|
-
xAxisField,
|
|
1178
|
-
yAxisFields,
|
|
1179
|
-
xAxisLabel,
|
|
1180
|
-
xAxisFormat,
|
|
1181
|
-
yAxisLabel,
|
|
1182
|
-
chartType,
|
|
1183
|
-
dashboardName,
|
|
1184
|
-
columns,
|
|
1185
|
-
dateField: { table: dateFieldTable, field: dateField },
|
|
1186
|
-
query: query,
|
|
1187
|
-
}),
|
|
1188
|
-
});
|
|
1189
|
-
const responseData = await response.json();
|
|
1190
|
-
if (!responseData) {
|
|
1191
|
-
return;
|
|
1192
|
-
}
|
|
1193
|
-
// setDashboard((dashboard) => {
|
|
1194
|
-
// return {
|
|
1195
|
-
// ...dashboard,
|
|
1196
|
-
// [response.data._id]: { ...existingVisualization, ...response.data }
|
|
1197
|
-
// }
|
|
1198
|
-
// })
|
|
1199
|
-
setIsOpen(false);
|
|
1200
|
-
setActiveComponent("/Dashboards");
|
|
1201
|
-
};
|
|
1202
|
-
const handleRunSqlPrompt = async () => {
|
|
1203
|
-
const { _id } = client;
|
|
1204
|
-
setSqlResponseLoading(true);
|
|
1205
|
-
const response = await fetch(`https://quill-344421.uc.r.appspot.com/quillai`, {
|
|
1206
|
-
method: "POST",
|
|
1207
|
-
headers: {
|
|
1208
|
-
Authorization: `Bearer `,
|
|
1209
|
-
environment: environment,
|
|
1210
|
-
"Content-Type": "application/json", // Important when sending JSON
|
|
1211
|
-
},
|
|
1212
|
-
body: JSON.stringify({
|
|
1213
|
-
initialQuestion: sqlPrompt,
|
|
1214
|
-
publicKey: _id,
|
|
1215
|
-
}),
|
|
1216
|
-
});
|
|
1217
|
-
const responseData = await response.json();
|
|
1218
|
-
setQuery(responseData.message);
|
|
1219
|
-
setSqlResponseLoading(false);
|
|
1220
|
-
};
|
|
1221
1753
|
const handleRunQuery = async () => {
|
|
1222
1754
|
const { _id } = client;
|
|
1223
1755
|
try {
|
|
@@ -1501,11 +2033,38 @@ const FORMAT_OPTIONS = [
|
|
|
1501
2033
|
{ value: "percent", label: "percent" },
|
|
1502
2034
|
{ value: "string", label: "string" },
|
|
1503
2035
|
];
|
|
1504
|
-
function Report({ reportId, saveDashboardItem, isOpen, setIsOpen, isEditQueryOpen, setIsEditQueryOpen, SecondaryButtonComponent,
|
|
2036
|
+
function Report({ reportId, saveDashboardItem, isOpen, setIsOpen, isEditQueryOpen, setIsEditQueryOpen, SecondaryButtonComponent, ButtonComponent, deleteReport, updateQuery, }) {
|
|
1505
2037
|
const { data, loading, error } = (0, react_2.useQuill)(reportId);
|
|
1506
2038
|
const [client] = (0, react_1.useContext)(ClientContext);
|
|
1507
2039
|
const [activeQuery, setActiveQuery] = (0, react_1.useContext)(ActiveQueryContext);
|
|
1508
2040
|
const [activeComponent, setActiveComponent] = (0, react_1.useContext)(ActiveComponentContext);
|
|
2041
|
+
const downloadCSV = () => {
|
|
2042
|
+
// report.rows
|
|
2043
|
+
if (!data) {
|
|
2044
|
+
return;
|
|
2045
|
+
}
|
|
2046
|
+
const json = data.rows; // JSON data passed as a prop
|
|
2047
|
+
const fields = Object.keys(json[0]); // Assumes all objects have same keys
|
|
2048
|
+
const csvRows = [];
|
|
2049
|
+
// Header row
|
|
2050
|
+
csvRows.push(fields.join(","));
|
|
2051
|
+
// Data rows
|
|
2052
|
+
for (let row of json) {
|
|
2053
|
+
let values = fields.map((field) => JSON.stringify(row[field] || ""));
|
|
2054
|
+
csvRows.push(values.join(","));
|
|
2055
|
+
}
|
|
2056
|
+
// Create CSV string and create a 'blob' with it
|
|
2057
|
+
const csvString = csvRows.join("\r\n");
|
|
2058
|
+
const csvBlob = new Blob([csvString], { type: "text/csv" });
|
|
2059
|
+
// Create a download link and click it
|
|
2060
|
+
const downloadLink = document.createElement("a");
|
|
2061
|
+
downloadLink.download = "download.csv";
|
|
2062
|
+
downloadLink.href = URL.createObjectURL(csvBlob);
|
|
2063
|
+
downloadLink.style.display = "none";
|
|
2064
|
+
document.body.appendChild(downloadLink);
|
|
2065
|
+
downloadLink.click();
|
|
2066
|
+
document.body.removeChild(downloadLink);
|
|
2067
|
+
};
|
|
1509
2068
|
const goBack = () => {
|
|
1510
2069
|
setActiveComponent("Dashboards");
|
|
1511
2070
|
};
|
|
@@ -1533,11 +2092,11 @@ function Report({ reportId, saveDashboardItem, isOpen, setIsOpen, isEditQueryOpe
|
|
|
1533
2092
|
}, children: [(0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Edit chart", onClick: () => setIsOpen(true) }), (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Edit query", onClick: () => setIsEditQueryOpen(true) }), (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Open query", onClick: () => {
|
|
1534
2093
|
setActiveQuery(data.queryString);
|
|
1535
2094
|
setActiveComponent("SQL editor");
|
|
1536
|
-
} }), (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Delete", onClick: deleteReport })] }), (0, jsx_runtime_1.jsx)(react_2.Table
|
|
2095
|
+
} }), (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Delete", onClick: deleteReport })] }), data.chartType !== "table" && ((0, jsx_runtime_1.jsx)(react_2.Table
|
|
1537
2096
|
// containerStyle={{ width: "80vw", height: 1100 }}
|
|
1538
2097
|
, {
|
|
1539
2098
|
// containerStyle={{ width: "80vw", height: 1100 }}
|
|
1540
|
-
containerStyle: { height: 400, width: "100%", marginTop: 24 }, chartId: reportId }), (0, jsx_runtime_1.jsx)(
|
|
2099
|
+
containerStyle: { height: 400, width: "100%", marginTop: 24 }, chartId: reportId })), (0, jsx_runtime_1.jsx)(EditVisualizationModal, { isOpen: isOpen, setIsOpen: setIsOpen, report: data, data: data.rows, query: data.queryString, columns: data.columns, fields: data.fields }), (0, jsx_runtime_1.jsx)(EditQueryModal, { query: data.queryString, report: data, isOpen: isEditQueryOpen, setIsOpen: setIsEditQueryOpen, updateQuery: updateQuery })] }));
|
|
1541
2100
|
}
|
|
1542
2101
|
function EditQueryModal({ query, report, isOpen, setIsOpen, updateQuery }) {
|
|
1543
2102
|
const [newQuery, setNewQuery] = (0, react_1.useState)(query);
|
|
@@ -1591,7 +2150,7 @@ function EditVisualizationModal({ isOpen, setIsOpen, report, columns, data, fiel
|
|
|
1591
2150
|
}
|
|
1592
2151
|
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: isOpen && ((0, jsx_runtime_1.jsxs)("div", { className: "fixed inset-0 overflow-y-auto relative", style: { zIndex: 120 }, children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 bg-black/30", "aria-hidden": "true", onClick: () => setIsOpen(false) }), (0, jsx_runtime_1.jsx)("div", { className: "flex min-h-full items-center justify-center p-4", children: (0, jsx_runtime_1.jsx)("div", { className: "bg-white px-7 py-7 rounded-lg", children: (0, jsx_runtime_1.jsx)(react_2.AddToDashboardModal, { fields: fields, isOpen: isOpen, setIsOpen: setIsOpen, rows: data, columns: columns, query: query, report: report, showTableFormatOptions: true, showDateFieldOptions: true, showAccessControlOptions: true }) }) })] })) }));
|
|
1593
2152
|
}
|
|
1594
|
-
function ReportWrapper({ SecondaryButtonComponent, ButtonComponent, ModalComponent, SelectComponent,
|
|
2153
|
+
function ReportWrapper({ SecondaryButtonComponent, ButtonComponent, ModalComponent, SelectComponent, }) {
|
|
1595
2154
|
const [organization, setOrganization] = (0, react_1.useContext)(OrganizationContext);
|
|
1596
2155
|
const [client] = (0, react_1.useContext)(ClientContext);
|
|
1597
2156
|
const [environment] = (0, react_1.useContext)(EnvironmentContext);
|
|
@@ -1628,10 +2187,10 @@ function ReportWrapper({ SecondaryButtonComponent, ButtonComponent, ModalCompone
|
|
|
1628
2187
|
if (!reportId) {
|
|
1629
2188
|
return;
|
|
1630
2189
|
}
|
|
1631
|
-
if (!client
|
|
2190
|
+
if (!client) {
|
|
1632
2191
|
return;
|
|
1633
2192
|
}
|
|
1634
|
-
const url = `https://quill-344421.uc.r.appspot.com/deletedash/${client._id}/${
|
|
2193
|
+
const url = `https://quill-344421.uc.r.appspot.com/deletedash/${client._id}/${customerId}/`;
|
|
1635
2194
|
const requestBody = {
|
|
1636
2195
|
dashboardItemId: reportId,
|
|
1637
2196
|
};
|