Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ const StyledButtonWrapper = styled.span`

type CollectionItem = { id: string | number; [key: string]: any };

function createCollectionArray(collection: Record<PropertyKey, any>) {
return Object.keys(collection).map(k => collection[k] as CollectionItem);
}

function createKeyedCollection(arr: Array<object>) {
const collectionArray = arr.map(
Expand Down Expand Up @@ -109,6 +106,7 @@ export default class CRUDCollection extends PureComponent<
const { collection, collectionArray } = createKeyedCollection(
this.props.collection,
);

this.setState(prevState => ({
collection,
collectionArray,
Expand All @@ -117,7 +115,7 @@ export default class CRUDCollection extends PureComponent<
}
}

onCellChange(id: number, col: string, val: boolean) {
onCellChange(id: number, col: string, val: any) {
this.setState(prevState => {
const updatedCollection = {
...prevState.collection,
Expand Down Expand Up @@ -197,11 +195,21 @@ export default class CRUDCollection extends PureComponent<
}

changeCollection(collection: any) {
const newCollectionArray = createCollectionArray(collection);
this.setState({ collection, collectionArray: newCollectionArray });
// Preserve existing order instead of recreating from Object.keys()
// Map existing items to their updated versions from the collection
const newCollectionArray = this.state.collectionArray
.map(existingItem => collection[existingItem.id] || existingItem)
.filter(item => collection[item.id]); // Remove deleted items

// Add any new items that weren't in the existing array
const existingIds = new Set(this.state.collectionArray.map(item => item.id));
const newItems = Object.values(collection).filter((item: any) => !existingIds.has(item.id));
const finalCollectionArray = [...newCollectionArray, ...newItems];

This comment was marked as resolved.


this.setState({ collection, collectionArray: finalCollectionArray });

if (this.props.onChange) {
this.props.onChange(newCollectionArray);
this.props.onChange(finalCollectionArray);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ function ColumnCollectionTable({
label={t('SQL expression')}
control={
<TextAreaControl
language="markdown"
language="sql"
offerEditInModal={false}
resize="vertical"
/>
Expand Down Expand Up @@ -691,11 +691,13 @@ class DatasourceEditor extends PureComponent {
const { datasourceType, datasource } = this.state;
const sql =
datasourceType === DATASOURCE_TYPES.physical.key ? '' : datasource.sql;

const newDatasource = {
...this.state.datasource,
sql,
columns: [...this.state.databaseColumns, ...this.state.calculatedColumns],
};

this.props.onChange(newDatasource, this.state.errors);
}

Expand Down Expand Up @@ -1704,6 +1706,7 @@ class DatasourceEditor extends PureComponent {
minLines={5}
textAreaStyles={{ minWidth: '200px', maxWidth: '450px' }}
resize="both"
debounceDelay={300}
/>
),
description: (v, onChange, label) => (
Expand Down Expand Up @@ -1888,6 +1891,55 @@ class DatasourceEditor extends PureComponent {
);
}

componentDidUpdate(prevProps) {
// Preserve calculated columns order when props change to prevent jumping
if (this.props.datasource !== prevProps.datasource) {
const newCalculatedColumns = this.props.datasource.columns.filter(col => !!col.expression);
const currentCalculatedColumns = this.state.calculatedColumns;

// Check if this is just an update to existing calculated columns (not addition/removal)
if (newCalculatedColumns.length === currentCalculatedColumns.length) {
// Create a map of current calculated columns by their identifier
const currentMap = new Map();
currentCalculatedColumns.forEach((col, index) => {
const id = col.id || col.column_name;
currentMap.set(id, { ...col, originalIndex: index });
});

This comment was marked as resolved.


// Try to preserve the order by matching with existing calculated columns
const orderedCalculatedColumns = [];
const usedIds = new Set();

// First, add existing columns in their current order
currentCalculatedColumns.forEach(currentCol => {
const id = currentCol.id || currentCol.column_name;
const updatedCol = newCalculatedColumns.find(newCol =>
(newCol.id || newCol.column_name) === id
);
if (updatedCol) {
orderedCalculatedColumns.push(updatedCol);
usedIds.add(id);
}
});

// Then add any new columns that weren't in the current list
newCalculatedColumns.forEach(newCol => {
const id = newCol.id || newCol.column_name;
if (!usedIds.has(id)) {
orderedCalculatedColumns.push(newCol);
}
});


// Update state with preserved order
this.setState({
calculatedColumns: orderedCalculatedColumns,
databaseColumns: this.props.datasource.columns.filter(col => !col.expression),
});
}
}
}

componentDidMount() {
Mousetrap.bind('ctrl+shift+f', e => {
e.preventDefault();
Expand Down
Loading