feat: UX improvements for list handling
This commit is contained in:
@@ -25,8 +25,6 @@ const createListBtn = document.getElementById('createListBtn');
|
|||||||
const listSelectionOverlay = document.getElementById('listSelectionOverlay');
|
const listSelectionOverlay = document.getElementById('listSelectionOverlay');
|
||||||
const listSelectionBody = document.getElementById('listSelectionBody');
|
const listSelectionBody = document.getElementById('listSelectionBody');
|
||||||
const closeListSelection = document.getElementById('closeListSelection');
|
const closeListSelection = document.getElementById('closeListSelection');
|
||||||
const saveListSelection = document.getElementById('saveListSelection');
|
|
||||||
const cancelListSelection = document.getElementById('cancelListSelection');
|
|
||||||
const listFilterWrapper = document.getElementById('listFilterWrapper');
|
const listFilterWrapper = document.getElementById('listFilterWrapper');
|
||||||
const listFilterChips = document.getElementById('listFilterChips');
|
const listFilterChips = document.getElementById('listFilterChips');
|
||||||
const clearListFilters = document.getElementById('clearListFilters');
|
const clearListFilters = document.getElementById('clearListFilters');
|
||||||
@@ -717,13 +715,6 @@ function setupListsManagement() {
|
|||||||
currentLinkForListSelection = null;
|
currentLinkForListSelection = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
cancelListSelection.addEventListener('click', () => {
|
|
||||||
listSelectionOverlay.classList.remove('show');
|
|
||||||
currentLinkForListSelection = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
saveListSelection.addEventListener('click', handleSaveListSelection);
|
|
||||||
|
|
||||||
// Close on backdrop click
|
// Close on backdrop click
|
||||||
listSelectionOverlay.addEventListener('click', (e) => {
|
listSelectionOverlay.addEventListener('click', (e) => {
|
||||||
if (e.target === listSelectionOverlay) {
|
if (e.target === listSelectionOverlay) {
|
||||||
@@ -976,20 +967,27 @@ function handleAddToLists(linkId) {
|
|||||||
<span>${escapeHtml(list.name)}</span>
|
<span>${escapeHtml(list.name)}</span>
|
||||||
</label>
|
</label>
|
||||||
`).join('');
|
`).join('');
|
||||||
|
|
||||||
|
// Add event listeners to checkboxes for auto-save
|
||||||
|
listSelectionBody.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
|
||||||
|
checkbox.addEventListener('change', () => {
|
||||||
|
handleCheckboxChange(linkId);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
listSelectionOverlay.classList.add('show');
|
listSelectionOverlay.classList.add('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle save list selection
|
// Handle checkbox change (auto-save)
|
||||||
async function handleSaveListSelection() {
|
async function handleCheckboxChange(linkId) {
|
||||||
if (!currentLinkForListSelection) return;
|
if (!linkId) return;
|
||||||
|
|
||||||
const checkboxes = listSelectionBody.querySelectorAll('input[type="checkbox"]:checked');
|
const checkboxes = listSelectionBody.querySelectorAll('input[type="checkbox"]:checked');
|
||||||
const selectedListIds = Array.from(checkboxes).map(cb => cb.value);
|
const selectedListIds = Array.from(checkboxes).map(cb => cb.value);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${API_BASE}/${currentLinkForListSelection}/lists`, {
|
const response = await fetch(`${API_BASE}/${linkId}/lists`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@@ -1004,20 +1002,23 @@ async function handleSaveListSelection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update local array
|
// Update local array
|
||||||
const linkIndex = allLinks.findIndex(l => l.id === currentLinkForListSelection);
|
const linkIndex = allLinks.findIndex(l => l.id === linkId);
|
||||||
if (linkIndex !== -1) {
|
if (linkIndex !== -1) {
|
||||||
allLinks[linkIndex].listIds = selectedListIds;
|
allLinks[linkIndex].listIds = selectedListIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update display
|
// No need to refresh the display - the link is already visible
|
||||||
displayLinks(getFilteredLinks());
|
// Only update if the link's visibility might have changed due to list filters
|
||||||
|
// But since we're just assigning lists, not changing visibility, we skip the refresh
|
||||||
listSelectionOverlay.classList.remove('show');
|
|
||||||
currentLinkForListSelection = null;
|
|
||||||
showMessage('Link lists updated successfully!', 'success');
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showMessage('Failed to update link lists', 'error');
|
showMessage('Failed to update link lists', 'error');
|
||||||
console.error('Error updating link lists:', error);
|
console.error('Error updating link lists:', error);
|
||||||
|
// Revert checkbox state on error
|
||||||
|
const link = allLinks.find(l => l.id === linkId);
|
||||||
|
const linkListIds = link?.listIds || [];
|
||||||
|
listSelectionBody.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
|
||||||
|
checkbox.checked = linkListIds.includes(checkbox.value);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -188,10 +188,6 @@
|
|||||||
<div class="list-selection-body" id="listSelectionBody">
|
<div class="list-selection-body" id="listSelectionBody">
|
||||||
<!-- List checkboxes will be inserted here -->
|
<!-- List checkboxes will be inserted here -->
|
||||||
</div>
|
</div>
|
||||||
<div class="list-selection-footer">
|
|
||||||
<button id="saveListSelection" class="btn-save-lists">Save</button>
|
|
||||||
<button id="cancelListSelection" class="btn-cancel-lists">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1694,50 +1694,6 @@ body {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-selection-footer {
|
|
||||||
display: flex;
|
|
||||||
gap: 0.75rem;
|
|
||||||
padding: 1.5rem;
|
|
||||||
border-top: 1px solid var(--border);
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-save-lists,
|
|
||||||
.btn-cancel-lists {
|
|
||||||
padding: 0.75rem 1.5rem;
|
|
||||||
border-radius: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-weight: 600;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-save-lists {
|
|
||||||
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
|
|
||||||
color: white;
|
|
||||||
box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-save-lists:hover {
|
|
||||||
transform: translateY(-1px);
|
|
||||||
box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-save-lists:active {
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-cancel-lists {
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text-secondary);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-cancel-lists:hover {
|
|
||||||
background: var(--surface-light);
|
|
||||||
border-color: var(--primary-color);
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add to List Button in Link Cards */
|
/* Add to List Button in Link Cards */
|
||||||
.add-to-list-btn {
|
.add-to-list-btn {
|
||||||
@@ -1789,15 +1745,6 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-selection-footer {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-save-lists,
|
|
||||||
.btn-cancel-lists {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-item {
|
.list-item {
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user