Replace bulk select button with hover checkboxes, remove board background override
- Cards now show a checkbox on hover (top-right) for bulk selection, removing the need for a separate "Select" toggle button - Removed BoardBackgroundPicker from board header since per-board backgrounds were overriding tenant branding - Removed inline background style from board area so branding page backgrounds apply correctly Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,6 @@
|
||||
import CardModal from '$lib/components/CardModal.svelte';
|
||||
import ActivityFeed from '$lib/components/ActivityFeed.svelte';
|
||||
import BoardFilters from '$lib/components/BoardFilters.svelte';
|
||||
import BoardBackgroundPicker from '$lib/components/BoardBackgroundPicker.svelte';
|
||||
import BulkToolbar from '$lib/components/BulkToolbar.svelte';
|
||||
import ColumnSortMenu from '$lib/components/ColumnSortMenu.svelte';
|
||||
import Avatar from '$lib/components/Avatar.svelte';
|
||||
@@ -38,8 +37,8 @@
|
||||
let showArchivedCards = $state(false);
|
||||
let archivedCards = $state<any[]>([]);
|
||||
let activeFilters = $state<FilterState>({ labelIds: [], assigneeIds: [], due: null });
|
||||
let selectMode = $state(false);
|
||||
let selectedCardIds = $state(new Set<string>());
|
||||
let selectMode = $derived(selectedCardIds.size > 0);
|
||||
let columnSorts = $state<Record<string, string | null>>({});
|
||||
|
||||
const flipDurationMs = 200;
|
||||
@@ -488,21 +487,6 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if data.canEdit}
|
||||
<button
|
||||
onclick={() => { selectMode = !selectMode; if (!selectMode) selectedCardIds = new Set(); }}
|
||||
class="rounded px-2 py-1 text-sm text-gray-500 hover:bg-gray-200 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 transition flex items-center gap-1"
|
||||
class:bg-gray-200={selectMode}
|
||||
title="Select cards for bulk actions"
|
||||
>
|
||||
<svg class="w-4 h-4" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Select
|
||||
</button>
|
||||
<BoardBackgroundPicker boardId={data.board.id} currentBackground={data.board.background || null} />
|
||||
{/if}
|
||||
|
||||
<button
|
||||
onclick={() => toggleArchivedCards()}
|
||||
class="ml-auto rounded px-2 py-1 text-sm text-gray-500 hover:bg-gray-200 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 transition flex items-center gap-1"
|
||||
@@ -554,7 +538,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Main area: columns + optional activity sidebar -->
|
||||
<div class="flex-1 flex overflow-hidden" style="{data.board.background ? `background: ${data.board.background}; background-size: cover; background-position: center;` : ''}">
|
||||
<div class="flex-1 flex overflow-hidden">
|
||||
<!-- Columns container -->
|
||||
<div class="flex-1 overflow-x-auto p-4">
|
||||
<div
|
||||
@@ -644,8 +628,8 @@
|
||||
{#each visibleCards as card (card.id)}
|
||||
{@const progress = getChecklistProgress(card)}
|
||||
{@const dueUrgency = getDueUrgency(card.dueDate)}
|
||||
<button
|
||||
class="w-full text-left mb-2 p-3 shadow-sm hover:shadow-md transition cursor-pointer {selectMode && selectedCardIds.has(card.id) ? 'ring-2 ring-[var(--color-primary)]' : ''}"
|
||||
<div
|
||||
class="group/card relative w-full text-left mb-2 p-3 shadow-sm hover:shadow-md transition cursor-pointer {selectedCardIds.has(card.id) ? 'ring-2 ring-[var(--color-primary)]' : ''}"
|
||||
style="background: var(--color-card-bg); border: 1px solid var(--color-card-border); color: var(--color-card-text); border-radius: var(--color-card-radius); backdrop-filter: var(--card-backdrop-blur, none);"
|
||||
animate:flip={{ duration: flipDurationMs }}
|
||||
onclick={() => {
|
||||
@@ -658,7 +642,32 @@
|
||||
selectedCard = card;
|
||||
}
|
||||
}}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); selectedCard = card; } }}
|
||||
>
|
||||
{#if data.canEdit}
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div
|
||||
class="absolute top-1.5 right-1.5 z-10 {selectedCardIds.has(card.id) ? 'opacity-100' : 'opacity-0 group-hover/card:opacity-100'} transition-opacity"
|
||||
onclick={(e) => {
|
||||
e.stopPropagation();
|
||||
const next = new Set(selectedCardIds);
|
||||
if (next.has(card.id)) next.delete(card.id);
|
||||
else next.add(card.id);
|
||||
selectedCardIds = next;
|
||||
}}
|
||||
>
|
||||
<div class="w-5 h-5 rounded border-2 flex items-center justify-center cursor-pointer {selectedCardIds.has(card.id) ? 'bg-[var(--color-primary)] border-[var(--color-primary)]' : 'border-gray-300 dark:border-gray-500 bg-white dark:bg-gray-700 hover:border-[var(--color-primary)]'} transition">
|
||||
{#if selectedCardIds.has(card.id)}
|
||||
<svg class="w-3 h-3 text-white" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if card.labels && card.labels.length > 0}
|
||||
<div class="flex flex-wrap gap-1 mb-1.5">
|
||||
{#each card.labels as label}
|
||||
@@ -722,7 +731,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -863,13 +872,10 @@
|
||||
{selectedCardIds}
|
||||
{columns}
|
||||
onaction={() => {
|
||||
selectMode = false;
|
||||
selectedCardIds = new Set();
|
||||
// Reload page data
|
||||
window.location.reload();
|
||||
}}
|
||||
oncancel={() => {
|
||||
selectMode = false;
|
||||
selectedCardIds = new Set();
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user