吸收数字员工技能远端策略下发
This commit is contained in:
@@ -2,7 +2,7 @@ import { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import GlassCard from '@/components/digital/GlassCard';
|
||||
import CardTitleBar from '@/components/digital/CardTitleBar';
|
||||
import { adaptSkillSummaries, type SkillSummary } from '@/lib/consoleDataAdapter';
|
||||
import { getSkills, setSkillEnabled } from '@/lib/api';
|
||||
import { getSkills, pullSkillPolicies, setSkillEnabled } from '@/lib/api';
|
||||
import { domSafeId } from './navigation';
|
||||
|
||||
type TaskCadence = 'daily' | 'weekly' | 'monthly' | 'adhoc';
|
||||
@@ -81,6 +81,8 @@ function skillMetaBadges(skill: SkillSummary): string[] {
|
||||
const badges: string[] = [];
|
||||
if (skill.serverId) badges.push(skill.serverId);
|
||||
if (skill.running !== null && skill.running !== undefined) badges.push(skill.running ? '运行中' : '未运行');
|
||||
if (skill.policySource === 'remote') badges.push('远端策略');
|
||||
if (skill.remotePolicy && skill.remotePolicy.enabled === false) badges.push('管理端禁用');
|
||||
if (skill.governancePolicy) badges.push(policyLabels[skill.governancePolicy]);
|
||||
if (typeof skill.toolCount === 'number') badges.push(`${skill.toolCount} 工具`);
|
||||
if (skill.allowTools?.length) badges.push(`allow ${skill.allowTools.length}`);
|
||||
@@ -174,7 +176,9 @@ export default function SkillLibrary({ focusSkillId }: { focusSkillId?: string |
|
||||
const [cadenceFilter, setCadenceFilter] = useState<'all' | TaskCadence>('all');
|
||||
const [selectedSkillId, setSelectedSkillId] = useState<string | null>(focusSkillId ?? null);
|
||||
const [updatingSkillId, setUpdatingSkillId] = useState<string | null>(null);
|
||||
const [pullingPolicies, setPullingPolicies] = useState(false);
|
||||
const [actionError, setActionError] = useState<string | null>(null);
|
||||
const [actionNotice, setActionNotice] = useState<string | null>(null);
|
||||
|
||||
const mountedRef = useRef(false);
|
||||
useEffect(() => {
|
||||
@@ -217,6 +221,7 @@ export default function SkillLibrary({ focusSkillId }: { focusSkillId?: string |
|
||||
const nextEnabled = !skill.enabled;
|
||||
setUpdatingSkillId(skill.id);
|
||||
setActionError(null);
|
||||
setActionNotice(null);
|
||||
try {
|
||||
const result = await setSkillEnabled(skill.id, nextEnabled);
|
||||
if (!result.ok) {
|
||||
@@ -233,6 +238,22 @@ export default function SkillLibrary({ focusSkillId }: { focusSkillId?: string |
|
||||
}
|
||||
}, []);
|
||||
|
||||
const pullPolicies = useCallback(async () => {
|
||||
setPullingPolicies(true);
|
||||
setActionError(null);
|
||||
setActionNotice(null);
|
||||
try {
|
||||
const result = await pullSkillPolicies();
|
||||
if (!result.ok) throw new Error(result.error || '技能策略拉取失败');
|
||||
await fetchSkills();
|
||||
setActionNotice(result.skipped ? '技能策略无需重复拉取。' : '技能策略已更新。');
|
||||
} catch (err) {
|
||||
setActionError(err instanceof Error ? err.message : '技能策略拉取失败');
|
||||
} finally {
|
||||
setPullingPolicies(false);
|
||||
}
|
||||
}, [fetchSkills]);
|
||||
|
||||
const filtered = skills
|
||||
.filter(s => cadenceFilter === 'all' || getCadence(s) === cadenceFilter)
|
||||
.filter(s => {
|
||||
@@ -322,6 +343,9 @@ export default function SkillLibrary({ focusSkillId }: { focusSkillId?: string |
|
||||
<div style={{ padding: '14px 18px' }}>
|
||||
<GlassCard>
|
||||
<CardTitleBar title="学习技能">
|
||||
<button onClick={pullPolicies} disabled={pullingPolicies} className="de-btn-secondary de-btn-sm">
|
||||
{pullingPolicies ? '拉取中...' : '拉取策略'}
|
||||
</button>
|
||||
<button onClick={fetchSkills} className="de-btn-secondary de-btn-sm">刷新</button>
|
||||
</CardTitleBar>
|
||||
<div className="de-card-body">
|
||||
@@ -330,6 +354,11 @@ export default function SkillLibrary({ focusSkillId }: { focusSkillId?: string |
|
||||
{actionError}
|
||||
</div>
|
||||
)}
|
||||
{actionNotice && (
|
||||
<div className="de-schedule-result" style={{ marginBottom: 12 }}>
|
||||
{actionNotice}
|
||||
</div>
|
||||
)}
|
||||
<div className="de-skill-toolbar">
|
||||
<input type="text" className="de-input" placeholder="搜索业务能力..." value={search} onChange={e => setSearch(e.target.value)} />
|
||||
<div className="de-filter-row">
|
||||
|
||||
Reference in New Issue
Block a user