refactor: normalize skills UI status keys
This commit is contained in:
@@ -396,11 +396,12 @@ export function renderApp(state: AppViewState) {
|
|||||||
messages: state.skillMessages,
|
messages: state.skillMessages,
|
||||||
busyKey: state.skillsBusyKey,
|
busyKey: state.skillsBusyKey,
|
||||||
onFilterChange: (next) => (state.skillsFilter = next),
|
onFilterChange: (next) => (state.skillsFilter = next),
|
||||||
onRefresh: () => loadSkills(state),
|
onRefresh: () => loadSkills(state, { clearMessages: true }),
|
||||||
onToggle: (key, enabled) => updateSkillEnabled(state, key, enabled),
|
onToggle: (key, enabled) => updateSkillEnabled(state, key, enabled),
|
||||||
onEdit: (key, value) => updateSkillEdit(state, key, value),
|
onEdit: (key, value) => updateSkillEdit(state, key, value),
|
||||||
onSaveKey: (key) => saveSkillApiKey(state, key),
|
onSaveKey: (key) => saveSkillApiKey(state, key),
|
||||||
onInstall: (name, installId) => installSkill(state, name, installId),
|
onInstall: (skillKey, name, installId) =>
|
||||||
|
installSkill(state, skillKey, name, installId),
|
||||||
})
|
})
|
||||||
: nothing}
|
: nothing}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ export type SkillMessage = {
|
|||||||
|
|
||||||
export type SkillMessageMap = Record<string, SkillMessage>;
|
export type SkillMessageMap = Record<string, SkillMessage>;
|
||||||
|
|
||||||
|
type LoadSkillsOptions = {
|
||||||
|
clearMessages?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
function setSkillMessage(state: SkillsState, key: string, message?: SkillMessage) {
|
function setSkillMessage(state: SkillsState, key: string, message?: SkillMessage) {
|
||||||
if (!key.trim()) return;
|
if (!key.trim()) return;
|
||||||
const next = { ...state.skillMessages };
|
const next = { ...state.skillMessages };
|
||||||
@@ -27,7 +31,15 @@ function setSkillMessage(state: SkillsState, key: string, message?: SkillMessage
|
|||||||
state.skillMessages = next;
|
state.skillMessages = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadSkills(state: SkillsState) {
|
function getErrorMessage(err: unknown) {
|
||||||
|
if (err instanceof Error) return err.message;
|
||||||
|
return String(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadSkills(state: SkillsState, options?: LoadSkillsOptions) {
|
||||||
|
if (options?.clearMessages && Object.keys(state.skillMessages).length > 0) {
|
||||||
|
state.skillMessages = {};
|
||||||
|
}
|
||||||
if (!state.client || !state.connected) return;
|
if (!state.client || !state.connected) return;
|
||||||
if (state.skillsLoading) return;
|
if (state.skillsLoading) return;
|
||||||
state.skillsLoading = true;
|
state.skillsLoading = true;
|
||||||
@@ -38,7 +50,7 @@ export async function loadSkills(state: SkillsState) {
|
|||||||
| undefined;
|
| undefined;
|
||||||
if (res) state.skillsReport = res;
|
if (res) state.skillsReport = res;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
state.skillsError = String(err);
|
state.skillsError = getErrorMessage(err);
|
||||||
} finally {
|
} finally {
|
||||||
state.skillsLoading = false;
|
state.skillsLoading = false;
|
||||||
}
|
}
|
||||||
@@ -68,10 +80,11 @@ export async function updateSkillEnabled(
|
|||||||
message: enabled ? "Skill enabled" : "Skill disabled",
|
message: enabled ? "Skill enabled" : "Skill disabled",
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
state.skillsError = String(err);
|
const message = getErrorMessage(err);
|
||||||
|
state.skillsError = message;
|
||||||
setSkillMessage(state, skillKey, {
|
setSkillMessage(state, skillKey, {
|
||||||
kind: "error",
|
kind: "error",
|
||||||
message: String(err),
|
message,
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
state.skillsBusyKey = null;
|
state.skillsBusyKey = null;
|
||||||
@@ -91,10 +104,11 @@ export async function saveSkillApiKey(state: SkillsState, skillKey: string) {
|
|||||||
message: "API key saved",
|
message: "API key saved",
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
state.skillsError = String(err);
|
const message = getErrorMessage(err);
|
||||||
|
state.skillsError = message;
|
||||||
setSkillMessage(state, skillKey, {
|
setSkillMessage(state, skillKey, {
|
||||||
kind: "error",
|
kind: "error",
|
||||||
message: String(err),
|
message,
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
state.skillsBusyKey = null;
|
state.skillsBusyKey = null;
|
||||||
@@ -103,11 +117,12 @@ export async function saveSkillApiKey(state: SkillsState, skillKey: string) {
|
|||||||
|
|
||||||
export async function installSkill(
|
export async function installSkill(
|
||||||
state: SkillsState,
|
state: SkillsState,
|
||||||
|
skillKey: string,
|
||||||
name: string,
|
name: string,
|
||||||
installId: string,
|
installId: string,
|
||||||
) {
|
) {
|
||||||
if (!state.client || !state.connected) return;
|
if (!state.client || !state.connected) return;
|
||||||
state.skillsBusyKey = name;
|
state.skillsBusyKey = skillKey;
|
||||||
state.skillsError = null;
|
state.skillsError = null;
|
||||||
try {
|
try {
|
||||||
const result = (await state.client.request("skills.install", {
|
const result = (await state.client.request("skills.install", {
|
||||||
@@ -116,15 +131,16 @@ export async function installSkill(
|
|||||||
timeoutMs: 120000,
|
timeoutMs: 120000,
|
||||||
})) as { ok?: boolean; message?: string };
|
})) as { ok?: boolean; message?: string };
|
||||||
await loadSkills(state);
|
await loadSkills(state);
|
||||||
setSkillMessage(state, name, {
|
setSkillMessage(state, skillKey, {
|
||||||
kind: "success",
|
kind: "success",
|
||||||
message: result?.message ?? "Installed",
|
message: result?.message ?? "Installed",
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
state.skillsError = String(err);
|
const message = getErrorMessage(err);
|
||||||
setSkillMessage(state, name, {
|
state.skillsError = message;
|
||||||
|
setSkillMessage(state, skillKey, {
|
||||||
kind: "error",
|
kind: "error",
|
||||||
message: String(err),
|
message,
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
state.skillsBusyKey = null;
|
state.skillsBusyKey = null;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export type SkillsProps = {
|
|||||||
onToggle: (skillKey: string, enabled: boolean) => void;
|
onToggle: (skillKey: string, enabled: boolean) => void;
|
||||||
onEdit: (skillKey: string, value: string) => void;
|
onEdit: (skillKey: string, value: string) => void;
|
||||||
onSaveKey: (skillKey: string) => void;
|
onSaveKey: (skillKey: string) => void;
|
||||||
onInstall: (name: string, installId: string) => void;
|
onInstall: (skillKey: string, name: string, installId: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function renderSkills(props: SkillsProps) {
|
export function renderSkills(props: SkillsProps) {
|
||||||
@@ -73,10 +73,9 @@ export function renderSkills(props: SkillsProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderSkill(skill: SkillStatusEntry, props: SkillsProps) {
|
function renderSkill(skill: SkillStatusEntry, props: SkillsProps) {
|
||||||
const busy = props.busyKey === skill.skillKey || props.busyKey === skill.name;
|
const busy = props.busyKey === skill.skillKey;
|
||||||
const apiKey = props.edits[skill.skillKey] ?? "";
|
const apiKey = props.edits[skill.skillKey] ?? "";
|
||||||
const message =
|
const message = props.messages[skill.skillKey] ?? null;
|
||||||
props.messages[skill.skillKey] ?? props.messages[skill.name] ?? null;
|
|
||||||
const canInstall =
|
const canInstall =
|
||||||
skill.install.length > 0 && skill.missing.bins.length > 0;
|
skill.install.length > 0 && skill.missing.bins.length > 0;
|
||||||
const missing = [
|
const missing = [
|
||||||
@@ -130,7 +129,8 @@ function renderSkill(skill: SkillStatusEntry, props: SkillsProps) {
|
|||||||
? html`<button
|
? html`<button
|
||||||
class="btn"
|
class="btn"
|
||||||
?disabled=${busy}
|
?disabled=${busy}
|
||||||
@click=${() => props.onInstall(skill.name, skill.install[0].id)}
|
@click=${() =>
|
||||||
|
props.onInstall(skill.skillKey, skill.name, skill.install[0].id)}
|
||||||
>
|
>
|
||||||
${busy ? "Installing…" : skill.install[0].label}
|
${busy ? "Installing…" : skill.install[0].label}
|
||||||
</button>`
|
</button>`
|
||||||
|
|||||||
Reference in New Issue
Block a user