Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Synchronize TableWidget row selection #1067

Merged

Conversation

AndresOrtegaGuerrero
Copy link
Member

@AndresOrtegaGuerrero AndresOrtegaGuerrero commented Jan 8, 2025

This PR addresses the issue of inconsistent row selection states in the table , in particular when the widget clear a selection in the table , but if you click the table it might retain extra information of the selection.

An updateSelection function is included to synchronize the selectedIndices array in JavaScript with the selected_rows list from Python

Old

Screen.Recording.2025-01-08.at.16.07.44.mov

New

Screen.Recording.2025-01-08.at.16.05.38.mov

@AndresOrtegaGuerrero AndresOrtegaGuerrero marked this pull request as draft January 8, 2025 15:01
@AndresOrtegaGuerrero AndresOrtegaGuerrero marked this pull request as ready for review January 8, 2025 15:05
Copy link

codecov bot commented Jan 8, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 67.85%. Comparing base (0bf982d) to head (d2d1700).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1067   +/-   ##
=======================================
  Coverage   67.85%   67.85%           
=======================================
  Files         112      112           
  Lines        6679     6679           
=======================================
  Hits         4532     4532           
  Misses       2147     2147           
Flag Coverage Δ
python-3.11 67.85% <ø> (ø)
python-3.9 ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Comment on lines +1238 to +1301
let domElement = document.createElement("div");
el.classList.add("custom-table");
let selectedIndices = [];

function drawTable() {
const data = model.get("data");
domElement.innerHTML = "";
let innerHTML = '<table><tr>' + data[0].map(header => `<th>${header}</th>`).join('') + '</tr>';

for (let i = 1; i < data.length; i++) {
innerHTML += '<tr>' + data[i].map(cell => `<td>${cell}</td>`).join('') + '</tr>';
}

innerHTML += "</table>";
domElement.innerHTML = innerHTML;

const rows = domElement.querySelectorAll('tr');
rows.forEach((row, index) => {
if (index > 0) {
row.addEventListener('click', () => {
const rowIndex = index - 1;
if (selectedIndices.includes(rowIndex)) {
selectedIndices = selectedIndices.filter(i => i !== rowIndex);
row.classList.remove('selected-row');
} else {
selectedIndices.push(rowIndex);
row.classList.add('selected-row');
}
model.set('selected_rows', [...selectedIndices]);
model.save_changes();
});

row.addEventListener('mouseover', () => {
if (!row.classList.contains('selected-row')) {
row.classList.add('hover-row');
}
});

row.addEventListener('mouseout', () => {
row.classList.remove('hover-row');
});
}
});
}

function updateSelection() {
const newSelection = model.get("selected_rows");
selectedIndices = [...newSelection]; // Synchronize the JavaScript state with the Python state
const rows = domElement.querySelectorAll('tr');
rows.forEach((row, index) => {
if (index > 0) {
if (selectedIndices.includes(index - 1)) {
row.classList.add('selected-row');
} else {
row.classList.remove('selected-row');
}
}
});
}

drawTable();
model.on("change:data", drawTable);
model.on("change:selected_rows", updateSelection);
el.appendChild(domElement);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand, why is it marking the entire code as a change? I can't tell what you changed 🤷🏻‍♂️ That said, from the behavior in the clip, seems like you solved it. But maybe you can say a bit what happened?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i was doing a test in a jupyter notebook , then i guess in the copy paste it moves the spaces , so the issue is that I added

function updateSelection() {
    const newSelection = model.get("selected_rows");
    selectedIndices = [...newSelection]; 
    const rows = domElement.querySelectorAll('tr');
    rows.forEach((row, index) => {
        if (index > 0) {
            if (selectedIndices.includes(index - 1)) {
                row.classList.add('selected-row');
            } else {
                row.classList.remove('selected-row');
            }
        }
    });
}

So when i assigned selected_row in python it is reflected in the JS, because before the selection was keeping the previous state

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and to listen this changes i added , so is i set to selected_rows in Python it will triggers the function updateSelection

model.on("change:selected_rows", updateSelection);

Copy link
Member

@edan-bainglass edan-bainglass left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't tell what changed 🤷🏻‍♂️

@edan-bainglass edan-bainglass self-requested a review January 8, 2025 16:23
Copy link
Member

@edan-bainglass edan-bainglass left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@AndresOrtegaGuerrero AndresOrtegaGuerrero merged commit 07593e3 into aiidalab:main Jan 8, 2025
8 checks passed
@superstar54
Copy link
Member

Hi @AndresOrtegaGuerrero and @edan-bainglass , for the calculation history page, I created a new table widget (https://github.com/superstar54/table-widget) today, it supports interactive features (editing, filtering, search), and I tried to make the table as general as possible. Will make a PR for the calculation history soon.

@AndresOrtegaGuerrero, please have a look to see if it can also be used here.

@edan-bainglass
Copy link
Member

Very nice! Performance okay?

@superstar54
Copy link
Member

Performance okay?

React, and Datagrid libraries are used, making it smooth, even for large data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants