feat: add ignore option for permission requests (UI-only dismissal)

This commit is contained in:
2026-02-21 03:52:26 -06:00
parent 07783f2aea
commit 24ba1fdf76
5 changed files with 77 additions and 3 deletions

View File

@@ -9,7 +9,8 @@ const {
groupedBySession,
modalVisible,
respondPermission,
respondPlan
respondPlan,
ignoreApproval
} = useGlobalApproval()
function truncateId(id: string): string {
@@ -68,6 +69,7 @@ watch(totalPending, (val) => {
:key="perm.requestId"
:request="perm"
@respond="(id, decision, reason) => respondPermission(id, decision, reason)"
@ignore="(id) => ignoreApproval(id)"
/>
<PlanApproval
v-for="plan in group.plans"

View File

@@ -10,6 +10,7 @@ const props = defineProps<{
const emit = defineEmits<{
respond: [requestId: string, decision: string, reason?: string]
ignore: [requestId: string]
}>()
// ── Mode detection ──
@@ -190,6 +191,14 @@ function elapsed(): string {
</svg>
Reject
</button>
<button class="btn btn-ignore" @click="emit('ignore', request.requestId)" title="Remove from UI without responding">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/>
<path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/>
<line x1="1" y1="1" x2="23" y2="23"/>
</svg>
Ignore
</button>
</div>
</div>
@@ -258,6 +267,14 @@ function elapsed(): string {
</svg>
Dismiss
</button>
<button class="btn btn-ignore" @click="emit('ignore', request.requestId)" title="Remove from UI without responding">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/>
<path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/>
<line x1="1" y1="1" x2="23" y2="23"/>
</svg>
Ignore
</button>
</div>
</div>
@@ -316,6 +333,14 @@ function elapsed(): string {
</svg>
Deny
</button>
<button class="btn btn-ignore" @click="emit('ignore', request.requestId)" title="Remove from UI without responding">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/>
<path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/>
<line x1="1" y1="1" x2="23" y2="23"/>
</svg>
Ignore
</button>
</div>
</div>
</template>
@@ -518,6 +543,9 @@ function elapsed(): string {
.btn-reject { background: #ef4444; color: white; }
.btn-reject:hover { background: #dc2626; }
.btn-ignore { background: transparent; color: var(--text-muted); border: 1px solid var(--border-color); }
.btn-ignore:hover { background: var(--bg-hover); color: var(--text-secondary); }
/* ── Transitions ── */
.expand-enter-active, .expand-leave-active { transition: all 0.2s ease; overflow: hidden; }
.expand-enter-from, .expand-leave-to { opacity: 0; max-height: 0; }

View File

@@ -103,6 +103,19 @@ export function useGlobalApproval() {
}
}
async function ignoreApproval(requestId: string) {
console.log(`[GlobalApproval] Ignoring ${requestId} (UI-only removal)`)
try {
await fetch('/api/hooks-approval/ignore', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ requestId })
})
} catch (e) {
console.error('[GlobalApproval] Failed to ignore approval:', e)
}
}
// ── connect/disconnect/fetchPending kept as no-ops for backward compat ──
// Session state WS (initialized in App.vue) handles everything now.
@@ -120,6 +133,7 @@ export function useGlobalApproval() {
disconnect,
fetchPending,
respondPermission,
respondPlan
respondPlan,
ignoreApproval
}
}