feat(action): direct accept/reject buttons — no mirror tab needed, Extension /api/action endpoint
This commit is contained in:
@@ -526,6 +526,19 @@ body {
|
||||
background: var(--accent-primary);
|
||||
}
|
||||
|
||||
.msg-action-danger {
|
||||
background: #ef4444;
|
||||
}
|
||||
|
||||
.msg-action-danger:hover {
|
||||
background: #dc2626;
|
||||
}
|
||||
|
||||
.msg-action-btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* --- 상태 메시지 --- */
|
||||
.msg-status {
|
||||
text-align: center;
|
||||
|
||||
@@ -230,9 +230,10 @@
|
||||
if (nu.isBlocking) {
|
||||
messages.push({
|
||||
type: 'actions',
|
||||
label: '⚠️ Antigravity에서 리뷰가 필요합니다',
|
||||
label: '⚠️ 사용자 승인 대기 중',
|
||||
buttons: [
|
||||
{ label: '미러 탭에서 확인', action: 'switch_mirror' },
|
||||
{ label: '✅ 진행', action: 'api_call', endpoint: '/api/bridge/action', body: { action: 'acceptStep' } },
|
||||
{ label: '❌ 거절', action: 'api_call', endpoint: '/api/bridge/action', body: { action: 'rejectStep' }, variant: 'danger' },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -314,12 +314,34 @@ class ChatPanel {
|
||||
|
||||
for (const btn of (msg.buttons || [])) {
|
||||
const el = document.createElement('button');
|
||||
el.className = 'msg-action-btn msg-action-primary';
|
||||
el.className = btn.variant === 'danger' ? 'msg-action-btn msg-action-danger' : 'msg-action-btn msg-action-primary';
|
||||
el.textContent = btn.label || btn;
|
||||
el.style.cursor = 'pointer';
|
||||
|
||||
// action 기반 처리
|
||||
if (btn.action === 'switch_mirror') {
|
||||
// api_call: 직접 API 호출 (승인/거절 등)
|
||||
if (btn.action === 'api_call' && btn.endpoint) {
|
||||
el.addEventListener('click', async () => {
|
||||
el.disabled = true;
|
||||
el.textContent = '처리 중...';
|
||||
try {
|
||||
const res = await fetch(btn.endpoint, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(btn.body || {}),
|
||||
});
|
||||
if (res.ok) {
|
||||
el.textContent = '✓ 완료';
|
||||
// 모든 형제 버튼 비활성화
|
||||
div.querySelectorAll('button').forEach(b => { b.disabled = true; });
|
||||
} else {
|
||||
const err = await res.json().catch(() => ({}));
|
||||
el.textContent = `실패: ${err.error || res.status}`;
|
||||
}
|
||||
} catch (e) {
|
||||
el.textContent = `오류: ${e.message}`;
|
||||
}
|
||||
});
|
||||
} else if (btn.action === 'switch_mirror') {
|
||||
el.addEventListener('click', () => {
|
||||
document.getElementById('tabMirror')?.click();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user