From 6a52508f5464a7869e422560f6f5ee0a77f53382 Mon Sep 17 00:00:00 2001 From: Tyler Holland Date: Fri, 27 Feb 2026 22:42:04 -0800 Subject: [PATCH 1/3] fix: add approval filter to automerge-label caller workflow Added if condition so the reusable workflow is only called on TytaniumDev's approvals, not every review submission. Removed redundant top-level permissions (reusable workflow declares its own). Co-Authored-By: Claude Opus 4.6 --- .github/workflows/automerge-label.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/automerge-label.yml b/.github/workflows/automerge-label.yml index c69999b..a5ab835 100644 --- a/.github/workflows/automerge-label.yml +++ b/.github/workflows/automerge-label.yml @@ -4,11 +4,9 @@ on: pull_request_review: types: [submitted] -permissions: - contents: read - pull-requests: write - issues: write - jobs: add-label: + if: >- + github.event.review.state == 'approved' && + github.event.review.user.login == 'TytaniumDev' uses: TytaniumDev/.github/.github/workflows/automerge-label.yml@main From a961a737923d97e418bc52c3d93e631efda7d6a9 Mon Sep 17 00:00:00 2001 From: Tyler Holland Date: Fri, 27 Feb 2026 22:45:07 -0800 Subject: [PATCH 2/3] feat(ui): add loading spinners to async buttons Rebase spinner changes onto current main (post-PR #90 Firestore migration). Adds a reusable Spinner component with size variants and integrates it into async action buttons (Run Again, Cancel Job, Delete Job, bulk delete) and the Browse page loading state. Removes .jules/ metadata file. Co-Authored-By: Claude Opus 4.6 --- .jules/palette.md | 3 -- frontend/src/components/Spinner.test.tsx | 25 ++++++++++++++++ frontend/src/components/Spinner.tsx | 36 ++++++++++++++++++++++++ frontend/src/pages/Browse.tsx | 7 +++-- frontend/src/pages/JobStatus.tsx | 13 ++++++--- 5 files changed, 75 insertions(+), 9 deletions(-) delete mode 100644 .jules/palette.md create mode 100644 frontend/src/components/Spinner.test.tsx create mode 100644 frontend/src/components/Spinner.tsx diff --git a/.jules/palette.md b/.jules/palette.md deleted file mode 100644 index 0caaab8..0000000 --- a/.jules/palette.md +++ /dev/null @@ -1,3 +0,0 @@ -## 2024-05-22 - Interactive Divs Pattern -**Learning:** The application frequently uses `div` elements with `onClick` handlers for selection lists (like deck selection), making them inaccessible to keyboard and screen reader users. -**Action:** When implementing selection grids, always wrap items in ` diff --git a/frontend/src/pages/JobStatus.tsx b/frontend/src/pages/JobStatus.tsx index d63e9f0..a89cfa9 100644 --- a/frontend/src/pages/JobStatus.tsx +++ b/frontend/src/pages/JobStatus.tsx @@ -7,6 +7,7 @@ import { getApiBase, fetchWithAuth, deleteJob } from '../api'; import { ColorIdentity } from '../components/ColorIdentity'; import { DeckShowcase } from '../components/DeckShowcase'; import { SimulationGrid } from '../components/SimulationGrid'; +import { Spinner } from '../components/Spinner'; import { useJobStream } from '../hooks/useJobStream'; import { useWinData } from '../hooks/useWinData'; import { useJobLogs } from '../hooks/useJobLogs'; @@ -184,8 +185,9 @@ export default function JobStatusPage() { type="button" onClick={handleRunAgain} disabled={isResubmitting} - className="bg-blue-600 hover:bg-blue-700 text-white text-sm rounded px-3 py-1 disabled:opacity-50 disabled:cursor-not-allowed" + className="bg-blue-600 hover:bg-blue-700 text-white text-sm rounded px-3 py-1 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-1.5" > + {isResubmitting && } {isResubmitting ? 'Submitting...' : 'Run Again'} )} @@ -237,8 +239,9 @@ export default function JobStatusPage() { type="button" onClick={handleCancel} disabled={isCancelling} - className="ml-auto px-3 py-1 text-xs rounded bg-orange-600 text-white hover:bg-orange-700 disabled:opacity-50 disabled:cursor-not-allowed" + className="ml-auto px-3 py-1 text-xs rounded bg-orange-600 text-white hover:bg-orange-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-1.5" > + {isCancelling && } {isCancelling ? 'Cancelling...' : 'Cancel Job'} @@ -324,8 +327,9 @@ export default function JobStatusPage() { type="button" onClick={handleCancel} disabled={isCancelling} - className="ml-4 px-3 py-1 text-xs rounded bg-orange-600 text-white hover:bg-orange-700 disabled:opacity-50 disabled:cursor-not-allowed" + className="ml-4 px-3 py-1 text-xs rounded bg-orange-600 text-white hover:bg-orange-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-1.5" > + {isCancelling && } {isCancelling ? 'Cancelling...' : 'Cancel Job'} )} @@ -780,8 +784,9 @@ export default function JobStatusPage() { type="button" onClick={handleDelete} disabled={isDeletingJob} - className="ml-auto px-3 py-1 text-sm rounded bg-red-600 text-white hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed" + className="ml-auto px-3 py-1 text-sm rounded bg-red-600 text-white hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-1.5" > + {isDeletingJob && } {isDeletingJob ? 'Deleting...' : 'Delete Job'} )} From 31e62805f795b6aec85e364081cc11a78a921c4b Mon Sep 17 00:00:00 2001 From: Tyler Holland Date: Fri, 27 Feb 2026 22:51:31 -0800 Subject: [PATCH 3/3] fix: address PR review comments - Restore explicit permissions block in automerge-label workflow (contents: read, pull-requests: write, issues: write) to enforce least-privilege on the GITHUB_TOKEN - Fix Spinner className concatenation to avoid trailing whitespace when no custom className is provided Co-Authored-By: Claude Opus 4.6 --- .github/workflows/automerge-label.yml | 5 +++++ frontend/src/components/Spinner.tsx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/automerge-label.yml b/.github/workflows/automerge-label.yml index a5ab835..9390cd8 100644 --- a/.github/workflows/automerge-label.yml +++ b/.github/workflows/automerge-label.yml @@ -4,6 +4,11 @@ on: pull_request_review: types: [submitted] +permissions: + contents: read + pull-requests: write + issues: write + jobs: add-label: if: >- diff --git a/frontend/src/components/Spinner.tsx b/frontend/src/components/Spinner.tsx index fed6db3..2482c4e 100644 --- a/frontend/src/components/Spinner.tsx +++ b/frontend/src/components/Spinner.tsx @@ -12,7 +12,7 @@ export function Spinner({ className = '', size = 'sm' }: SpinnerProps) { return (