diff --git a/frontend/src/Editor/Box.jsx b/frontend/src/Editor/Box.jsx
index c893e8aecb..16e67d4a07 100644
--- a/frontend/src/Editor/Box.jsx
+++ b/frontend/src/Editor/Box.jsx
@@ -309,6 +309,10 @@ export const Box = function Box({
dataQueries={dataQueries}
variablesExposedForPreview={variablesExposedForPreview}
exposeToCodeHinter={exposeToCodeHinter}
+ setProperty={(property, value) => {
+ paramUpdated(id, property, { value });
+ }}
+ mode={mode}
>
) : (
diff --git a/frontend/src/Editor/Components/Table/Table.jsx b/frontend/src/Editor/Components/Table/Table.jsx
index 79ea902cdf..9b69d93a70 100644
--- a/frontend/src/Editor/Components/Table/Table.jsx
+++ b/frontend/src/Editor/Components/Table/Table.jsx
@@ -25,6 +25,7 @@ import { reducer, reducerActions, initialState } from './reducer';
import customFilter from './custom-filter';
import generateColumnsData from './columns';
import generateActionsData from './columns/actions';
+import autogenerateColumns from './columns/autogenerateColumns';
import IndeterminateCheckbox from './IndeterminateCheckbox';
import { useTranslation } from 'react-i18next';
import * as XLSX from 'xlsx/xlsx.mjs';
@@ -52,6 +53,8 @@ export function Table({
properties,
variablesExposedForPreview,
exposeToCodeHinter,
+ setProperty,
+ mode,
exposedVariables,
}) {
const {
@@ -214,7 +217,6 @@ export function Table({
if (currentState) {
tableData = resolveReferences(component.definition.properties.data.value, currentState, []);
if (!Array.isArray(tableData)) tableData = [];
- console.log('resolved param', tableData);
}
tableData = tableData || [];
@@ -286,6 +288,17 @@ export function Table({
]
);
+ useEffect(() => {
+ if (tableData.length != 0 && component.definition.properties.autogenerateColumns.value && mode === 'edit') {
+ autogenerateColumns(
+ tableData,
+ component.definition.properties.columns.value,
+ component.definition.properties?.columnDeletionHistory?.value ?? [],
+ setProperty
+ );
+ }
+ }, [JSON.stringify(tableData)]);
+
const computedStyles = {
// width: `${width}px`,
};
diff --git a/frontend/src/Editor/Components/Table/columns/autogenerateColumns.js b/frontend/src/Editor/Components/Table/columns/autogenerateColumns.js
new file mode 100644
index 0000000000..f000598452
--- /dev/null
+++ b/frontend/src/Editor/Components/Table/columns/autogenerateColumns.js
@@ -0,0 +1,49 @@
+import _ from 'lodash';
+import { v4 as uuidv4 } from 'uuid';
+
+export default function autogenerateColumns(tableData, existingColumns, columnDeletionHistory, setProperty) {
+ const firstRow = tableData?.[0] ?? {};
+
+ const keysOfTableData = Object.keys(firstRow);
+
+ const keysOfExistingColumns = existingColumns.map((column) => column.key || column.name);
+
+ const keysFromWhichNewColumnsShouldBeGenerated = _.difference(keysOfTableData, [
+ ...keysOfExistingColumns,
+ ...columnDeletionHistory,
+ ]);
+
+ const keysAndDataTypesToGenerateNewColumns = keysFromWhichNewColumnsShouldBeGenerated?.map((key) => [
+ key,
+ typeof firstRow[key],
+ ]);
+
+ const keysOfExistingColumnsThatNeedToPersist = existingColumns
+ .filter((column) => !column.autogenerated || keysOfTableData.includes(column.key || column.name))
+ .map((column) => column.key || column.name);
+
+ const generatedColumns = keysAndDataTypesToGenerateNewColumns.map(([key, dataType]) => ({
+ id: uuidv4(),
+ name: key,
+ key: key,
+ columnType: convertDataTypeToColumnType(dataType),
+ autogenerated: true,
+ }));
+
+ const finalKeys = [...keysFromWhichNewColumnsShouldBeGenerated, ...keysOfExistingColumnsThatNeedToPersist];
+ const finalColumns = [...existingColumns, ...generatedColumns].filter((column) =>
+ finalKeys.includes(column.key || column.name)
+ );
+
+ setTimeout(() => setProperty('columns', finalColumns), 10);
+}
+
+const dataTypeToColumnTypeMapping = {
+ string: 'string',
+ number: 'number',
+};
+
+const convertDataTypeToColumnType = (dataType) => {
+ if (Object.keys(dataTypeToColumnTypeMapping).includes(dataType)) return dataTypeToColumnTypeMapping[dataType];
+ else return 'default';
+};
diff --git a/frontend/src/Editor/Editor.jsx b/frontend/src/Editor/Editor.jsx
index b451fd022a..7716c699c7 100644
--- a/frontend/src/Editor/Editor.jsx
+++ b/frontend/src/Editor/Editor.jsx
@@ -62,6 +62,7 @@ import { EditorContextWrapper } from './Context/EditorContextWrapper';
// eslint-disable-next-line import/no-unresolved
import Selecto from 'react-selecto';
import { withTranslation } from 'react-i18next';
+import { v4 as uuid } from 'uuid';
setAutoFreeze(false);
enablePatches();
@@ -551,7 +552,7 @@ class EditorComponent extends React.Component {
},
this.handleAddPatch
);
- this.setState({ isSaving: true, appDefinition: newDefinition }, () => {
+ this.setState({ isSaving: true, appDefinition: newDefinition, appDefinitionLocalVersion: uuid() }, () => {
if (!opts.skipAutoSave) this.autoSave();
});
computeComponentState(this, newDefinition.components);
@@ -1666,6 +1667,7 @@ class EditorComponent extends React.Component {
apps={apps}
darkMode={this.props.darkMode}
handleEditorEscapeKeyPress={this.handleEditorEscapeKeyPress}
+ appDefinitionLocalVersion={this.state.appDefinitionLocalVersion}
>
) : (
diff --git a/frontend/src/Editor/Inspector/Components/Table.jsx b/frontend/src/Editor/Inspector/Components/Table.jsx
index 1b1413e1dd..9f91949434 100644
--- a/frontend/src/Editor/Inspector/Components/Table.jsx
+++ b/frontend/src/Editor/Inspector/Components/Table.jsx
@@ -684,16 +684,7 @@ class TableComponent extends React.Component {
onColumnItemChange = (index, item, value) => {
const columns = this.props.component.component.definition.properties.columns;
const column = columns.value[index];
- if (item === 'name') {
- const columnSizes = this.props.component.component.definition.properties.columnSizes;
- if (columnSizes) {
- const newColumnSizes = JSON.parse(JSON.stringify(columnSizes));
- if (newColumnSizes[column.name]) {
- newColumnSizes[value] = newColumnSizes[column.name];
- this.props.paramUpdated({ name: 'columnSizes' }, null, newColumnSizes, 'properties');
- }
- }
- }
+
column[item] = value;
const newColumns = columns.value;
newColumns[index] = column;
@@ -703,8 +694,16 @@ class TableComponent extends React.Component {
removeColumn = (index) => {
const columns = this.props.component.component.definition.properties.columns;
const newValue = columns.value;
- newValue.splice(index, 1);
+ const removedColumns = newValue.splice(index, 1);
this.props.paramUpdated({ name: 'columns' }, 'value', newValue, 'properties');
+
+ const existingcolumnDeletionHistory =
+ this.props.component.component.definition.properties.columnDeletionHistory?.value ?? [];
+ const newcolumnDeletionHistory = [
+ ...existingcolumnDeletionHistory,
+ ...removedColumns.map((column) => column.key || column.name),
+ ];
+ this.props.paramUpdated({ name: 'columnDeletionHistory' }, 'value', newcolumnDeletionHistory, 'properties');
};
getPopoverFieldSource = (column, field) =>
diff --git a/frontend/src/Editor/Inspector/Inspector.jsx b/frontend/src/Editor/Inspector/Inspector.jsx
index 161ac02784..6cc1d0c33f 100644
--- a/frontend/src/Editor/Inspector/Inspector.jsx
+++ b/frontend/src/Editor/Inspector/Inspector.jsx
@@ -29,6 +29,7 @@ export const Inspector = ({
switchSidebarTab,
removeComponent,
handleEditorEscapeKeyPress,
+ appDefinitionLocalVersion,
}) => {
const component = {
id: selectedComponentId,
@@ -389,7 +390,7 @@ export const Inspector = ({
};
return (
-