ui: add contextual tooltips to web form controls
This commit is contained in:
@@ -832,7 +832,7 @@ function updateAssistantHealth(configData) {
|
||||
const modelDataList = (id, provider, selected) => {
|
||||
const options = modelOptionsByProvider[provider] ?? [];
|
||||
return `
|
||||
<input id="${id}" list="${id}-list" value="${escapeHtml(selected ?? '')}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="${id}" list="${id}-list" value="${escapeHtml(selected ?? '')}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" title="Enter a model ID for the selected provider or pick one from the suggestion list." />
|
||||
<datalist id="${id}-list">
|
||||
${options.map((model) => `<option value="${escapeHtml(model)}"></option>`).join('')}
|
||||
</datalist>
|
||||
@@ -909,13 +909,13 @@ function updateAssistantHealth(configData) {
|
||||
<div class="p-3 border border-zinc-800 rounded-md bg-zinc-950/60">
|
||||
<div class="text-sm text-zinc-50 mb-2">${escapeHtml(tier)} tier</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
<label class="flex flex-col gap-1">
|
||||
<label class="flex flex-col gap-1" title="Provider used for this model tier.">
|
||||
<span class="text-xs text-zinc-500">Provider</span>
|
||||
<select id="assist-tier-${tier}-provider" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none">
|
||||
<select id="assist-tier-${tier}-provider" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" title="Select a provider for the ${escapeHtml(tier)} tier.">
|
||||
${providerOption(provider)}
|
||||
</select>
|
||||
</label>
|
||||
<label class="flex flex-col gap-1">
|
||||
<label class="flex flex-col gap-1" title="Default model name for this tier.">
|
||||
<span class="text-xs text-zinc-500">Model</span>
|
||||
${modelDataList(`assist-tier-${tier}-model`, provider, model)}
|
||||
</label>
|
||||
@@ -925,9 +925,9 @@ function updateAssistantHealth(configData) {
|
||||
}).join('')}
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 mb-4">
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Main tier used when no task-specific routing rule applies.">
|
||||
<span class="text-sm text-zinc-400">Primary tier</span>
|
||||
<select id="assist-primary-tier" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none">
|
||||
<select id="assist-primary-tier" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Choose the default model tier for general assistant responses.">
|
||||
${tierOption(modelTier)}
|
||||
</select>
|
||||
</label>
|
||||
@@ -943,23 +943,23 @@ function updateAssistantHealth(configData) {
|
||||
<div class="p-3 border border-zinc-800 rounded-md bg-zinc-950/60">
|
||||
<div class="text-sm text-zinc-50 mb-2">${escapeHtml(task.label)}</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-2">
|
||||
<label class="flex flex-col gap-1">
|
||||
<label class="flex flex-col gap-1" title="Tier used when this task is delegated.">
|
||||
<span class="text-xs text-zinc-500">Delegation tier</span>
|
||||
<select id="assist-delegation-${task.key}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none">
|
||||
<select id="assist-delegation-${task.key}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" title="Select the tier used for ${escapeHtml(task.label.toLowerCase())} delegation.">
|
||||
${tierOption(delegationTier)}
|
||||
</select>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 mt-5 md:mt-0">
|
||||
<input id="assist-bg-${task.key}-enabled" type="checkbox" ${backgroundEnabled ? 'checked' : ''} />
|
||||
<label class="flex items-center gap-2 mt-5 md:mt-0" title="When enabled, this task can use a custom provider/model override.">
|
||||
<input id="assist-bg-${task.key}-enabled" type="checkbox" ${backgroundEnabled ? 'checked' : ''} title="Toggle background provider/model override for this task." />
|
||||
<span class="text-xs text-zinc-400">Enable provider/model override</span>
|
||||
</label>
|
||||
<label class="flex flex-col gap-1">
|
||||
<label class="flex flex-col gap-1" title="Provider used when override is enabled.">
|
||||
<span class="text-xs text-zinc-500">Provider</span>
|
||||
<select id="assist-bg-${task.key}-provider" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none">
|
||||
<select id="assist-bg-${task.key}-provider" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" title="Pick the override provider for this task.">
|
||||
${providerOption(draftTask.provider ?? background?.provider ?? tiers?.default?.provider ?? 'openai')}
|
||||
</select>
|
||||
</label>
|
||||
<label class="flex flex-col gap-1">
|
||||
<label class="flex flex-col gap-1" title="Model used when override is enabled.">
|
||||
<span class="text-xs text-zinc-500">Model</span>
|
||||
${modelDataList(
|
||||
`assist-bg-${task.key}-model`,
|
||||
@@ -967,9 +967,9 @@ function updateAssistantHealth(configData) {
|
||||
draftTask.model ?? background?.model ?? '',
|
||||
)}
|
||||
</label>
|
||||
<label class="flex flex-col gap-1">
|
||||
<label class="flex flex-col gap-1" title="Tier to fall back to if the override model fails.">
|
||||
<span class="text-xs text-zinc-500">Fallback tier</span>
|
||||
<select id="assist-bg-${task.key}-fallback" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none">
|
||||
<select id="assist-bg-${task.key}-fallback" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" title="Choose the fallback tier for this task override.">
|
||||
${tierOption(draftTask.fallbackTier ?? background?.fallback_tier ?? 'fast')}
|
||||
</select>
|
||||
</label>
|
||||
@@ -988,59 +988,59 @@ function updateAssistantHealth(configData) {
|
||||
<div class="text-sm font-semibold text-zinc-50 mb-3">Councils</div>
|
||||
<div class="text-sm text-zinc-500 mb-3">On-demand council orchestration settings and council role model tiers.</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3 mb-4">
|
||||
<label class="flex items-center gap-2 mt-5 md:mt-0">
|
||||
<input id="assist-councils-enabled" type="checkbox" ${councils.enabled ? 'checked' : ''} />
|
||||
<label class="flex items-center gap-2 mt-5 md:mt-0" title="Enable on-demand council orchestration flows.">
|
||||
<input id="assist-councils-enabled" type="checkbox" ${councils.enabled ? 'checked' : ''} title="Toggle council orchestration features." />
|
||||
<span class="text-xs text-zinc-400">Enable councils</span>
|
||||
</label>
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Model tier for D-council agents.">
|
||||
<span class="text-sm text-zinc-400">D model tier</span>
|
||||
<select id="assist-council-d-tier" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none">
|
||||
<select id="assist-council-d-tier" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Set the model tier for D-council roles.">
|
||||
${tierOption(councilsD.model_tier ?? 'complex')}
|
||||
</select>
|
||||
</label>
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Model tier for P-council agents.">
|
||||
<span class="text-sm text-zinc-400">P model tier</span>
|
||||
<select id="assist-council-p-tier" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none">
|
||||
<select id="assist-council-p-tier" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Set the model tier for P-council roles.">
|
||||
${tierOption(councilsP.model_tier ?? 'complex')}
|
||||
</select>
|
||||
</label>
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Model tier used for council meta synthesis.">
|
||||
<span class="text-sm text-zinc-400">Meta model tier</span>
|
||||
<select id="assist-council-meta-tier" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none">
|
||||
<select id="assist-council-meta-tier" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Set the model tier for the council meta arbiter.">
|
||||
${tierOption(councils.meta_model_tier ?? 'complex')}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 mb-4">
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Agent ID for the D arbiter role.">
|
||||
<span class="text-sm text-zinc-400">D arbiter agent</span>
|
||||
<input id="assist-council-d-arbiter" type="text" value="${escapeHtml(councilsD.arbiter_agent ?? 'council_d_arbiter')}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="assist-council-d-arbiter" type="text" value="${escapeHtml(councilsD.arbiter_agent ?? 'council_d_arbiter')}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Configured agent key for the D arbiter role." />
|
||||
</label>
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Agent ID for the D freethinker role.">
|
||||
<span class="text-sm text-zinc-400">D freethinker agent</span>
|
||||
<input id="assist-council-d-freethinker" type="text" value="${escapeHtml(councilsD.freethinker_agent ?? 'council_d_freethinker')}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="assist-council-d-freethinker" type="text" value="${escapeHtml(councilsD.freethinker_agent ?? 'council_d_freethinker')}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Configured agent key for the D freethinker role." />
|
||||
</label>
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Agent ID for the P arbiter role.">
|
||||
<span class="text-sm text-zinc-400">P arbiter agent</span>
|
||||
<input id="assist-council-p-arbiter" type="text" value="${escapeHtml(councilsP.arbiter_agent ?? 'council_p_arbiter')}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="assist-council-p-arbiter" type="text" value="${escapeHtml(councilsP.arbiter_agent ?? 'council_p_arbiter')}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Configured agent key for the P arbiter role." />
|
||||
</label>
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Agent ID for the P freethinker role.">
|
||||
<span class="text-sm text-zinc-400">P freethinker agent</span>
|
||||
<input id="assist-council-p-freethinker" type="text" value="${escapeHtml(councilsP.freethinker_agent ?? 'council_p_freethinker')}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="assist-council-p-freethinker" type="text" value="${escapeHtml(councilsP.freethinker_agent ?? 'council_p_freethinker')}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Configured agent key for the P freethinker role." />
|
||||
</label>
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Agent ID for the meta arbiter role.">
|
||||
<span class="text-sm text-zinc-400">Meta arbiter agent</span>
|
||||
<input id="assist-council-meta-arbiter" type="text" value="${escapeHtml(councils.meta_arbiter_agent ?? 'council_meta_arbiter')}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="assist-council-meta-arbiter" type="text" value="${escapeHtml(councils.meta_arbiter_agent ?? 'council_meta_arbiter')}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Configured agent key for the council meta arbiter role." />
|
||||
</label>
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Optional JSON scaffold used as council prompt template.">
|
||||
<span class="text-sm text-zinc-400">Scaffold path (optional)</span>
|
||||
<input id="assist-council-scaffold" type="text" value="${escapeHtml(councils.scaffold_path ?? '')}" placeholder="docs/councils/ai-council-production-scaffold.json" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="assist-council-scaffold" type="text" value="${escapeHtml(councils.scaffold_path ?? '')}" placeholder="docs/councils/ai-council-production-scaffold.json" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Path to a scaffold JSON file under the project directory." />
|
||||
</label>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 mb-4">
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Upper bound on iterative council rounds per run.">
|
||||
<span class="text-sm text-zinc-400">Max rounds</span>
|
||||
<input id="assist-council-max-rounds" type="number" min="1" max="6" value="${escapeHtml(String(councilsDefaults.max_rounds ?? 2))}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="assist-council-max-rounds" type="number" min="1" max="6" value="${escapeHtml(String(councilsDefaults.max_rounds ?? 2))}" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Use 1-6 rounds; higher values increase cost and latency." />
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
@@ -1052,16 +1052,14 @@ function updateAssistantHealth(configData) {
|
||||
<div class="text-sm font-semibold text-zinc-50 mb-2">Council Conversations</div>
|
||||
<div class="text-xs text-zinc-500 mb-3">${escapeHtml(councilSummary)}</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-[1fr_auto] gap-2 mb-3">
|
||||
<input id="assist-council-task" type="text" value="${escapeHtml(_lastCouncilTask)}" placeholder="Run councils on demand: e.g. design a 2-week experiment plan..." class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="assist-council-task" type="text" value="${escapeHtml(_lastCouncilTask)}" placeholder="Run councils on demand: e.g. design a 2-week experiment plan..." class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Prompt for an ad-hoc council run; use a concrete decision or planning question." />
|
||||
<button class="px-3 py-1.5 text-sm font-medium rounded-md border border-zinc-700 bg-zinc-800 text-zinc-200 hover:bg-zinc-700 transition-colors assistant-action-btn" data-action="run-council">
|
||||
Run Council
|
||||
</button>
|
||||
</div>
|
||||
<div id="assist-council-status" class="text-sm text-zinc-500 mb-3"></div>
|
||||
<div class="max-h-72 overflow-y-auto space-y-2">
|
||||
${councilConversations.length === 0
|
||||
? '<div class="text-sm text-zinc-500">No conversation log yet.</div>'
|
||||
: councilConversations.map((turn, idx) => `
|
||||
${councilConversations.length === 0 ? '<div class="text-sm text-zinc-500">No conversation log yet.</div>' : councilConversations.map((turn, idx) => `
|
||||
<details class="border border-zinc-800 rounded-md bg-zinc-900/70 p-2">
|
||||
<summary class="cursor-pointer text-sm text-zinc-100">
|
||||
#${idx + 1} ${escapeHtml(turn.call_id)} · ${escapeHtml(turn.agent)} @ ${escapeHtml(turn.tier)}
|
||||
@@ -1086,13 +1084,13 @@ function updateAssistantHealth(configData) {
|
||||
`).join('')}
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Channel used for scheduled briefing messages.">
|
||||
<span class="text-sm text-zinc-400">Briefing output channel</span>
|
||||
<input id="assist-brief-channel" type="text" value="${escapeHtml(briefingOutput?.channel ?? '')}" placeholder="telegram" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="assist-brief-channel" type="text" value="${escapeHtml(briefingOutput?.channel ?? '')}" placeholder="telegram" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Set the output adapter name for daily briefing delivery." />
|
||||
</label>
|
||||
<label class="flex flex-col gap-1.5">
|
||||
<label class="flex flex-col gap-1.5" title="Destination peer/chat ID for scheduled briefings.">
|
||||
<span class="text-sm text-zinc-400">Briefing output peer/chat id</span>
|
||||
<input id="assist-brief-peer" type="text" value="${escapeHtml(briefingOutput?.peer ?? '')}" placeholder="123456789" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="assist-brief-peer" type="text" value="${escapeHtml(briefingOutput?.peer ?? '')}" placeholder="123456789" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-3 py-2 text-sm focus:border-blue-500 outline-none" title="Set the recipient peer/chat ID for briefing delivery." />
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
@@ -1389,7 +1387,7 @@ function updateServices(servicesData) {
|
||||
? 'text-green-500'
|
||||
: svc.status === 'configured'
|
||||
? 'text-blue-500'
|
||||
: svc.status === 'error'
|
||||
: svc.status === 'error'
|
||||
? 'text-red-500'
|
||||
: 'text-zinc-500';
|
||||
const itemCount = svc.itemCount ? ` (${svc.itemCount})` : '';
|
||||
@@ -1446,21 +1444,21 @@ function renderServiceConfigModal() {
|
||||
const heartbeatSection = service.name === 'heartbeat'
|
||||
? `
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
<label class="flex flex-col gap-1">
|
||||
<label class="flex flex-col gap-1" title="Heartbeat check interval (examples: 1m, 5m, 30s).">
|
||||
<span class="text-xs text-zinc-500">Interval (e.g. 5m)</span>
|
||||
<input id="svc-heartbeat-interval" type="text" value="${escapeHtml(String(getConfigValue('automation.heartbeat.interval', '5m')))}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="svc-heartbeat-interval" type="text" value="${escapeHtml(String(getConfigValue('automation.heartbeat.interval', '5m')))}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" title="How often heartbeat checks are executed." />
|
||||
</label>
|
||||
<label class="flex flex-col gap-1">
|
||||
<label class="flex flex-col gap-1" title="Minimum wait between repeated failure notifications.">
|
||||
<span class="text-xs text-zinc-500">Notify cooldown</span>
|
||||
<input id="svc-heartbeat-notify-cooldown" type="text" value="${escapeHtml(String(getConfigValue('automation.heartbeat.notify_cooldown', '30m')))}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="svc-heartbeat-notify-cooldown" type="text" value="${escapeHtml(String(getConfigValue('automation.heartbeat.notify_cooldown', '30m')))}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" title="Cooldown duration before sending another alert for the same issue." />
|
||||
</label>
|
||||
<label class="flex flex-col gap-1">
|
||||
<label class="flex flex-col gap-1" title="Consecutive failed checks required before a service is marked unhealthy.">
|
||||
<span class="text-xs text-zinc-500">Failure threshold</span>
|
||||
<input id="svc-heartbeat-failure-threshold" type="number" min="1" max="10" value="${escapeHtml(String(getConfigValue('automation.heartbeat.failure_threshold', 2)))}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="svc-heartbeat-failure-threshold" type="number" min="1" max="10" value="${escapeHtml(String(getConfigValue('automation.heartbeat.failure_threshold', 2)))}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" title="Use 1 for aggressive alerting, higher values to reduce false positives." />
|
||||
</label>
|
||||
<label class="flex flex-col gap-1">
|
||||
<label class="flex flex-col gap-1" title="Free disk space alert threshold in megabytes.">
|
||||
<span class="text-xs text-zinc-500">Disk threshold (MB)</span>
|
||||
<input id="svc-heartbeat-disk-threshold" type="number" min="10" value="${escapeHtml(String(getConfigValue('automation.heartbeat.disk_threshold_mb', 100)))}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" />
|
||||
<input id="svc-heartbeat-disk-threshold" type="number" min="10" value="${escapeHtml(String(getConfigValue('automation.heartbeat.disk_threshold_mb', 100)))}" class="bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm focus:border-blue-500 outline-none" title="Alert when free disk falls below this value." />
|
||||
</label>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
@@ -1470,8 +1468,8 @@ function renderServiceConfigModal() {
|
||||
const selected = Array.isArray(getConfigValue('automation.heartbeat.checks', HEARTBEAT_CHECK_KEYS))
|
||||
&& getConfigValue('automation.heartbeat.checks', HEARTBEAT_CHECK_KEYS).includes(check);
|
||||
return `
|
||||
<label class="flex items-center gap-2 text-xs text-zinc-300">
|
||||
<input type="checkbox" data-heartbeat-check="${check}" ${selected ? 'checked' : ''} />
|
||||
<label class="flex items-center gap-2 text-xs text-zinc-300" title="Enable or disable the ${escapeHtml(check)} heartbeat check.">
|
||||
<input type="checkbox" data-heartbeat-check="${check}" ${selected ? 'checked' : ''} title="Toggle ${escapeHtml(check)} check." />
|
||||
<span>${escapeHtml(check)}</span>
|
||||
</label>
|
||||
`;
|
||||
@@ -1501,8 +1499,8 @@ function renderServiceConfigModal() {
|
||||
<div class="mb-3 p-3 border border-zinc-800 rounded bg-zinc-950/60">
|
||||
<div class="text-xs uppercase text-zinc-500 mb-2">Quick Settings</div>
|
||||
${hasQuickToggle ? `
|
||||
<label class="flex items-center gap-2 mb-2">
|
||||
<input id="svc-quick-enabled" type="checkbox" ${quickToggleValue ? 'checked' : ''} />
|
||||
<label class="flex items-center gap-2 mb-2" title="Master on/off for this service (when available).">
|
||||
<input id="svc-quick-enabled" type="checkbox" ${quickToggleValue ? 'checked' : ''} title="Enable or disable this service." />
|
||||
<span class="text-sm text-zinc-200">Enabled</span>
|
||||
</label>
|
||||
` : '<div class="text-xs text-zinc-500 mb-2">No quick toggle available for this service.</div>'}
|
||||
@@ -1510,7 +1508,7 @@ function renderServiceConfigModal() {
|
||||
</div>
|
||||
<div class="mb-3 p-3 border border-zinc-800 rounded bg-zinc-950/60">
|
||||
<div class="text-xs uppercase text-zinc-500 mb-2">Advanced Patch (optional JSON)</div>
|
||||
<textarea id="svc-advanced-patch" rows="5" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm font-mono focus:border-blue-500 outline-none" placeholder='{"automation.heartbeat.enabled": true}'>${escapeHtml(_serviceConfigState.advancedPatch ?? '')}</textarea>
|
||||
<textarea id="svc-advanced-patch" rows="5" class="w-full bg-zinc-950 text-zinc-50 border border-zinc-800 rounded-md px-2 py-1.5 text-sm font-mono focus:border-blue-500 outline-none" placeholder='{"automation.heartbeat.enabled": true}' title="Optional JSON object of config path/value pairs to patch on save.">${escapeHtml(_serviceConfigState.advancedPatch ?? '')}</textarea>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div id="svc-config-status" class="text-xs ${toneClass}">${escapeHtml(_serviceConfigState.status ?? '')}</div>
|
||||
|
||||
Reference in New Issue
Block a user