mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-08 20:58:45 +02:00
fix: MCP group toggle styling and server-level approval UX
Two fixes in the auto-approval pill: 1. GroupToggle now uses brand-gradient-bg with glow shadow and matches ToggleSwitch sm dimensions, making MCP group toggles visually consistent with individual tool toggles. 2. Individual tool toggles now reflect server-level approval state. When a server key is approved, all tool rows show as enabled. Toggling a single tool OFF in a server-approved group expands the server key to individual tool IDs minus the excluded tool, enabling the 'approve all → disable one specific tool' workflow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -418,9 +418,19 @@ export function InlineApprovalPill({
|
|||||||
.filter((g) => g.tools.length > 0 || g.label.toLowerCase().includes(searchLower));
|
.filter((g) => g.tools.length > 0 || g.label.toLowerCase().includes(searchLower));
|
||||||
}, [groups, searchLower]);
|
}, [groups, searchLower]);
|
||||||
|
|
||||||
function toggleTool(toolId: string) {
|
function toggleTool(toolId: string, group: ApprovalToolGroup) {
|
||||||
const next = new Set(effectiveAutoApproved);
|
const next = new Set(effectiveAutoApproved);
|
||||||
if (next.has(toolId)) {
|
|
||||||
|
// If the group has server-level approval, expand it to individual tools
|
||||||
|
// so the user can selectively disable one tool.
|
||||||
|
if (group.serverApprovalKey && next.has(group.serverApprovalKey)) {
|
||||||
|
next.delete(group.serverApprovalKey);
|
||||||
|
for (const tool of group.tools) {
|
||||||
|
if (tool.id !== toolId) {
|
||||||
|
next.add(tool.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (next.has(toolId)) {
|
||||||
next.delete(toolId);
|
next.delete(toolId);
|
||||||
} else {
|
} else {
|
||||||
next.add(toolId);
|
next.add(toolId);
|
||||||
@@ -491,6 +501,12 @@ export function InlineApprovalPill({
|
|||||||
return expandedGroups.has(groupId);
|
return expandedGroups.has(groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isToolEffectivelyApproved(toolId: string, group: ApprovalToolGroup): boolean {
|
||||||
|
if (effectiveAutoApproved.has(toolId)) return true;
|
||||||
|
if (group.serverApprovalKey && effectiveAutoApproved.has(group.serverApprovalKey)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const allApprovedGlobal = effectiveAutoApprovedCount === totalItemCount && totalItemCount > 0;
|
const allApprovedGlobal = effectiveAutoApprovedCount === totalItemCount && totalItemCount > 0;
|
||||||
|
|
||||||
const approveAll = useCallback(() => {
|
const approveAll = useCallback(() => {
|
||||||
@@ -656,9 +672,9 @@ export function InlineApprovalPill({
|
|||||||
<div key={tool.id} className={isCollapsible ? 'pl-3' : ''}>
|
<div key={tool.id} className={isCollapsible ? 'pl-3' : ''}>
|
||||||
<PopoverToggleRow
|
<PopoverToggleRow
|
||||||
detail={detail}
|
detail={detail}
|
||||||
enabled={effectiveAutoApproved.has(tool.id)}
|
enabled={isToolEffectivelyApproved(tool.id, group)}
|
||||||
label={tool.label}
|
label={tool.label}
|
||||||
onToggle={() => toggleTool(tool.id)}
|
onToggle={() => toggleTool(tool.id, group)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -691,8 +707,8 @@ function GroupToggle({
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
aria-pressed={allApproved}
|
aria-pressed={allApproved}
|
||||||
className={`relative inline-flex h-[16px] w-[28px] shrink-0 items-center rounded-full transition-colors ${
|
className={`relative inline-flex h-[14px] w-[24px] shrink-0 items-center rounded-full transition-all duration-200 ${
|
||||||
allApproved ? 'bg-[var(--color-accent)]' : someApproved ? 'bg-[var(--color-surface-3)]' : 'bg-[var(--color-surface-3)]'
|
allApproved ? 'brand-gradient-bg shadow-[0_0_8px_rgba(36,92,249,0.3)]' : 'bg-[var(--color-surface-3)]'
|
||||||
}`}
|
}`}
|
||||||
onClick={onToggle}
|
onClick={onToggle}
|
||||||
type="button"
|
type="button"
|
||||||
@@ -701,8 +717,8 @@ function GroupToggle({
|
|||||||
<Minus className="absolute left-1/2 size-2 -translate-x-1/2 text-[var(--color-text-primary)]" strokeWidth={3} />
|
<Minus className="absolute left-1/2 size-2 -translate-x-1/2 text-[var(--color-text-primary)]" strokeWidth={3} />
|
||||||
) : (
|
) : (
|
||||||
<span
|
<span
|
||||||
className={`inline-block size-[12px] rounded-full bg-white shadow transition-transform ${
|
className={`inline-block size-[10px] rounded-full bg-white shadow-sm transition-transform ${
|
||||||
allApproved ? 'translate-x-[13px]' : 'translate-x-[2px]'
|
allApproved ? 'translate-x-[12px]' : 'translate-x-[2px]'
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user