Skip to content

Commit eeb39e7

Browse files
authored
Merge pull request #6 from opencobra/constructor_dev
add new feature: sorting table
2 parents b6da917 + fb9d815 commit eeb39e7

File tree

14 files changed

+2882
-2551
lines changed

14 files changed

+2882
-2551
lines changed

curationTool/reactions/static/reactions/Home_page.css

Lines changed: 571 additions & 597 deletions
Large diffs are not rendered by default.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
document.addEventListener('DOMContentLoaded', () => {
2+
const modal = document.getElementById('deleteFlagModal');
3+
const msg = document.getElementById('deleteFlagMessage');
4+
const closeBtn = document.getElementById('closeDeleteFlagModal');
5+
const confirmBtn = document.getElementById('confirmDeleteFlagBtn');
6+
7+
/* ---------- 1. delegated listener for every current/future flag ---------- */
8+
document.addEventListener('click', evt => {
9+
const icon = evt.target.closest('.flag-icon');
10+
if (!icon) return; // not a flag click
11+
12+
modal.dataset.flagId = icon.dataset.flagId;
13+
modal.dataset.flagName = icon.dataset.flagName;
14+
modal.dataset.reactionId = icon.dataset.reactionId;
15+
16+
msg.textContent =
17+
`Remove flag "${modal.dataset.flagName}" from this reaction?`;
18+
modal.style.display = 'block';
19+
});
20+
21+
/* ---------- 2. close modal ---------- */
22+
closeBtn.addEventListener('click', () => {
23+
modal.style.display = 'none';
24+
});
25+
26+
/* ---------- 3. confirm deletion ---------- */
27+
confirmBtn.addEventListener('click', () => {
28+
fetch('/saved_reactions/remove_flag/', {
29+
method : 'POST',
30+
headers: {
31+
'Content-Type': 'application/json',
32+
'X-CSRFToken' : csrfToken
33+
},
34+
body: JSON.stringify({
35+
user_id : userID,
36+
reaction_id: modal.dataset.reactionId,
37+
flag_id : modal.dataset.flagId
38+
})
39+
})
40+
.then(r => r.json())
41+
.then(data => {
42+
if (data.status === 'success') {
43+
location.reload(); // or update the row in place
44+
} else {
45+
alert(data.message || 'Error removing flag.');
46+
}
47+
})
48+
.catch(err => {
49+
console.error(err);
50+
alert('Something went wrong.');
51+
});
52+
53+
modal.style.display = 'none';
54+
});
55+
});

curationTool/reactions/static/reactions/js_savedreactions/flag_saved_reaction.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,29 @@ document.addEventListener('DOMContentLoaded', function() {
3333
}
3434

3535
document.getElementById('AddFlagtosavedreaction').addEventListener('click', function() {
36-
const selectedReactionIds = getSelectedReactionIds(); // Implement this function to retrieve selected reactions
36+
const selectedReactionIds = Array.from(document.querySelectorAll('.reaction-checkbox:checked'))
37+
.map(cb => cb.dataset.reactionId); // Implement this function to retrieve selected reactions
3738
const selectedFlagElement = document.querySelector('.dropdown-trigger');
3839
var selectedFlagName = selectedFlagElement.textContent.trim();
3940
const flagIcon = selectedFlagElement.querySelector('i');
40-
var selectedFlagColor = rgbToHex(flagIcon.style.color);
41+
let selectedFlagColor = null;
42+
43+
if (flagIcon && flagIcon.style && flagIcon.style.color) {
44+
selectedFlagColor = rgbToHex(flagIcon.style.color);
45+
}
46+
47+
function showAlert(message) {
48+
document.getElementById('alertMessage').textContent = message;
49+
document.getElementById('alertModal').style.display = "block";
50+
}
4151

4252
if (!selectedReactionIds.length) {
43-
console.error('No reactions selected');
53+
showAlert('Please select at least one reaction.');
4454
return;
4555
}
4656

4757
if (selectedFlagName === 'None' || !selectedFlagColor) {
48-
console.error('No flag selected or flag color missing');
58+
showAlert('Please choose a valid flag before applying.');
4959
return;
5060
}
5161

@@ -70,12 +80,20 @@ document.addEventListener('DOMContentLoaded', function() {
7080
console.log('Flag added to selected reactions successfully');
7181
location.reload();
7282
} else {
73-
console.error(data.message);
83+
alert(data.message || 'An error occurred while saving flags.');
7484
}
7585
})
76-
.catch(error => console.error('Error:', error));
86+
.catch(error => {
87+
console.error('Error:', error);
88+
alert('Something went wrong. Please try again later.');
89+
});
90+
});
91+
92+
document.querySelector('.close-alert-btn').addEventListener('click', function() {
93+
document.getElementById('alertModal').style.display = "none";
7794
});
7895

96+
7997
function getSelectedReactionIds() {
8098
let selected = [];
8199
selected = checkedReactions;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
document.addEventListener('DOMContentLoaded', function () {
2+
const table = document.getElementById('reactionList');
3+
const tbody = table.querySelector('tbody');
4+
const originalRows = Array.from(tbody.querySelectorAll('tr')); // Store initial order
5+
6+
const getValue = (row, key) => {
7+
switch (key) {
8+
case 'flag':
9+
const icon = row.querySelector('.flag-icon');
10+
return icon?.getAttribute('data-flag-name')?.toLowerCase() || 'zzz'; // 'zzz' pushes nulls to bottom
11+
case 'subsystem':
12+
return row.children[3]?.textContent.trim().toLowerCase() || 'zzz';
13+
case 'substrates':
14+
return row.children[4]?.textContent.trim().toLowerCase() || 'zzz';
15+
case 'products':
16+
return row.children[6]?.textContent.trim().toLowerCase() || 'zzz';
17+
default:
18+
return '';
19+
}
20+
};
21+
22+
document.getElementById('sortBy').addEventListener('change', () => {
23+
const sortKey = document.getElementById('sortBy').value;
24+
25+
// Reset to original order if no sort selected
26+
if (!sortKey) {
27+
tbody.innerHTML = '';
28+
originalRows.forEach((row) => tbody.appendChild(row.cloneNode(true)));
29+
return;
30+
}
31+
32+
const sortedRows = [...tbody.querySelectorAll('tr')].sort((a, b) => {
33+
const aVal = getValue(a, sortKey);
34+
const bVal = getValue(b, sortKey);
35+
return aVal.localeCompare(bVal);
36+
});
37+
38+
tbody.innerHTML = '';
39+
40+
sortedRows.forEach((row) => tbody.appendChild(row));
41+
42+
rebindCheckboxListeners();
43+
});
44+
});

0 commit comments

Comments
 (0)