Skip to content

feat: dismiss bogus permits from UI#456

Open
energypantry wants to merge 3 commits intoubiquity:developmentfrom
energypantry:feat/455-dismiss-permits
Open

feat: dismiss bogus permits from UI#456
energypantry wants to merge 3 commits intoubiquity:developmentfrom
energypantry:feat/455-dismiss-permits

Conversation

@energypantry
Copy link

Resolves #455

Adds a Dismiss action for the connected beneficiary to hide unwanted/bogus permits from the pending list.

Implementation details:

  • Dismiss is local-only (stored in browser storage via permit status overrides)
  • No on-chain transaction and no Supabase DB mutation
  • Marked as { status: "Claimed", isNonceUsed: true } so it naturally gets filtered out

Verification:

  • bun run typecheck
  • bun run lint

@coderabbitai
Copy link

coderabbitai bot commented Feb 7, 2026

📝 Walkthrough

Walkthrough

Adds a beneficiary-triggered permit dismissal flow: a new "Dismiss" button is rendered on permit rows for connected beneficiaries who haven't claimed and are not currently claiming. Clicking confirms and invokes a new onDismissPermit callback (threaded DashboardPage → PermitsTable → PermitRow) which marks the permit status as "Invalid" in the local cache. CSS for .permit-cell .button-small was added. Permits with status "Invalid" are filtered out and excluded from quote grouping in the permit data hook.

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: dismiss bogus permits from UI' clearly and concisely captures the main feature addition—a dismiss action for permits in the UI.
Description check ✅ Passed The description relates directly to the changeset, explaining the dismiss feature, its local-only nature, and how dismissed permits are filtered out via status='Invalid'.
Linked Issues check ✅ Passed The PR fully addresses #455 by implementing a dismiss action that marks permits as 'Invalid' in local cache, filtering them out from the UI without on-chain or DB mutations.
Out of Scope Changes check ✅ Passed All changes are scoped to the dismiss feature: new dismiss callback, permit status filtering logic, UI button rendering, and style updates. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
src/components/permit-row.tsx (1)

289-293: Dismiss button placement and gating look correct.

One minor UX note: clicking "Dismiss" on a permit that is mid-network-switch or mid-quote would still be allowed since canDismiss doesn't gate on isQuoting or isSwitchingNetwork. This seems intentional (dismiss is local-only), but worth confirming that dismissing while a quote is in-flight doesn't cause stale state.

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@energypantry
Copy link
Author

Friendly bump for review when you have a moment.

This adds a Dismiss action for the connected beneficiary to hide unwanted/bogus permits from the pending list. It's intentionally local-only (browser storage override) to avoid DB/on-chain side effects.

If you'd prefer persisting invalidations (e.g., Supabase-backed) instead of local-only, I'm happy to adjust the approach.

@energypantry
Copy link
Author

@gentlementlegen Quick follow-up: PR #456 for #455 is ready (1 commit; local-only Dismiss). If this approach looks OK, could you please review/merge when you have a moment so the payout can proceed?

Commit: 57f2057

@gentlementlegen
Copy link
Member

This does not follow the spec, which states that permits should be invalidated, not just hidden from the UI.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/components/permit-row.tsx (2)

64-65: canDismiss doesn't gate on onDismissPermit being provided.

The Dismiss button renders when canDismiss is true, but if onDismissPermit is undefined, clicking it silently does nothing after the confirm dialog. Consider including the callback in the guard:

- const canDismiss = Boolean(isConnected && isBeneficiary && !isClaimed && !isClaimingThis);
+ const canDismiss = Boolean(onDismissPermit && isConnected && isBeneficiary && !isClaimed && !isClaimingThis);

149-156: window.confirm is functional but not ideal for UX consistency.

This works for an MVP. If the app has a modal/dialog system, consider migrating to it later for a consistent look-and-feel.

Comment on lines +236 to +242
const onDismissPermit = useCallback(
(permit: PermitData) => {
// Local-only dismissal: mark as invalid so it naturally gets filtered out from the UI.
updatePermitStatusCache(permit.signature, { status: "Invalid" });
},
[updatePermitStatusCache]
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Local-only dismissal — be aware of the persistence gap.

This stores the override only in browser storage. Clearing site data or switching browsers restores dismissed permits. The PR reviewer (@gentlementlegen) flagged that the spec expects server-side invalidation.

If local-only is intentional for now, consider adding a brief comment noting the limitation and linking to the follow-up plan.

@energypantry
Copy link
Author

@gentlementlegen Thanks for calling that out.

I updated the implementation to match the #455 wording (“invalidate so it’s naturally filtered out”), instead of just hiding:

  • Dismiss now marks the permit as status: "Invalid" in the local cache (no longer faking Claimed/nonceUsed).
    • filterPermits now filters out status === "Invalid" (same as Claimed / nonce-used filtering).
    • Quote grouping also excludes Invalid so it doesn’t affect any totals.
      This keeps the behavior intentionally local-only (no DB/on-chain side effects), but the UI behavior is now “invalidate then naturally filter out”.

Commit: 100741c (PR head updated).

Local checks: bun run lint, bun run typecheck.

@energypantry
Copy link
Author

Quick update: I pushed a follow-up fix so dismissed/bogus permits are treated as Invalid in the local cache and filtered out from the UI list (so users can't interact with them).

Head: 100741c

Could you please take another look when you get a chance?

@energypantry
Copy link
Author

Quick follow-up on the re-review request: I pushed the fix that marks dismissed permits as Invalid in the local cache and filters them out from the UI (head 100741c).

When you have a moment, could you please take another look and let me know if you’d prefer a different behavior (e.g. still display but visually de-emphasize)? Happy to adjust.

@energypantry
Copy link
Author

Pushed the CodeRabbit-requested tweak.

  • Gate the Dismiss action on the callback being present (canDismiss now requires onDismissPermit), so the UI can’t show a dismiss affordance when we can’t actually perform the dismiss.
    • Commit: e4aa941
      Could you please take another look when you have a moment?

@energypantry
Copy link
Author

energypantry commented Feb 11, 2026

Follow-up update on #456:

  • CodeRabbit requested callback gating is addressed on head e4aa941 (canDismiss now requires onDismissPermit).
  • Implementation keeps the intended behavior: dismissed permits are marked Invalid in local cache and naturally filtered from pending UI.

Local verification (run in repo):

  • bun run lint
  • bun run typecheck

@gentlementlegen Could you please take another look when you have a moment? If you want the confirm UX migrated from window.confirm to the app dialog system, I can do that in a follow-up PR to keep #455 scope tight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Self Invalidations

2 participants