@quillsql/admin 1.5.2 → 1.6.1
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/dist/cjs/Admin.d.ts +19 -72
- package/dist/cjs/Admin.d.ts.map +1 -1
- package/dist/cjs/Admin.js +215 -996
- package/dist/cjs/AdminProvider.d.ts +2 -12
- package/dist/cjs/AdminProvider.d.ts.map +1 -1
- package/dist/cjs/AdminProvider.js +27 -32
- package/dist/cjs/api/ConnectionClient.d.ts +19 -0
- package/dist/cjs/api/ConnectionClient.d.ts.map +1 -1
- package/dist/cjs/api/ConnectionClient.js +108 -13
- package/dist/cjs/components/DashboardSelectPopover.d.ts.map +1 -1
- package/dist/cjs/components/DashboardSelectPopover.js +20 -3
- package/dist/cjs/components/DropDownMenu.js +1 -1
- package/dist/cjs/components/DropDownMenuWithLabel.d.ts.map +1 -1
- package/dist/cjs/components/DropDownMenuWithLabel.js +18 -87
- package/dist/cjs/components/EmptyDashboardComponent/index.d.ts.map +1 -1
- package/dist/cjs/components/EmptyDashboardComponent/index.js +11 -9
- package/dist/cjs/components/OrgSelect.d.ts.map +1 -1
- package/dist/cjs/components/OrgSelect.js +10 -20
- package/dist/cjs/components/QuillSelect.d.ts +3 -0
- package/dist/cjs/components/QuillSelect.d.ts.map +1 -0
- package/dist/cjs/components/QuillSelect.js +137 -0
- package/dist/cjs/components/SegmentedControl.d.ts +9 -0
- package/dist/cjs/components/SegmentedControl.d.ts.map +1 -0
- package/dist/cjs/components/SegmentedControl.js +60 -0
- package/dist/cjs/components/SqlTextEditor.d.ts +9 -1
- package/dist/cjs/components/SqlTextEditor.d.ts.map +1 -1
- package/dist/cjs/components/SqlTextEditor.js +60 -12
- package/dist/cjs/components/UiComponents.d.ts +18 -30
- package/dist/cjs/components/UiComponents.d.ts.map +1 -1
- package/dist/cjs/components/UiComponents.js +48 -84
- package/dist/cjs/constants/dataTypes.d.ts +2 -0
- package/dist/cjs/constants/dataTypes.d.ts.map +1 -0
- package/dist/cjs/constants/dataTypes.js +21 -0
- package/dist/cjs/forms/client_onboard/ConnectDatabase.d.ts.map +1 -1
- package/dist/cjs/forms/client_onboard/ConnectDatabase.js +9 -17
- package/dist/cjs/forms/client_onboard/ConnectSchema.d.ts +2 -1
- package/dist/cjs/forms/client_onboard/ConnectSchema.d.ts.map +1 -1
- package/dist/cjs/forms/client_onboard/ConnectSchema.js +143 -68
- package/dist/cjs/forms/client_onboard/CreateSqlViews.d.ts.map +1 -1
- package/dist/cjs/forms/client_onboard/CreateSqlViews.js +57 -15
- package/dist/cjs/forms/sql_views/CreateEditSqlView.d.ts +11 -5
- package/dist/cjs/forms/sql_views/CreateEditSqlView.d.ts.map +1 -1
- package/dist/cjs/forms/sql_views/CreateEditSqlView.js +107 -53
- package/dist/cjs/hooks/useOnClickOutside.d.ts +3 -0
- package/dist/cjs/hooks/useOnClickOutside.d.ts.map +1 -0
- package/dist/cjs/hooks/useOnClickOutside.js +20 -0
- package/dist/cjs/modals/EditFiltersModal.d.ts +17 -0
- package/dist/cjs/modals/EditFiltersModal.d.ts.map +1 -0
- package/dist/cjs/modals/EditFiltersModal.js +355 -0
- package/dist/cjs/modals/NewDashboardModal.d.ts +1 -3
- package/dist/cjs/modals/NewDashboardModal.d.ts.map +1 -1
- package/dist/cjs/modals/NewDashboardModal.js +64 -47
- package/dist/cjs/modals/PromoteDashModal.d.ts.map +1 -1
- package/dist/cjs/modals/PromoteDashModal.js +11 -4
- package/dist/cjs/modals/PromoteViewModal.d.ts +2 -1
- package/dist/cjs/modals/PromoteViewModal.d.ts.map +1 -1
- package/dist/cjs/modals/PromoteViewModal.js +46 -36
- package/dist/cjs/modals/ReorderDashboardModal.d.ts.map +1 -1
- package/dist/cjs/modals/ReorderDashboardModal.js +42 -45
- package/dist/cjs/modals/index.d.ts +0 -1
- package/dist/cjs/modals/index.d.ts.map +1 -1
- package/dist/cjs/modals/index.js +1 -3
- package/dist/cjs/primitives/ButtonPrimitive.d.ts +3 -1
- package/dist/cjs/primitives/ButtonPrimitive.d.ts.map +1 -1
- package/dist/cjs/primitives/ButtonPrimitive.js +5 -3
- package/dist/cjs/primitives/TextInputPrimitive.d.ts +1 -0
- package/dist/cjs/primitives/TextInputPrimitive.d.ts.map +1 -1
- package/dist/cjs/primitives/TextInputPrimitive.js +35 -20
- package/dist/cjs/primitives/TogglePrimitive.js +5 -5
- package/dist/cjs/public_components/CreateEnvironment.d.ts +2 -1
- package/dist/cjs/public_components/CreateEnvironment.d.ts.map +1 -1
- package/dist/cjs/public_components/CreateEnvironment.js +5 -2
- package/dist/cjs/public_components/DashboardBuilder.d.ts.map +1 -1
- package/dist/cjs/public_components/DashboardBuilder.js +71 -125
- package/dist/cjs/public_components/DashboardManager.d.ts.map +1 -1
- package/dist/cjs/public_components/DashboardManager.js +109 -146
- package/dist/cjs/public_components/SQLViewManager.d.ts +1 -0
- package/dist/cjs/public_components/SQLViewManager.d.ts.map +1 -1
- package/dist/cjs/public_components/SQLViewManager.js +271 -46
- package/dist/cjs/utils/astProcessing.d.ts +2 -0
- package/dist/cjs/utils/astProcessing.d.ts.map +1 -0
- package/dist/cjs/utils/astProcessing.js +41 -0
- package/dist/cjs/utils/astProcessing.uspec.d.ts +2 -0
- package/dist/cjs/utils/astProcessing.uspec.d.ts.map +1 -0
- package/dist/cjs/utils/astProcessing.uspec.js +26 -0
- package/dist/cjs/utils/columnProcessing.d.ts +3 -0
- package/dist/cjs/utils/columnProcessing.d.ts.map +1 -0
- package/dist/cjs/utils/columnProcessing.js +42 -0
- package/dist/cjs/utils/dataEditor.d.ts +2 -2
- package/dist/cjs/utils/dataEditor.d.ts.map +1 -1
- package/dist/cjs/utils/dataEditor.js +4 -2
- package/dist/cjs/utils/databases.d.ts +0 -1
- package/dist/cjs/utils/databases.d.ts.map +1 -1
- package/dist/cjs/utils/databases.js +5 -6
- package/dist/cjs/utils/monacoAutocomplete.d.ts +21 -0
- package/dist/cjs/utils/monacoAutocomplete.d.ts.map +1 -0
- package/dist/cjs/utils/monacoAutocomplete.js +250 -0
- package/dist/cjs/utils/schema.d.ts +11 -0
- package/dist/cjs/utils/schema.d.ts.map +1 -1
- package/dist/cjs/utils/schema.js +129 -0
- package/dist/cjs/utils/table.d.ts +1 -0
- package/dist/cjs/utils/table.d.ts.map +1 -1
- package/dist/cjs/utils/table.js +13 -0
- package/dist/cjs/utils/textProcessing.d.ts +2 -0
- package/dist/cjs/utils/textProcessing.d.ts.map +1 -0
- package/dist/cjs/utils/textProcessing.js +9 -0
- package/dist/esm/Admin.d.ts +19 -72
- package/dist/esm/Admin.d.ts.map +1 -1
- package/dist/esm/Admin.js +218 -989
- package/dist/esm/AdminProvider.d.ts +2 -12
- package/dist/esm/AdminProvider.d.ts.map +1 -1
- package/dist/esm/AdminProvider.js +27 -32
- package/dist/esm/api/ConnectionClient.d.ts +19 -0
- package/dist/esm/api/ConnectionClient.d.ts.map +1 -1
- package/dist/esm/api/ConnectionClient.js +106 -12
- package/dist/esm/components/DashboardSelectPopover.d.ts.map +1 -1
- package/dist/esm/components/DashboardSelectPopover.js +20 -3
- package/dist/esm/components/DropDownMenu.js +1 -1
- package/dist/esm/components/DropDownMenuWithLabel.d.ts.map +1 -1
- package/dist/esm/components/DropDownMenuWithLabel.js +18 -87
- package/dist/esm/components/EmptyDashboardComponent/index.d.ts.map +1 -1
- package/dist/esm/components/EmptyDashboardComponent/index.js +11 -9
- package/dist/esm/components/OrgSelect.d.ts.map +1 -1
- package/dist/esm/components/OrgSelect.js +6 -19
- package/dist/esm/components/QuillSelect.d.ts +3 -0
- package/dist/esm/components/QuillSelect.d.ts.map +1 -0
- package/dist/esm/components/QuillSelect.js +130 -0
- package/dist/esm/components/SegmentedControl.d.ts +9 -0
- package/dist/esm/components/SegmentedControl.d.ts.map +1 -0
- package/dist/esm/components/SegmentedControl.js +56 -0
- package/dist/esm/components/SqlTextEditor.d.ts +9 -1
- package/dist/esm/components/SqlTextEditor.d.ts.map +1 -1
- package/dist/esm/components/SqlTextEditor.js +59 -11
- package/dist/esm/components/UiComponents.d.ts +18 -30
- package/dist/esm/components/UiComponents.d.ts.map +1 -1
- package/dist/esm/components/UiComponents.js +45 -83
- package/dist/esm/constants/dataTypes.d.ts +2 -0
- package/dist/esm/constants/dataTypes.d.ts.map +1 -0
- package/dist/esm/constants/dataTypes.js +18 -0
- package/dist/esm/forms/client_onboard/ConnectDatabase.d.ts.map +1 -1
- package/dist/esm/forms/client_onboard/ConnectDatabase.js +9 -17
- package/dist/esm/forms/client_onboard/ConnectSchema.d.ts +2 -1
- package/dist/esm/forms/client_onboard/ConnectSchema.d.ts.map +1 -1
- package/dist/esm/forms/client_onboard/ConnectSchema.js +145 -70
- package/dist/esm/forms/client_onboard/CreateSqlViews.d.ts.map +1 -1
- package/dist/esm/forms/client_onboard/CreateSqlViews.js +58 -16
- package/dist/esm/forms/sql_views/CreateEditSqlView.d.ts +11 -5
- package/dist/esm/forms/sql_views/CreateEditSqlView.d.ts.map +1 -1
- package/dist/esm/forms/sql_views/CreateEditSqlView.js +108 -54
- package/dist/esm/hooks/useOnClickOutside.d.ts +3 -0
- package/dist/esm/hooks/useOnClickOutside.d.ts.map +1 -0
- package/dist/esm/hooks/useOnClickOutside.js +18 -0
- package/dist/esm/modals/EditFiltersModal.d.ts +17 -0
- package/dist/esm/modals/EditFiltersModal.d.ts.map +1 -0
- package/dist/esm/modals/EditFiltersModal.js +348 -0
- package/dist/esm/modals/NewDashboardModal.d.ts +1 -3
- package/dist/esm/modals/NewDashboardModal.d.ts.map +1 -1
- package/dist/esm/modals/NewDashboardModal.js +64 -47
- package/dist/esm/modals/PromoteDashModal.d.ts.map +1 -1
- package/dist/esm/modals/PromoteDashModal.js +11 -4
- package/dist/esm/modals/PromoteViewModal.d.ts +2 -1
- package/dist/esm/modals/PromoteViewModal.d.ts.map +1 -1
- package/dist/esm/modals/PromoteViewModal.js +50 -40
- package/dist/esm/modals/ReorderDashboardModal.d.ts.map +1 -1
- package/dist/esm/modals/ReorderDashboardModal.js +43 -46
- package/dist/esm/modals/index.d.ts +0 -1
- package/dist/esm/modals/index.d.ts.map +1 -1
- package/dist/esm/modals/index.js +0 -1
- package/dist/esm/primitives/ButtonPrimitive.d.ts +3 -1
- package/dist/esm/primitives/ButtonPrimitive.d.ts.map +1 -1
- package/dist/esm/primitives/ButtonPrimitive.js +5 -3
- package/dist/esm/primitives/TextInputPrimitive.d.ts +1 -0
- package/dist/esm/primitives/TextInputPrimitive.d.ts.map +1 -1
- package/dist/esm/primitives/TextInputPrimitive.js +33 -21
- package/dist/esm/primitives/TogglePrimitive.js +5 -5
- package/dist/esm/public_components/CreateEnvironment.d.ts +2 -1
- package/dist/esm/public_components/CreateEnvironment.d.ts.map +1 -1
- package/dist/esm/public_components/CreateEnvironment.js +5 -2
- package/dist/esm/public_components/DashboardBuilder.d.ts.map +1 -1
- package/dist/esm/public_components/DashboardBuilder.js +72 -126
- package/dist/esm/public_components/DashboardManager.d.ts.map +1 -1
- package/dist/esm/public_components/DashboardManager.js +112 -149
- package/dist/esm/public_components/SQLViewManager.d.ts +1 -0
- package/dist/esm/public_components/SQLViewManager.d.ts.map +1 -1
- package/dist/esm/public_components/SQLViewManager.js +271 -48
- package/dist/esm/utils/astProcessing.d.ts +2 -0
- package/dist/esm/utils/astProcessing.d.ts.map +1 -0
- package/dist/esm/utils/astProcessing.js +37 -0
- package/dist/esm/utils/astProcessing.uspec.d.ts +2 -0
- package/dist/esm/utils/astProcessing.uspec.d.ts.map +1 -0
- package/dist/esm/utils/astProcessing.uspec.js +24 -0
- package/dist/esm/utils/columnProcessing.d.ts +3 -0
- package/dist/esm/utils/columnProcessing.d.ts.map +1 -0
- package/dist/esm/utils/columnProcessing.js +37 -0
- package/dist/esm/utils/dataEditor.d.ts +2 -2
- package/dist/esm/utils/dataEditor.d.ts.map +1 -1
- package/dist/esm/utils/dataEditor.js +4 -2
- package/dist/esm/utils/databases.d.ts +0 -1
- package/dist/esm/utils/databases.d.ts.map +1 -1
- package/dist/esm/utils/databases.js +5 -6
- package/dist/esm/utils/monacoAutocomplete.d.ts +21 -0
- package/dist/esm/utils/monacoAutocomplete.d.ts.map +1 -0
- package/dist/esm/utils/monacoAutocomplete.js +245 -0
- package/dist/esm/utils/schema.d.ts +11 -0
- package/dist/esm/utils/schema.d.ts.map +1 -1
- package/dist/esm/utils/schema.js +126 -1
- package/dist/esm/utils/table.d.ts +1 -0
- package/dist/esm/utils/table.d.ts.map +1 -1
- package/dist/esm/utils/table.js +11 -1
- package/dist/esm/utils/textProcessing.d.ts +2 -0
- package/dist/esm/utils/textProcessing.d.ts.map +1 -0
- package/dist/esm/utils/textProcessing.js +5 -0
- package/package.json +3 -2
- package/dist/cjs/modals/EditDashboardsModal.d.ts +0 -20
- package/dist/cjs/modals/EditDashboardsModal.d.ts.map +0 -1
- package/dist/cjs/modals/EditDashboardsModal.js +0 -94
- package/dist/esm/modals/EditDashboardsModal.d.ts +0 -20
- package/dist/esm/modals/EditDashboardsModal.d.ts.map +0 -1
- package/dist/esm/modals/EditDashboardsModal.js +0 -91
|
@@ -6,9 +6,30 @@ import { EnvSelectPopover } from '../components';
|
|
|
6
6
|
import { TableCell } from '../Admin';
|
|
7
7
|
import CreateEditSqlView from '../forms/sql_views/CreateEditSqlView';
|
|
8
8
|
import { addSqlView, editSQLView, deleteSQLView } from '../utils/dataEditor';
|
|
9
|
-
import { getTableColumnsBySchema } from '../api/ConnectionClient';
|
|
10
|
-
import { MemoizedButton, MemoizedDeleteButton, MemoizedSecondaryButton, } from '../components/UiComponents';
|
|
9
|
+
import { getSqlViewData, getTableColumnsBySchema, } from '../api/ConnectionClient';
|
|
10
|
+
import { LoadingSpinner, MemoizedButton, MemoizedDeleteButton, MemoizedModal, MemoizedSecondaryButton, } from '../components/UiComponents';
|
|
11
11
|
import DatabaseMismatchCard from '../components/DatabaseMismatchCard';
|
|
12
|
+
import TogglePrimitive from '../primitives/TogglePrimitive';
|
|
13
|
+
import { SegmentedControl } from '../components/SegmentedControl';
|
|
14
|
+
import SqlTextEditor from '../components/SqlTextEditor';
|
|
15
|
+
import { Table } from '@quillsql/react';
|
|
16
|
+
import { getSchemaInfo } from '../utils/schema';
|
|
17
|
+
import { PromoteViewModal } from '../modals';
|
|
18
|
+
export const getDuplicateColumns = (columns) => {
|
|
19
|
+
if (!columns) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
const columnCount = columns?.reduce((acc, curr) => {
|
|
23
|
+
if (acc[curr.field]) {
|
|
24
|
+
acc[curr.field] += 1;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
acc[curr.field] = 1;
|
|
28
|
+
}
|
|
29
|
+
return acc;
|
|
30
|
+
}, {});
|
|
31
|
+
return Object.keys(columnCount).filter((column) => columnCount[column] > 1);
|
|
32
|
+
};
|
|
12
33
|
export default function SQLViewManager({ containerStyle, }) {
|
|
13
34
|
const [tables, setTables] = useState(undefined);
|
|
14
35
|
const [modalIsOpen, setIsOpen] = useState(false);
|
|
@@ -24,14 +45,19 @@ export default function SQLViewManager({ containerStyle, }) {
|
|
|
24
45
|
const [deleteModalIsOpen, setDeleteModalIsOpen] = useState(false);
|
|
25
46
|
const [isPromoteViewModalOpen, setIsPromoteViewModalOpen] = useState(false);
|
|
26
47
|
const [allTableData, setAllTableData] = useState([]);
|
|
48
|
+
const [referencedTablesMap, setReferencedTablesMap] = useState({});
|
|
27
49
|
const [schemaIsLoading, setSchemaIsLoading] = useState(false);
|
|
50
|
+
const [customFieldInfo, setCustomFieldInfo] = useState(undefined);
|
|
51
|
+
const [provider, setProvider] = useState(null);
|
|
28
52
|
const [initialSqlView, setInitialSqlView] = useState(undefined);
|
|
53
|
+
const [submittingView, setSubmittingView] = useState(false);
|
|
29
54
|
const parentRef = useRef(null);
|
|
30
55
|
const { state, dispatch } = useAdmin();
|
|
31
56
|
const closeEditModal = () => {
|
|
32
57
|
setEditModalIsOpen(false);
|
|
33
58
|
setEditName('');
|
|
34
59
|
setEditViewQuery('');
|
|
60
|
+
setCustomFieldInfo(undefined);
|
|
35
61
|
};
|
|
36
62
|
const clickTableCell = (table) => {
|
|
37
63
|
setEditName(table.name);
|
|
@@ -42,9 +68,26 @@ export default function SQLViewManager({ containerStyle, }) {
|
|
|
42
68
|
name: table.name,
|
|
43
69
|
query: table.viewQuery,
|
|
44
70
|
});
|
|
71
|
+
setCustomFieldInfo(table.customFieldInfo);
|
|
45
72
|
setEditModalIsOpen(true);
|
|
46
73
|
};
|
|
47
74
|
const getTables = async () => {
|
|
75
|
+
const schemaData = await getSchemaInfo({
|
|
76
|
+
queryEndpoint: state.queryEndpoint,
|
|
77
|
+
queryHeaders: state.queryHeaders,
|
|
78
|
+
publicKey: state.client._id,
|
|
79
|
+
customerId: state.client.customerId,
|
|
80
|
+
gatherSchemaData: false,
|
|
81
|
+
}, 'svm');
|
|
82
|
+
setTables(schemaData);
|
|
83
|
+
};
|
|
84
|
+
const getSchemaTableDetails = async () => {
|
|
85
|
+
setSchemaIsLoading(true);
|
|
86
|
+
const response = await getTableColumnsBySchema(state.client._id, state.client.schemaNames, state.client.databaseType, state.queryEndpoint);
|
|
87
|
+
setAllTableData(response);
|
|
88
|
+
setSchemaIsLoading(false);
|
|
89
|
+
};
|
|
90
|
+
const getReferencedTablesMap = async () => {
|
|
48
91
|
const response = await fetch(`${state.queryEndpoint}`, {
|
|
49
92
|
method: 'POST',
|
|
50
93
|
headers: {
|
|
@@ -55,7 +98,7 @@ export default function SQLViewManager({ containerStyle, }) {
|
|
|
55
98
|
metadata: {
|
|
56
99
|
clientId: state.client._id,
|
|
57
100
|
publicKey: state.client._id,
|
|
58
|
-
task: '
|
|
101
|
+
task: 'referenced-tables-map',
|
|
59
102
|
databaseType: state.client.databaseType,
|
|
60
103
|
},
|
|
61
104
|
}),
|
|
@@ -64,74 +107,119 @@ export default function SQLViewManager({ containerStyle, }) {
|
|
|
64
107
|
throw new Error('Failed to fetch tables data');
|
|
65
108
|
}
|
|
66
109
|
const data = await response.json();
|
|
67
|
-
|
|
68
|
-
};
|
|
69
|
-
const getSchemaTableDetails = async () => {
|
|
70
|
-
setSchemaIsLoading(true);
|
|
71
|
-
const response = await getTableColumnsBySchema(state.client._id, state.client.schemaNames, state.client.databaseType, state.queryEndpoint);
|
|
72
|
-
setAllTableData(response);
|
|
73
|
-
setSchemaIsLoading(false);
|
|
110
|
+
setReferencedTablesMap(data.data.referencedTablesMap);
|
|
74
111
|
};
|
|
75
112
|
useEffect(() => {
|
|
76
113
|
let isSubscribed = true;
|
|
77
114
|
if (isSubscribed && state.client) {
|
|
78
115
|
getTables();
|
|
79
116
|
getSchemaTableDetails();
|
|
117
|
+
getReferencedTablesMap();
|
|
80
118
|
}
|
|
81
119
|
return () => {
|
|
82
120
|
isSubscribed = false;
|
|
83
121
|
};
|
|
84
122
|
}, [state.client]);
|
|
85
|
-
const
|
|
86
|
-
setTableToBeDeleted(editName);
|
|
87
|
-
setDeleteModalIsOpen(true);
|
|
88
|
-
};
|
|
89
|
-
const handleModalSubmit = async (submitRequest, query, name, id) => {
|
|
123
|
+
const handleModalSubmit = async (submitRequest, query, name, id, columns, customFieldInfo) => {
|
|
90
124
|
try {
|
|
125
|
+
const prevTableName = tables?.find((table) => table._id === id)?.name;
|
|
126
|
+
const isPlural = referencedTablesMap &&
|
|
127
|
+
referencedTablesMap[prevTableName] &&
|
|
128
|
+
referencedTablesMap[prevTableName].length > 1
|
|
129
|
+
? 's'
|
|
130
|
+
: '';
|
|
131
|
+
let trimmedName = name?.trim() || undefined;
|
|
132
|
+
let submitResponse;
|
|
91
133
|
switch (submitRequest) {
|
|
92
134
|
case 'add':
|
|
93
|
-
if (!
|
|
94
|
-
alert('No
|
|
135
|
+
if (!trimmedName) {
|
|
136
|
+
alert('No name found');
|
|
95
137
|
return;
|
|
96
138
|
}
|
|
97
|
-
if (tables?.map((table) => table.name).includes(
|
|
139
|
+
if (tables?.map((table) => table.name).includes(trimmedName)) {
|
|
98
140
|
alert('Name already exists');
|
|
99
141
|
return;
|
|
100
142
|
}
|
|
101
|
-
if
|
|
102
|
-
|
|
143
|
+
// determine if there are duplicate names if there are then alert the user
|
|
144
|
+
let duplicateColumns = getDuplicateColumns(columns);
|
|
145
|
+
if (duplicateColumns.length > 0) {
|
|
146
|
+
alert(`Ambiguous column names found. Either use aliases or remove the column to make every column name unique: \n\n${duplicateColumns.join('\n')}`);
|
|
103
147
|
return;
|
|
104
148
|
}
|
|
105
|
-
|
|
149
|
+
if (!/^[a-z0-9_]+$/.test(trimmedName)) {
|
|
150
|
+
alert('Names can only include lowercase letters, numbers, and underscores');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
submitResponse = await addSqlView(trimmedName, query, customFieldInfo, state);
|
|
106
154
|
break;
|
|
107
155
|
case 'edit':
|
|
108
156
|
if (!id) {
|
|
109
157
|
return;
|
|
110
158
|
}
|
|
111
|
-
if (
|
|
112
|
-
|
|
159
|
+
if (referencedTablesMap && referencedTablesMap[prevTableName]) {
|
|
160
|
+
// This condition is for only query edits
|
|
161
|
+
if (editQueryView) {
|
|
162
|
+
const errorColumns = [];
|
|
163
|
+
referencedTablesMap[prevTableName] = referencedTablesMap[prevTableName].forEach((table) => {
|
|
164
|
+
table.referencedColumns.forEach((column) => {
|
|
165
|
+
if (!columns?.find((col) => {
|
|
166
|
+
return col.field === column;
|
|
167
|
+
})) {
|
|
168
|
+
errorColumns.push(`'${column}' referenced by ${table.dashboardName} - ${table.reportName}`);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
if (errorColumns.length > 0) {
|
|
173
|
+
alert(`Edit Error\n\n${errorColumns.join('\n')} \n\nPlease modify your query to include these columns.`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
const referencedTableInfo = referencedTablesMap[prevTableName].map((info) => {
|
|
179
|
+
return `${info.dashboardName} - ${info.reportName}`;
|
|
180
|
+
});
|
|
181
|
+
alert(`Edit Error\n\n${referencedTableInfo.join('\n')} \n\nPlease delete those charts before renaming this table.`);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (!trimmedName) {
|
|
186
|
+
alert('No name found');
|
|
113
187
|
return;
|
|
114
188
|
}
|
|
115
|
-
if (!/^[a-z0-9_]+$/.test(
|
|
189
|
+
if (!/^[a-z0-9_]+$/.test(trimmedName)) {
|
|
116
190
|
alert('Names can only include lowercase letters, numbers, and underscores');
|
|
117
191
|
return;
|
|
118
192
|
}
|
|
193
|
+
// determine if there are duplicate names if there are then alert the user
|
|
194
|
+
const duplicateColumns2 = getDuplicateColumns(columns);
|
|
195
|
+
if (duplicateColumns2.length > 0) {
|
|
196
|
+
alert(`Ambiguous column names found. Either use aliases or remove the column to make every column name unique: \n\n${duplicateColumns2.join('\n')}`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
119
199
|
// check if the tableName is present excluding the table with the same id
|
|
120
200
|
if (tables
|
|
121
201
|
?.filter((table) => table._id !== id)
|
|
122
202
|
.map((table) => table.name)
|
|
123
|
-
.includes(
|
|
203
|
+
.includes(trimmedName)) {
|
|
124
204
|
alert('Name already exists');
|
|
125
205
|
return;
|
|
126
206
|
}
|
|
127
|
-
await editSQLView(
|
|
207
|
+
submitResponse = await editSQLView(trimmedName, query, id, customFieldInfo, state);
|
|
128
208
|
break;
|
|
129
209
|
case 'delete':
|
|
130
210
|
if (!id) {
|
|
131
211
|
alert('No id found');
|
|
132
212
|
return;
|
|
133
213
|
}
|
|
134
|
-
|
|
214
|
+
// Determine if the table is referenced in other charts
|
|
215
|
+
if (referencedTablesMap && referencedTablesMap[prevTableName]) {
|
|
216
|
+
const referencedTableInfo = referencedTablesMap[prevTableName].map((info) => {
|
|
217
|
+
return `${info.dashboardName} - ${info.reportName}`;
|
|
218
|
+
});
|
|
219
|
+
alert(`This table is referenced in the following dashboard${isPlural}/chart${isPlural}.\n\n${referencedTableInfo.join('\n')} \n\nPlease delete those charts before deleting this table.`);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
submitResponse = await deleteSQLView(id, state);
|
|
135
223
|
break;
|
|
136
224
|
default:
|
|
137
225
|
setEditName('');
|
|
@@ -140,6 +228,10 @@ export default function SQLViewManager({ containerStyle, }) {
|
|
|
140
228
|
setEditModalIsOpen(true);
|
|
141
229
|
return;
|
|
142
230
|
}
|
|
231
|
+
if (submitResponse.status !== 'success') {
|
|
232
|
+
alert(`There was an error processing your ${submitRequest} request.`);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
143
235
|
await getTables();
|
|
144
236
|
closeEditModal();
|
|
145
237
|
setEditQueryView(false);
|
|
@@ -148,21 +240,13 @@ export default function SQLViewManager({ containerStyle, }) {
|
|
|
148
240
|
console.error(e);
|
|
149
241
|
}
|
|
150
242
|
};
|
|
151
|
-
const handleEditAddView = async (request, query, name, id) => {
|
|
243
|
+
const handleEditAddView = async (request, query, name, id, columns) => {
|
|
152
244
|
switch (request) {
|
|
153
245
|
case 'edit':
|
|
154
|
-
|
|
155
|
-
alert('No name found');
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
if (!id) {
|
|
159
|
-
alert('No id found');
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
await handleModalSubmit('edit', query, name, id);
|
|
246
|
+
await handleModalSubmit('edit', query, name, id, columns);
|
|
163
247
|
break;
|
|
164
248
|
default:
|
|
165
|
-
await handleModalSubmit('final-edit', query);
|
|
249
|
+
await handleModalSubmit('final-edit', query, undefined, undefined, columns);
|
|
166
250
|
break;
|
|
167
251
|
}
|
|
168
252
|
};
|
|
@@ -195,7 +279,7 @@ export default function SQLViewManager({ containerStyle, }) {
|
|
|
195
279
|
borderLeftWidth: 0,
|
|
196
280
|
borderRightWidth: 0,
|
|
197
281
|
borderStyle: 'solid',
|
|
198
|
-
borderColor: state.theme
|
|
282
|
+
borderColor: state.theme?.borderColor,
|
|
199
283
|
paddingBottom: 20,
|
|
200
284
|
// boxShadow: "0px 1px 4px 0px rgba(0, 0, 0, 0.07)",
|
|
201
285
|
// paddingRight: '50px',
|
|
@@ -231,14 +315,31 @@ export default function SQLViewManager({ containerStyle, }) {
|
|
|
231
315
|
paddingTop: 25,
|
|
232
316
|
}, children: tables && tables?.length
|
|
233
317
|
? tables.map((table) => (_jsx(TableCell, { table: table, clickTableCell: clickTableCell }, table._id)))
|
|
234
|
-
: null }, 'edit-view-query')) : (_jsx(CreateEditSqlView, { containerStyle: {}, initialSqlView: initialSqlView, closeEditView: () => setEditQueryView(false), addEditView: (request, name, query, id) => {
|
|
235
|
-
handleEditAddView(request, name, query, id);
|
|
236
|
-
}, allTableData: allTableData, schemaIsLoading: schemaIsLoading })) }))] }), _jsx(EditAddViewModal, { viewName: editName, viewQuery: editViewQuery, viewId: editViewId, editModalIsOpen: editModalIsOpen, closeEditModal: closeEditModal, submit:
|
|
318
|
+
: null }, 'edit-view-query')) : (_jsx(CreateEditSqlView, { containerStyle: {}, initialSqlView: initialSqlView, closeEditView: () => setEditQueryView(false), addEditView: (request, name, query, id, columns) => {
|
|
319
|
+
handleEditAddView(request, name, query, id, columns);
|
|
320
|
+
}, setProvider: (provider) => { setProvider(provider); }, provider: provider, allTableData: allTableData, schemaIsLoading: schemaIsLoading })) }))] }), _jsx(PromoteViewModal, { clientId: state.client._id, client: state.client, clients: state.clients, isOpen: isPromoteViewModalOpen, setIsOpen: setIsPromoteViewModalOpen, ModalComponent: MemoizedModal, views: tables || [], parentRef: parentRef }), _jsx(EditAddViewModal, { viewName: editName, viewQuery: editViewQuery, viewId: editViewId, editModalIsOpen: editModalIsOpen, customFieldInfo: customFieldInfo, closeEditModal: closeEditModal, submit: async (submitRequest, query, name, id, columns, customFieldInfo) => {
|
|
321
|
+
if (submitRequest !== 'delete') {
|
|
322
|
+
setSubmittingView(true);
|
|
323
|
+
}
|
|
324
|
+
await handleModalSubmit(submitRequest, query, name, id, columns, customFieldInfo);
|
|
325
|
+
setSubmittingView(false);
|
|
326
|
+
}, state: state, onEditViewClick: () => setEditQueryView(true), isLoading: submittingView })] }));
|
|
237
327
|
}
|
|
238
|
-
function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, closeEditModal, submit, state, onEditViewClick = () => { }, }) {
|
|
328
|
+
function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, customFieldInfo, closeEditModal, submit, state, onEditViewClick = () => { }, isLoading, }) {
|
|
239
329
|
const [name, setName] = useState(viewName);
|
|
240
330
|
const [query, setQuery] = useState(viewQuery);
|
|
241
331
|
const [id, setId] = useState(viewId);
|
|
332
|
+
const [useCustomField, setUseCustomField] = useState(customFieldInfo ? true : false);
|
|
333
|
+
const [customFieldType, setCustomFieldType] = useState(customFieldInfo ? customFieldInfo.type : 'eav');
|
|
334
|
+
const [customFieldQuery, setCustomFieldQuery] = useState(customFieldInfo ? customFieldInfo.query : '');
|
|
335
|
+
const [runQueryButtonLoading, setRunQueryButtonLoading] = useState(false);
|
|
336
|
+
const [tableData, setTableData] = useState(undefined);
|
|
337
|
+
const [errorInfo, setErrorInfo] = useState({ show: false, message: '' });
|
|
338
|
+
useEffect(() => {
|
|
339
|
+
setCustomFieldQuery(customFieldInfo?.query || '');
|
|
340
|
+
setCustomFieldType(customFieldInfo?.type || 'eav');
|
|
341
|
+
setUseCustomField(customFieldInfo ? true : false);
|
|
342
|
+
}, [customFieldInfo]);
|
|
242
343
|
useEffect(() => {
|
|
243
344
|
setName(viewName);
|
|
244
345
|
}, [viewName]);
|
|
@@ -248,7 +349,15 @@ function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, closeE
|
|
|
248
349
|
useEffect(() => {
|
|
249
350
|
setId(viewId);
|
|
250
351
|
}, [viewId]);
|
|
251
|
-
return (_jsx(ModalPrimitive, { isOpen: editModalIsOpen, close:
|
|
352
|
+
return (_jsx(ModalPrimitive, { isOpen: editModalIsOpen, close: () => {
|
|
353
|
+
setUseCustomField(false);
|
|
354
|
+
setCustomFieldType('eav');
|
|
355
|
+
setCustomFieldQuery('');
|
|
356
|
+
setTableData(undefined);
|
|
357
|
+
setErrorInfo({ show: false, message: '' });
|
|
358
|
+
setName('');
|
|
359
|
+
closeEditModal();
|
|
360
|
+
}, children: _jsxs("div", { style: { height: '100%', overflow: 'scroll', width: '100%' }, children: [_jsxs("div", { style: {
|
|
252
361
|
display: 'flex',
|
|
253
362
|
flexDirection: 'row',
|
|
254
363
|
alignItems: 'center',
|
|
@@ -281,7 +390,6 @@ function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, closeE
|
|
|
281
390
|
fontWeight: 'medium',
|
|
282
391
|
height: '120px',
|
|
283
392
|
boxShadow: '0 1px 2px 0 rgba(0,0,0,.05)',
|
|
284
|
-
width: '500px',
|
|
285
393
|
background: 'linear-gradient(white 50%, transparent)',
|
|
286
394
|
color: state.theme?.primaryTextColor,
|
|
287
395
|
borderWidth: '1px',
|
|
@@ -315,7 +423,81 @@ function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, closeE
|
|
|
315
423
|
} }), viewName && (_jsx("div", { style: { position: 'absolute', bottom: '10px', right: '10px' }, children: _jsx(MemoizedSecondaryButton, { label: 'Edit Query ↗', onClick: () => {
|
|
316
424
|
closeEditModal();
|
|
317
425
|
onEditViewClick();
|
|
318
|
-
} }) }))] }),
|
|
426
|
+
} }) }))] }), _jsx("br", {}), ['65d65b57cdd8ae70a5648d9c', '665610862cf7a3000be66453'].includes(state.client._id) &&
|
|
427
|
+
state.client.databaseType === 'PostgreSQL' && (_jsxs(_Fragment, { children: [_jsx("h3", { style: {
|
|
428
|
+
fontWeight: '600',
|
|
429
|
+
fontSize: '14px',
|
|
430
|
+
marginBottom: '6px',
|
|
431
|
+
color: '#212121',
|
|
432
|
+
}, children: "Custom fields" }), _jsx(TogglePrimitive, { value: useCustomField, onClick: () => {
|
|
433
|
+
setUseCustomField((useCustomField) => !useCustomField);
|
|
434
|
+
} }), _jsx("br", {}), useCustomField && (_jsxs(_Fragment, { children: [_jsx("h3", { style: {
|
|
435
|
+
fontWeight: '600',
|
|
436
|
+
fontSize: '14px',
|
|
437
|
+
marginBottom: '6px',
|
|
438
|
+
marginTop: '20px',
|
|
439
|
+
color: '#212121',
|
|
440
|
+
}, children: "Custom field type" }), _jsx(SegmentedControl, { theme: state.theme, value: customFieldType, onChange: (e) => {
|
|
441
|
+
setCustomFieldType(e);
|
|
442
|
+
}, left: 'EAV', right: 'JSON' }), _jsx("br", {}), _jsx("h3", { style: {
|
|
443
|
+
fontWeight: '600',
|
|
444
|
+
fontSize: '14px',
|
|
445
|
+
marginBottom: '6px',
|
|
446
|
+
color: '#212121',
|
|
447
|
+
}, children: "Custom field query" }), _jsx("h3", { style: {
|
|
448
|
+
fontWeight: '400',
|
|
449
|
+
fontSize: '14px',
|
|
450
|
+
marginBottom: '20px',
|
|
451
|
+
color: '#212121',
|
|
452
|
+
}, children: customFieldType === 'eav'
|
|
453
|
+
? `A table of custom fields. It must have these columns: ref_table, ref_id, field, value, type, ${state.client.customerFieldName.replaceAll('"', '')}.`
|
|
454
|
+
: `A table of custom fields. It must have these columns: ref_table, ref_column, field, ${state.client.customerFieldName.replaceAll('"', '')}.` }), _jsx(SqlTextEditor, { value: customFieldQuery, setValue: (e) => {
|
|
455
|
+
setCustomFieldQuery(e);
|
|
456
|
+
}, setEditorMounted: () => { }, containerStyle: {
|
|
457
|
+
width: 800,
|
|
458
|
+
}, previousProvider: null, height: '150px', schema: [] }), _jsx("br", {}), _jsx(MemoizedButton, { label: 'Run query', onClick: async () => {
|
|
459
|
+
if (/limit\s+\d+\s*;?\s*$/i.test(customFieldQuery)) {
|
|
460
|
+
setErrorInfo({
|
|
461
|
+
show: true,
|
|
462
|
+
message: 'Error: Please remove the limit at the end of your query.',
|
|
463
|
+
});
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
setErrorInfo({ show: false, message: '' });
|
|
467
|
+
setRunQueryButtonLoading(true);
|
|
468
|
+
const getSqlResults = await getSqlViewData(state.client._id, customFieldQuery, state.client.databaseType, state.queryEndpoint);
|
|
469
|
+
if (!getSqlResults.success) {
|
|
470
|
+
setErrorInfo({
|
|
471
|
+
show: true,
|
|
472
|
+
message: getSqlResults.error,
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
setErrorInfo({ show: false, message: '' });
|
|
477
|
+
setTableData(getSqlResults);
|
|
478
|
+
}
|
|
479
|
+
setRunQueryButtonLoading(false);
|
|
480
|
+
} }), _jsx("br", {}), runQueryButtonLoading && (_jsx("div", { style: {
|
|
481
|
+
height: '250px',
|
|
482
|
+
width: '100%',
|
|
483
|
+
display: 'flex',
|
|
484
|
+
justifyContent: 'center',
|
|
485
|
+
alignItems: 'center',
|
|
486
|
+
}, children: _jsx(LoadingSpinner, {}) })), !errorInfo.show && tableData && !runQueryButtonLoading && (_jsx(Table, { rows: tableData.rows, columns: tableData.fields, containerStyle: {
|
|
487
|
+
height: '250px',
|
|
488
|
+
maxWidth: '800px',
|
|
489
|
+
paddingTop: '20px',
|
|
490
|
+
}, hideCSVDownloadButton: true })), errorInfo.show && (_jsx("div", { style: {
|
|
491
|
+
fontSize: 15,
|
|
492
|
+
fontWeight: '400',
|
|
493
|
+
paddingTop: '20px',
|
|
494
|
+
}, children: _jsx("div", { style: {
|
|
495
|
+
padding: 30,
|
|
496
|
+
background: 'rgba(0,0,0,0.02)',
|
|
497
|
+
display: 'inline-block',
|
|
498
|
+
flex: 0,
|
|
499
|
+
borderRadius: 6,
|
|
500
|
+
}, children: errorInfo.message }) }))] }))] })), _jsxs("div", { style: {
|
|
319
501
|
display: 'flex',
|
|
320
502
|
flexDirection: 'row',
|
|
321
503
|
alignItems: 'center',
|
|
@@ -327,6 +509,47 @@ function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, closeE
|
|
|
327
509
|
alert('Please enter a name');
|
|
328
510
|
return;
|
|
329
511
|
}
|
|
330
|
-
|
|
331
|
-
|
|
512
|
+
if (useCustomField) {
|
|
513
|
+
const fields = tableData?.fields.map((field) => field.field);
|
|
514
|
+
const missingFields = [];
|
|
515
|
+
if (!fields) {
|
|
516
|
+
alert('Custom field query is missing required columns');
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
if (customFieldType === 'eav') {
|
|
520
|
+
// make sure the tableData has the required columns
|
|
521
|
+
[
|
|
522
|
+
'ref_table',
|
|
523
|
+
'ref_id',
|
|
524
|
+
'field',
|
|
525
|
+
'value',
|
|
526
|
+
'type',
|
|
527
|
+
state.client.customerFieldName.replaceAll('"', ''),
|
|
528
|
+
].forEach((requiredField) => {
|
|
529
|
+
if (!fields.includes(requiredField)) {
|
|
530
|
+
missingFields.push(requiredField);
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
[
|
|
536
|
+
'ref_table',
|
|
537
|
+
'field',
|
|
538
|
+
'ref_column',
|
|
539
|
+
state.client.customerFieldName.replaceAll('"', ''),
|
|
540
|
+
].forEach((requiredField) => {
|
|
541
|
+
if (!fields.includes(requiredField)) {
|
|
542
|
+
missingFields.push(requiredField);
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
if (missingFields.length > 0) {
|
|
547
|
+
alert(`Custom field query is missing required columns: ${missingFields.join(', ')}`);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
submit(viewName ? 'edit' : 'add', query, name, id, undefined, useCustomField
|
|
552
|
+
? { type: customFieldType, query: customFieldQuery }
|
|
553
|
+
: undefined);
|
|
554
|
+
}, label: viewName ? 'Save changes' : 'Create view', isLoading: isLoading })] })] }) }));
|
|
332
555
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"astProcessing.d.ts","sourceRoot":"","sources":["../../../src/utils/astProcessing.ts"],"names":[],"mappings":"AAAA,wBAAgB,kCAAkC,CAChD,qBAAqB,EAAE,MAAM,EAAE,EAC/B,UAAU,EAAE,MAAM,EAAE,EACpB,MAAM,EAAE,GAAG,EACX,GAAG,EAAE,GAAG,OAsCT"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function processJoinASTWithDuplicateColumns(duplicateColumnsNames, tableNames, schema, ast) {
|
|
2
|
+
const columns = [];
|
|
3
|
+
schema.forEach((table) => {
|
|
4
|
+
if (tableNames.includes(table.tableName)) {
|
|
5
|
+
table.columns.forEach((column) => {
|
|
6
|
+
let tableName = table.tableName;
|
|
7
|
+
if (table.tableName.includes('.')) {
|
|
8
|
+
tableName = table.tableName.split('.')[1] || table.tableName;
|
|
9
|
+
}
|
|
10
|
+
if (duplicateColumnsNames.includes(column.columnName)) {
|
|
11
|
+
columns.push({
|
|
12
|
+
type: 'expr',
|
|
13
|
+
as: `${tableName}_${column.columnName}`,
|
|
14
|
+
expr: {
|
|
15
|
+
type: 'column_ref',
|
|
16
|
+
table: tableName,
|
|
17
|
+
column: column.columnName,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
columns.push({
|
|
23
|
+
type: 'expr',
|
|
24
|
+
as: null,
|
|
25
|
+
expr: {
|
|
26
|
+
type: 'column_ref',
|
|
27
|
+
table: tableName,
|
|
28
|
+
column: column.columnName,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
ast.columns = columns;
|
|
36
|
+
return ast;
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"astProcessing.uspec.d.ts","sourceRoot":"","sources":["../../../src/utils/astProcessing.uspec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { processJoinASTWithDuplicateColumns } from "./astProcessing";
|
|
2
|
+
describe('astProcessing', () => {
|
|
3
|
+
describe('processJoinASTWithDuplicateColumns', () => {
|
|
4
|
+
it('should return a new ast object with unambiguous columns', () => {
|
|
5
|
+
const dummyAst = { where: 'dummy where' };
|
|
6
|
+
const tableNames = ['table1', 'table2'];
|
|
7
|
+
const duplicateColumns = ['amount'];
|
|
8
|
+
const schema = [
|
|
9
|
+
{
|
|
10
|
+
tableName: 'table1',
|
|
11
|
+
columns: [{ columnName: 'amount' }, { columnName: 'name' }],
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
tableName: 'table2',
|
|
15
|
+
columns: [{ columnName: 'amount' }, { columnName: 'other_name' }],
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
const resultAst = processJoinASTWithDuplicateColumns(duplicateColumns, tableNames, schema, dummyAst);
|
|
19
|
+
expect(resultAst.columns.length).toEqual(4);
|
|
20
|
+
expect(resultAst.columns[0].as).toEqual('table1_amount');
|
|
21
|
+
expect(resultAst.columns[1].as).toEqual(null);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columnProcessing.d.ts","sourceRoot":"","sources":["../../../src/utils/columnProcessing.ts"],"names":[],"mappings":"AAAA,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAsBlE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,UAa1E"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function convertFieldTypeToJSType(fieldType) {
|
|
2
|
+
switch (fieldType) {
|
|
3
|
+
case 'bool':
|
|
4
|
+
return 'bool';
|
|
5
|
+
case 'int8':
|
|
6
|
+
case 'int2':
|
|
7
|
+
case 'int4':
|
|
8
|
+
case 'float4':
|
|
9
|
+
case 'float8':
|
|
10
|
+
case 'numeric':
|
|
11
|
+
return 'number';
|
|
12
|
+
case 'date':
|
|
13
|
+
case 'time':
|
|
14
|
+
case 'timestamptz':
|
|
15
|
+
case 'timestamp':
|
|
16
|
+
return 'date';
|
|
17
|
+
case 'interval':
|
|
18
|
+
case 'varchar':
|
|
19
|
+
case 'text':
|
|
20
|
+
default:
|
|
21
|
+
return 'string';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function processColumnReference(column, databaseType) {
|
|
25
|
+
if (['postgresql', 'snowflake'].includes(databaseType.toLowerCase())) {
|
|
26
|
+
const columnParts = column.split('.');
|
|
27
|
+
if (columnParts.length > 1) {
|
|
28
|
+
return `"${columnParts[0]}"."${columnParts[1]}"`;
|
|
29
|
+
}
|
|
30
|
+
return `"${column}"`;
|
|
31
|
+
}
|
|
32
|
+
const columnParts = column.split('.');
|
|
33
|
+
if (columnParts.length > 1) {
|
|
34
|
+
return `\`${columnParts[0]}\`.\`${columnParts[1]}\``;
|
|
35
|
+
}
|
|
36
|
+
return `\`${column}\``;
|
|
37
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const editSQLView: (editName: string, editViewQuery: string, editViewId: string, state: any) => Promise<any>;
|
|
2
|
-
export declare const addSqlView: (name: string, editViewQuery: string, state: any) => Promise<any>;
|
|
1
|
+
export declare const editSQLView: (editName: string, editViewQuery: string, editViewId: string, customFieldInfo: any, state: any) => Promise<any>;
|
|
2
|
+
export declare const addSqlView: (name: string, editViewQuery: string, customFieldInfo: any, state: any) => Promise<any>;
|
|
3
3
|
export declare const deleteSQLView: (id: string, state: any) => Promise<any>;
|
|
4
4
|
//# sourceMappingURL=dataEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataEditor.d.ts","sourceRoot":"","sources":["../../../src/utils/dataEditor.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,aACZ,MAAM,iBACD,MAAM,cACT,MAAM,
|
|
1
|
+
{"version":3,"file":"dataEditor.d.ts","sourceRoot":"","sources":["../../../src/utils/dataEditor.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,aACZ,MAAM,iBACD,MAAM,cACT,MAAM,mBACD,GAAG,SACb,GAAG,iBAuDX,CAAC;AAEF,eAAO,MAAM,UAAU,SACf,MAAM,iBACG,MAAM,mBACJ,GAAG,SACb,GAAG,iBAgDX,CAAC;AAEF,eAAO,MAAM,aAAa,OAAc,MAAM,SAAS,GAAG,iBAmCzD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { QUILL_SERVER } from './constants';
|
|
2
|
-
export const editSQLView = async (editName, editViewQuery, editViewId, state) => {
|
|
2
|
+
export const editSQLView = async (editName, editViewQuery, editViewId, customFieldInfo, state) => {
|
|
3
3
|
if (!editName.length) {
|
|
4
4
|
alert('Please enter a table name.');
|
|
5
5
|
return;
|
|
@@ -24,6 +24,7 @@ export const editSQLView = async (editName, editViewQuery, editViewId, state) =>
|
|
|
24
24
|
metadata: {
|
|
25
25
|
preQueries: [editViewQuery.replace(/;/, '')],
|
|
26
26
|
name: editName,
|
|
27
|
+
customFieldInfo: customFieldInfo,
|
|
27
28
|
task: 'view',
|
|
28
29
|
id: editViewId,
|
|
29
30
|
clientId: state.client._id,
|
|
@@ -52,7 +53,7 @@ export const editSQLView = async (editName, editViewQuery, editViewId, state) =>
|
|
|
52
53
|
}
|
|
53
54
|
return await response.json();
|
|
54
55
|
};
|
|
55
|
-
export const addSqlView = async (name, editViewQuery, state) => {
|
|
56
|
+
export const addSqlView = async (name, editViewQuery, customFieldInfo, state) => {
|
|
56
57
|
if (!name.length) {
|
|
57
58
|
alert('Please enter a table name.');
|
|
58
59
|
return;
|
|
@@ -72,6 +73,7 @@ export const addSqlView = async (name, editViewQuery, state) => {
|
|
|
72
73
|
body: JSON.stringify({
|
|
73
74
|
metadata: {
|
|
74
75
|
preQueries: [editViewQuery.replace(/;/, '')],
|
|
76
|
+
customFieldInfo: customFieldInfo,
|
|
75
77
|
name: name,
|
|
76
78
|
task: 'view',
|
|
77
79
|
clientId: state.client._id,
|
|
@@ -29,7 +29,6 @@ interface SnowflakeConnection extends DatabaseConnection {
|
|
|
29
29
|
port: string;
|
|
30
30
|
}
|
|
31
31
|
interface BigQueryConnection extends DatabaseConnection {
|
|
32
|
-
companyTag: string;
|
|
33
32
|
jsonString: string;
|
|
34
33
|
}
|
|
35
34
|
export type ConnectionType = DatabaseConnection | PostgresConnection | MySQLConnection | SnowflakeConnection | BigQueryConnection;
|