v0.15.13
This commit is contained in:
+40
-17
@@ -8495,20 +8495,6 @@ textarea:focus {
|
||||
}
|
||||
}
|
||||
|
||||
.flow-card[data-flow-card-id] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.flow-card[data-flow-card-id]:focus-visible {
|
||||
outline: 2px solid color-mix(in srgb, var(--accent) 55%, transparent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.flow-card[data-flow-card-id] button,
|
||||
.flow-card[data-flow-card-id] details {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.flow-generated-card {
|
||||
border-left: 3px solid var(--accent-border);
|
||||
}
|
||||
@@ -10573,17 +10559,54 @@ select.select-native-proxy[aria-invalid="true"]+.custom-select .custom-select-tr
|
||||
background: var(--surface-muted);
|
||||
}
|
||||
|
||||
.flow-card .flow-simulate-button {
|
||||
.flow-runtime-summary {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.flow-execution-type {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.flow-execution-type small {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.flow-execution-type strong {
|
||||
font-size: .82rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.flow-execution-schedule strong {
|
||||
color: var(--teal);
|
||||
}
|
||||
|
||||
.flow-execution-automation strong,
|
||||
.flow-execution-mixed strong {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.flow-execution-none strong,
|
||||
.flow-execution-draft strong {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.flow-card .flow-card-action-button {
|
||||
border: 1px solid var(--line);
|
||||
background: var(--surface-muted);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.flow-card .flow-simulate-button:hover:not(:disabled) {
|
||||
.flow-card .flow-card-action-button:hover:not(:disabled) {
|
||||
border-color: var(--line-strong);
|
||||
}
|
||||
|
||||
.flow-card .flow-simulate-button:disabled {
|
||||
.flow-card .flow-card-action-button:disabled {
|
||||
opacity: .45;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
+20
-9
@@ -104,14 +104,29 @@ function flowDefaultConfig(kind) {
|
||||
return {};
|
||||
}
|
||||
|
||||
function flowExecutionType(flow) {
|
||||
const schedules = flow.compiled_schedule_ids?.length || 0;
|
||||
const automations = flow.compiled_automation_ids?.length || 0;
|
||||
if (flow.draft) return { key: 'flow.executionDraft', className: 'draft' };
|
||||
if (schedules > 0 && automations > 0) return { key: 'flow.executionMixed', className: 'mixed' };
|
||||
if (schedules > 0) return { key: 'flow.executionSchedule', className: 'schedule' };
|
||||
if (automations > 0) return { key: 'flow.executionAutomation', className: 'automation' };
|
||||
return { key: 'flow.executionNone', className: 'none' };
|
||||
}
|
||||
|
||||
function renderFlows() {
|
||||
const host = $('#flowList'); if (!host) return;
|
||||
const count = $('#flowListCount'); if (count) count.textContent = tr('flow.listCount', { count: app.flows.length });
|
||||
host.innerHTML = app.flows.length ? app.flows.map(flow => `<article class="list-card flow-card ${flow.enabled && !flow.draft ? '' : 'is-disabled'} ${flow.draft ? 'is-draft' : ''}" data-flow-card-id="${esc(flow.id)}" tabindex="0" aria-label="${esc(`${tr('flow.openEditor')}: ${flow.name}`)}">
|
||||
<div class="list-card-head"><div class="flow-card-copy"><h3>${esc(flow.name)}${flow.draft ? ` <span class="badge flow-draft-badge">${esc(tr('flow.draft'))}</span>` : ''}</h3><div class="flow-card-description"><p>${esc(flow.description || tr('flow.defaultDescription'))}</p><button type="button" class="flow-description-edit" data-action="edit-flow-description" data-id="${esc(flow.id)}" aria-label="${esc(tr('flow.editDescription'))}" title="${esc(tr('flow.editDescription'))}">${uiIcon('edit')}</button></div></div>${flow.draft ? `<button type="button" class="enable-toggle" disabled title="${esc(tr('flow.draftDisabledHint'))}"><span>${uiIcon('edit')}</span>${esc(tr('flow.disabledState'))}</button>` : `<button type="button" class="enable-toggle ${flow.enabled ? 'active' : ''}" data-action="toggle-flow-enabled" data-id="${esc(flow.id)}" data-value="${flow.enabled ? 'false' : 'true'}" aria-label="${esc(tr(flow.enabled ? 'flow.disable' : 'flow.enable'))}" title="${esc(tr('flow.quickToggleHint'))}"><span>${uiIcon(flow.enabled ? 'check' : 'circle')}</span>${esc(flow.enabled ? tr('flow.enabledState') : tr('flow.disabledState'))}</button>`}</div>
|
||||
<div class="card-stats"><div class="card-stat"><small>${esc(tr('flow.blocks'))}</small><strong>${flow.nodes?.length || 0}</strong></div><div class="card-stat"><small>${esc(tr('nav.schedules'))}</small><strong>${flow.compiled_schedule_ids?.length || 0}</strong></div><div class="card-stat"><small>${esc(tr('nav.automations'))}</small><strong>${flow.compiled_automation_ids?.length || 0}</strong></div></div>
|
||||
<div class="card-footer"><small>${esc(flow.draft ? tr('flow.draftNoExecution') : tr('flow.compileCount', { schedules: flow.compiled_schedule_ids?.length || 0, automations: flow.compiled_automation_ids?.length || 0 }))}</small><div class="card-menu"><button class="flow-simulate-button" data-action="simulate-flow" data-id="${esc(flow.id)}" ${flow.draft ? `disabled title="${esc(tr('flow.simulatorDraftHint'))}"` : ''}>${esc(tr('flow.simpleSimulator'))}</button><button class="card-primary-action" data-action="edit-flow" data-id="${esc(flow.id)}">${esc(tr('flow.openEditor'))}</button><details class="card-overflow"><summary aria-label="${esc(tr('actions.more'))}" title="${esc(tr('actions.more'))}">${uiIcon('more-horizontal')}</summary><div class="card-overflow-menu"><button data-action="export-flow-by-id" data-id="${esc(flow.id)}">${esc(tr('flow.export'))}</button><button class="danger" data-action="delete-flow" data-id="${esc(flow.id)}">${esc(tr('actions.delete'))}</button></div></details></div></div>
|
||||
</article>`).join('') : `<div class="empty"><strong>${esc(tr('flow.emptyTitle'))}</strong>${esc(tr('flow.emptyText'))}</div>`;
|
||||
host.innerHTML = app.flows.length ? app.flows.map(flow => {
|
||||
const schedules = flow.compiled_schedule_ids?.length || 0;
|
||||
const automations = flow.compiled_automation_ids?.length || 0;
|
||||
const execution = flowExecutionType(flow);
|
||||
return `<article class="list-card flow-card ${flow.enabled && !flow.draft ? '' : 'is-disabled'} ${flow.draft ? 'is-draft' : ''}">
|
||||
<div class="list-card-head"><div class="flow-card-copy"><h3>${esc(flow.name)}${flow.draft ? ` <span class="badge flow-draft-badge">${esc(tr('flow.draft'))}</span>` : ''}</h3><div class="flow-card-description"><p>${esc(flow.description || tr('flow.defaultDescription'))}</p><button type="button" class="flow-description-edit" data-action="edit-flow-description" data-id="${esc(flow.id)}" aria-label="${esc(tr('flow.editDescription'))}" title="${esc(tr('flow.editDescription'))}">${uiIcon('edit')}</button></div></div>${flow.draft ? `<button type="button" class="enable-toggle" disabled title="${esc(tr('flow.draftDisabledHint'))}"><span>${uiIcon('edit')}</span>${esc(tr('flow.disabledState'))}</button>` : `<button type="button" class="enable-toggle ${flow.enabled ? 'active' : ''}" data-action="toggle-flow-enabled" data-id="${esc(flow.id)}" data-value="${flow.enabled ? 'false' : 'true'}" aria-label="${esc(tr(flow.enabled ? 'flow.disable' : 'flow.enable'))}" title="${esc(tr('flow.quickToggleHint'))}"><span>${uiIcon(flow.enabled ? 'check' : 'circle')}</span>${esc(flow.enabled ? tr('flow.enabledState') : tr('flow.disabledState'))}</button>`}</div>
|
||||
<div class="card-stats"><div class="card-stat"><small>${esc(tr('flow.blocks'))}</small><strong>${flow.nodes?.length || 0}</strong></div><div class="card-stat"><small>${esc(tr('nav.schedules'))}</small><strong>${schedules}</strong></div><div class="card-stat"><small>${esc(tr('nav.automations'))}</small><strong>${automations}</strong></div></div>
|
||||
<div class="card-footer"><div class="flow-runtime-summary"><div class="flow-execution-type flow-execution-${esc(execution.className)}"><small>${esc(tr('flow.executionType'))}</small><strong>${esc(tr(execution.key))}</strong></div><small class="flow-compile-count">${esc(flow.draft ? tr('flow.draftNoExecution') : tr('flow.compileCount', { schedules, automations }))}</small></div><div class="card-menu"><button class="flow-card-action-button" data-action="simulate-flow" data-id="${esc(flow.id)}" ${flow.draft ? `disabled title="${esc(tr('flow.simulatorDraftHint'))}"` : ''}>${esc(tr('flow.simpleSimulator'))}</button><button class="flow-card-action-button" data-action="edit-flow" data-id="${esc(flow.id)}">${esc(tr('flow.editorButton'))}</button><details class="card-overflow"><summary aria-label="${esc(tr('actions.more'))}" title="${esc(tr('actions.more'))}">${uiIcon('more-horizontal')}</summary><div class="card-overflow-menu"><button data-action="export-flow-by-id" data-id="${esc(flow.id)}">${esc(tr('flow.export'))}</button><button class="danger" data-action="delete-flow" data-id="${esc(flow.id)}">${esc(tr('actions.delete'))}</button></div></details></div></div>
|
||||
</article>`;
|
||||
}).join('') : `<div class="empty"><strong>${esc(tr('flow.emptyTitle'))}</strong>${esc(tr('flow.emptyText'))}</div>`;
|
||||
}
|
||||
|
||||
let flowDescriptionTargetId = null;
|
||||
@@ -1801,8 +1816,6 @@ document.addEventListener('contextmenu', event => {
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', event => {
|
||||
const flowCard = event.target.closest?.('[data-flow-card-id]');
|
||||
if (flowCard && event.target === flowCard && (event.key === 'Enter' || event.key === ' ')) { event.preventDefault(); openFlowEditor(flowCard.dataset.flowCardId); return; }
|
||||
if ($('#flowEditor')?.hidden || !app.flowDraft) return;
|
||||
if (event.target.closest?.('input,select,textarea,[contenteditable="true"]')) return;
|
||||
if (event.target.closest?.('dialog[open]') || document.querySelector('dialog[open]')) return;
|
||||
@@ -1856,8 +1869,6 @@ document.addEventListener('click', event => {
|
||||
return;
|
||||
}
|
||||
if (!event.target.closest?.('#flowContextMenu')) hideFlowContextMenu();
|
||||
const flowCard = event.target.closest?.('[data-flow-card-id]');
|
||||
if (flowCard && !event.target.closest?.('button,summary,details,input,select,textarea,a,label')) { openFlowEditor(flowCard.dataset.flowCardId); return; }
|
||||
const edge = event.target.closest?.('[data-flow-edge]'); if (edge) { removeFlowEdge(edge.dataset.flowEdge); return; }
|
||||
const add = event.target.closest?.('[data-flow-add]'); if (add) { const dialog = add.closest?.('#flowBlockDialog'); if (!dialog) flowBlockInsertPoint = null; addFlowNode(add.dataset.flowAdd); if (dialog?.open) dialog.close(); return; }
|
||||
const templateCategory = event.target.closest?.('[data-flow-template-category]'); if (templateCategory) { renderFlowPresetBrowser(templateCategory.dataset.flowTemplateCategory); return; }
|
||||
|
||||
Reference in New Issue
Block a user