forked from bai/curriculum-project-hub
feat(hub): org-scoped agent role/skill folder tree (ADR-0028)
Add a shared transparent OrganizationAgentConfigFolder tree for grouping agent roles and skills in the admin UI without affecting identity, bindings, run loading, or slash commands.
This commit is contained in:
@@ -14,15 +14,20 @@
|
||||
models,
|
||||
skills,
|
||||
slug,
|
||||
folderItems,
|
||||
onupdated,
|
||||
onskillschanged,
|
||||
onfolderchanged,
|
||||
}: {
|
||||
r: AgentRoleRow;
|
||||
models: AgentModelRow[];
|
||||
skills: AgentSkillRow[];
|
||||
slug: string;
|
||||
/** ADR-0028 folder choices ('' = 未分类); transparent grouping only */
|
||||
folderItems: { value: string; label: string }[];
|
||||
onupdated: (updated: AgentRoleRow) => void;
|
||||
onskillschanged: (roleId: string, skillNames: string[]) => void;
|
||||
onfolderchanged: (roleId: string, folderId: string | null) => void;
|
||||
} = $props();
|
||||
|
||||
const initial = {
|
||||
@@ -44,6 +49,8 @@
|
||||
let isDefault = $state(initial.isDefault);
|
||||
let selectedSkills = $state<string[]>([...initial.skillNames]);
|
||||
let saving = $state(false);
|
||||
let folderValue = $state(r.folderId ?? '');
|
||||
let savingFolder = $state(false);
|
||||
|
||||
const groupedTools = TOOL_OPTIONS.reduce(
|
||||
(acc, t) => {
|
||||
@@ -105,6 +112,24 @@
|
||||
function sortKeyDirty(): boolean {
|
||||
return Number(sortOrder) !== r.sortOrder;
|
||||
}
|
||||
|
||||
// ADR-0028: folder assignment is a label-class change — instant-apply, no
|
||||
// session archival, independent of the configuration save button.
|
||||
async function saveFolder(next: string) {
|
||||
const folderId = next === '' ? null : next;
|
||||
if (folderId === r.folderId) return;
|
||||
savingFolder = true;
|
||||
try {
|
||||
await api.setAgentRoleFolder(slug, r.roleId, folderId);
|
||||
onfolderchanged(r.roleId, folderId);
|
||||
toastSuccess('已更新所属文件夹');
|
||||
} catch (err) {
|
||||
folderValue = r.folderId ?? '';
|
||||
toastError(err instanceof Error ? err.message : String(err));
|
||||
} finally {
|
||||
savingFolder = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="saas-card-pad">
|
||||
@@ -114,6 +139,12 @@
|
||||
{#if r.isDefault}
|
||||
<span class="saas-badge-success">默认</span>
|
||||
{/if}
|
||||
<div class="ml-auto flex items-center gap-2">
|
||||
<span class="text-xs text-surface-600">文件夹</span>
|
||||
<div class="w-44">
|
||||
<SelectField items={folderItems} bind:value={folderValue} disabled={savingFolder} onchange={saveFolder} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
|
||||
Reference in New Issue
Block a user