Add button to sheet and shift selector
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
|
||||
let sortColumn = $state<keyof RowData | null>(null);
|
||||
let sortDirection = $state<'asc' | 'desc'>('asc');
|
||||
let lastCheckedId: string | null = $state(null);
|
||||
|
||||
const ROW_LIMIT = 200;
|
||||
|
||||
@@ -85,20 +86,52 @@
|
||||
} finally {
|
||||
isLoading = false;
|
||||
}
|
||||
} // Run on component mount
|
||||
}
|
||||
|
||||
function handleRowClick(event: MouseEvent, clickedId: string) {
|
||||
const clickedRow = rows.find((r) => r.id === clickedId);
|
||||
if (!clickedRow || !clickedRow._valid) return;
|
||||
|
||||
// Handle shift-clicking for range selection
|
||||
if (event.shiftKey && lastCheckedId) {
|
||||
const lastIndex = displayData.findIndex((r) => r.id === lastCheckedId);
|
||||
const currentIndex = displayData.findIndex((r) => r.id === clickedId);
|
||||
|
||||
if (lastIndex !== -1 && currentIndex !== -1) {
|
||||
const start = Math.min(lastIndex, currentIndex);
|
||||
const end = Math.max(lastIndex, currentIndex);
|
||||
const isChecked = !clickedRow._checked; // The state to apply to the range
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
const rowToSelect = displayData[i];
|
||||
if (rowToSelect && rowToSelect._valid) {
|
||||
// Prevent checking more than the limit
|
||||
if (isChecked && selectedCount >= ROW_LIMIT && !rowToSelect._checked) {
|
||||
continue;
|
||||
}
|
||||
rowToSelect._checked = isChecked;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Normal click, just toggle the state
|
||||
if (!clickedRow._checked && selectedCount >= ROW_LIMIT) {
|
||||
// Do not allow checking more than the limit
|
||||
} else {
|
||||
clickedRow._checked = !clickedRow._checked;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the last checked ID for the next shift-click
|
||||
lastCheckedId = clickedId;
|
||||
}
|
||||
|
||||
// Run on component mount
|
||||
onMount(() => {
|
||||
ensureToken();
|
||||
fetchAndProcessData();
|
||||
});
|
||||
|
||||
// Function to toggle a single row's checked state
|
||||
function toggleRow(id: string) {
|
||||
const row = rows.find((r) => r.id === id);
|
||||
if (row && row._valid) {
|
||||
row._checked = !row._checked;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to toggle select-all: selects first 200 eligible items in current view
|
||||
function toggleSelectAll(event: Event) {
|
||||
const target = event.target as HTMLInputElement;
|
||||
@@ -169,28 +202,33 @@
|
||||
<div>
|
||||
<h2 class="mb-2 text-xl font-semibold text-gray-900">Filter and Select Rows</h2>
|
||||
<p class="text-sm text-gray-700">
|
||||
Review your data and select which rows to include. Select a batch of max 200 items by using the top checkbox.
|
||||
Review your data and select which rows to include. Select a batch of max 200 items by using
|
||||
the top checkbox.
|
||||
</p>
|
||||
<p class="text-sm text-gray-700">
|
||||
<p class="mt-1 text-sm text-gray-700">
|
||||
Tip: Hold <kbd
|
||||
class="rounded-md border border-gray-400 bg-gray-200 px-1.5 py-0.5 text-xs font-semibold"
|
||||
>Shift</kbd
|
||||
> and click two checkboxes to select a range of rows.
|
||||
</p>
|
||||
<p class="mt-1 text-sm text-gray-700">
|
||||
Already printed or invalid data is marked in the status column.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-2">
|
||||
{#if $selectedSheet?.id}
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Need to make changes?
|
||||
<a
|
||||
href={`https://docs.google.com/spreadsheets/d/${$selectedSheet.id}/edit`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-blue-600 underline hover:text-blue-800"
|
||||
class="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
|
||||
>
|
||||
Open the spreadsheet
|
||||
Open Sheet
|
||||
</a>
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
<button
|
||||
onclick={fetchAndProcessData}
|
||||
class="inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:cursor-wait disabled:opacity-50"
|
||||
class="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:cursor-wait disabled:opacity-50"
|
||||
disabled={isLoading}
|
||||
>
|
||||
{#if isLoading}
|
||||
@@ -220,6 +258,7 @@
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if isLoading}
|
||||
<div class="py-12 text-center">
|
||||
@@ -313,7 +352,7 @@
|
||||
class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 disabled:cursor-not-allowed disabled:bg-gray-200"
|
||||
checked={row._checked}
|
||||
disabled={!row._valid || (selectedCount >= ROW_LIMIT && !row._checked)}
|
||||
onchange={() => toggleRow(row.id)}
|
||||
onclick={(e) => handleRowClick(e, row.id)}
|
||||
/>
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-4 py-3 text-sm">{row._rowIndex}</td>
|
||||
|
||||
Reference in New Issue
Block a user