v0.11.3
This commit is contained in:
Generated
+1
-1
@@ -633,7 +633,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gree-controller"
|
||||
version = "0.11.2"
|
||||
version = "0.11.3"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"aes-gcm",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "gree-controller"
|
||||
version = "0.11.2"
|
||||
version = "0.11.3"
|
||||
edition = "2021"
|
||||
authors = ["GREE Controller contributors"]
|
||||
description = "Standalone local GREE HVAC controller with Web UI, SQLite and Home Assistant sensor support"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
d67af429e4da9ce08e9d2f2a8472849ffbd70d135b1c5da535a076026794d04c ./.env.example
|
||||
a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore
|
||||
a40c2764fb504ebe70c8cd1cf7f1f1c9f5f870a5e51e5a4711eac6721d6cc09b ./Cargo.lock
|
||||
aa1d1bc6b03f0c0f4719a0c6dcb0725980da2ce9dc37f3476b14372da3468f6a ./Cargo.toml
|
||||
2b03135cfb84c2df0f14380231e954882d743ba922c65ba3cbc56474057a039b ./Cargo.lock
|
||||
2bd686728663c50fa901cc3b35519da0e91e08e44994aff46783dedbd62409bd ./Cargo.toml
|
||||
19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE
|
||||
f2ff4364706d1906e9961c56f311fb056c166f63a1b0ec184e844bc02be9c33f ./README.md
|
||||
fe279b20b6e9da85c1e639078c213875bfa842102017cda4d0d06120fe8fe3ba ./README.md
|
||||
41dfdc6d099b54f87d4dd51f696122b3c88d3bf3ddf420bea8f4bc621ba920b0 ./build.rs
|
||||
a3708b5708784936ff2509ccf094fc9926071560452cb0a07e5d3d283e265d7e ./docs/API.md
|
||||
ec33deef383b0aee070d3fef68c54387d6dba4fc2fc9b56f4a902484c5338989 ./docs/API.md
|
||||
2e1e18fd8167dabfe2469c26e85cce62486c7cb6a502c63c6f6b0cd74d5885e0 ./docs/FLOW.md
|
||||
a0893b2a56eb1523f1a72871842e9be2139a5fafba1f51ae942fc407a6e4ca34 ./home-assistant/README.md
|
||||
f8e8559fe10fe523ac5bc9aac25c6e26e862f679d502e8f3c39f38a0a8e40911 ./home-assistant/custom_components/gree_controller/__init__.py
|
||||
@@ -26,8 +26,8 @@ cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./home-assista
|
||||
13f30e2dcdcedbd1b6c3f99c2335e0487108fd72c8e86922368b84f2fa2038ae ./home-assistant/custom_components/gree_controller/translations/pl.json
|
||||
4513070521d3dda0efb0d974a86ba674494cfb2b66fe9e5cac5b1b0430dede97 ./home-assistant/generated/gree_controller_entities.example.json
|
||||
253a0bc912786e67ea7fc92a64e4a510ad973bec343a88ccfb1f28fca3e8cf01 ./lang/README.md
|
||||
2cd6bca7f5aa2a4e59f789c5c55229aab7ba52c1f2b9d5742c8f17162b0c4f8f ./lang/en.json
|
||||
13f056aa147c3adb301b7d935adf498bbbf6d6906ec3eb96b3e39cd4c0e90fce ./lang/pl.json
|
||||
69f9a7d4152036db8a48773d5c0fa364ab0fbb9cde1f28d07390023509d3544d ./lang/en.json
|
||||
36cbb4ab3233b21ef13ce1dd01f747c5067d406f246df8c52ea48b3a426d64f3 ./lang/pl.json
|
||||
d8459024f04ca514bd8e9d6bd3af872fb942fd85a7cdd5583f4a9d28aab6faba ./make_zip.py
|
||||
b14233a8987e53bbbdd6770386ba10fa166ec25c1e098275c173c544b37846fc ./presets/bedroom_window_night.json
|
||||
1960841119c0b673fb2f03621b32237552fd828045304cd221401214b997c910 ./presets/device_resilience.json
|
||||
@@ -172,7 +172,7 @@ f13f1be3d5789539eba3fc1b59c14835f8c681eca7634e118fa3763a53aeee2b ./src/queries/
|
||||
b92a6cb158b494fe145b43c7641e65f6fafff47201d7d76edbec2cfd8b94835c ./systemd/gree-controller.service
|
||||
544a31cb2e5374227026afd6abd0d910381f3fca1638154ebd74e3c3d96a35d1 ./web/404.html
|
||||
e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.svg
|
||||
9cfdddeb88418a01936c66611327c566cb3d3ab6816d4ffd1189c53e6cf7df8d ./web/index.html
|
||||
b39ebf9538c078f2311d3064207da0fa46217037e1eb56566867028565719e53 ./web/index.html
|
||||
9ba3f6fa05b72aa989139b2a909982571b2a02055052e4c40104f1e81a9aa7eb ./web/js/README.md
|
||||
21b662914590e720dafefe4dc3dccc91dbeb963cce9ae91f007c835d2d0c1fe5 ./web/js/bootstrap.js
|
||||
72fa280996ba331a05bdb29a1f49b4e61bdd8964953c8ce1db952156620f08fe ./web/js/charts.js
|
||||
@@ -180,7 +180,7 @@ e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.
|
||||
dfc123885a9b6b5c1d07c12d2d2625ff15aa0844e5cd3736092ccd0a360da39c ./web/js/dashboard.js
|
||||
f53e2da5c48b55cf0191ffeb970a2c053c66e62d29099e3c5b5fccc8d89440cc ./web/js/entities.js
|
||||
9a0e87911f78cd8a969f4c57ce74774f5fa829fdecd79494d9a7f9d5804f9792 ./web/js/events.js
|
||||
8cbc2bc0f31721fbc441bd4be1008b430cae43d4a4035bf72b88eaf32a054c74 ./web/js/flows.js
|
||||
2bcf1292d26815e4919492c558601d8f0ddd61163f7ec916b562a40b409abdde ./web/js/flows.js
|
||||
f06557c6d338259059b990f8f79c91d68ac8ec1f245c302468f08929b5506901 ./web/js/forms.js
|
||||
dbf36223863ba882c03eccea4516ba8db7acf0c2e72c6c64490cb994f1e20f96 ./web/js/history.js
|
||||
7eaa04992ea828dc89f5eaebf674cbbfd160f53eb8d0d6ef0d4e47bd8c28c435 ./web/js/main.js
|
||||
@@ -190,6 +190,6 @@ c8c82e88c3715b1bfabf155e36266a4c94f5e2fc03eb39dcdd9d08a1985a997c ./web/js/route
|
||||
34513d9ec2e45c60443dffe028eea74f415b8a29016df6af3377a80a4ac0df5b ./web/js/settings-ui.js
|
||||
aa6a2ba22648de44547efd09f41c4335ebe38ed564f4684e942d7827df40f1a2 ./web/js/settings.js
|
||||
6b653e4fe2d4db4ffae6ff8f39b8ce57a10a990dc0000ee4aae51d949afadd52 ./web/manifest.webmanifest
|
||||
5f8c321809677a12f20bf270c17c7472f6dfc289c03d40c879b92ba10e3f6d6d ./web/styles.css
|
||||
3069a9860857d4c9f1d820c6066cc9c9326d495b49083a422d327249032dd9e4 ./web/styles.css
|
||||
ae1b03f30b494f474a781a5d32072f1e73eba2b7c768109fc1cc8028cb6662a4 ./web/sw.js
|
||||
d505d793ce7cc9485b45b78bba1c0d51887adc7451ab59a42702946e5b991382 ./web/theme-init.js
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Self-hosted controller for GREE-compatible air conditioners with a local Web UI, thermostat zones, schedules, Home Assistant integration, history, notifications and a documented HTTP/WebSocket API.
|
||||
|
||||
**Current release: 0.11.2**
|
||||
**Current release: 0.11.3**
|
||||
|
||||
> [Full API reference](docs/API.md) — authentication, every endpoint, request bodies, response models, WebSocket events and examples.
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
# GREE Controller API reference
|
||||
|
||||
HTTP and WebSocket API for GREE Controller **0.11.2**.
|
||||
HTTP and WebSocket API for GREE Controller **0.11.3**.
|
||||
|
||||
[← Main documentation](../README.md)
|
||||
|
||||
@@ -213,7 +213,7 @@ Response:
|
||||
{
|
||||
"status": "ok",
|
||||
"name": "gree-controller",
|
||||
"version": "0.11.2",
|
||||
"version": "0.11.3",
|
||||
"uptime_seconds": 1234,
|
||||
"control_ready": true,
|
||||
"time": "2026-08-30T06:54:00Z"
|
||||
@@ -237,7 +237,7 @@ Returns the initial Web UI snapshot:
|
||||
"settings": {},
|
||||
"outdoor_temperature": null,
|
||||
"system": {
|
||||
"version": "0.11.2",
|
||||
"version": "0.11.3",
|
||||
"uptime_seconds": 1234,
|
||||
"auth_required": false,
|
||||
"control_ready": true,
|
||||
|
||||
@@ -1045,6 +1045,7 @@
|
||||
"flow.logMessageBlockedOwnership": "The Flow action was suppressed because control ownership changed during execution.",
|
||||
"flow.logMessageConflict": "The Flow action was skipped because another automation already claimed the same target.",
|
||||
"flow.nameAliasHint": "This is only the user-facing display name. The technical Flow ID and generated task names remain unchanged.",
|
||||
"flow.editName": "Edit Flow name",
|
||||
"flow.sharedInputSourceOnlyHint": "This shared input stores only the value source. Configure the comparison in the Flow block.",
|
||||
"flow.triggers": "Triggers",
|
||||
"flow.node.cronTrigger": "CRON schedule",
|
||||
|
||||
@@ -1045,6 +1045,7 @@
|
||||
"flow.logMessageBlockedOwnership": "Akcja Flow została pominięta, ponieważ w trakcie wykonania zmienił się właściciel sterowania.",
|
||||
"flow.logMessageConflict": "Akcja Flow została pominięta z powodu konfliktu z inną automatyzacją dla tego samego celu.",
|
||||
"flow.nameAliasHint": "To tylko nazwa wyświetlana użytkownikowi. Techniczne ID Flow i nazwy wygenerowanych zadań pozostają bez zmian.",
|
||||
"flow.editName": "Edytuj nazwę Flow",
|
||||
"flow.sharedInputSourceOnlyHint": "Wspólne wejście zapisuje tylko źródło wartości. Porównanie ustawiasz w bloku Flow.",
|
||||
"flow.triggers": "Wyzwalacze",
|
||||
"flow.node.cronTrigger": "CRON / harmonogram",
|
||||
|
||||
+1
-1
@@ -693,7 +693,7 @@
|
||||
|
||||
<section id="flowEditor" class="flow-editor" hidden aria-label="Flow editor">
|
||||
<header class="flow-editor-bar">
|
||||
<div class="flow-editor-title"><button type="button" class="icon-button" data-action="close-flow-editor" aria-label="Back">←</button><div><span class="eyebrow" data-i18n="flow.editorEyebrow">Flow editor</span><input id="flowName" maxlength="100" data-i18n-placeholder="flow.namePlaceholder" data-i18n-title="flow.nameAliasHint" placeholder="My automation"></div></div>
|
||||
<div class="flow-editor-title"><button type="button" class="icon-button" data-action="close-flow-editor" aria-label="Back">←</button><div><span class="eyebrow" data-i18n="flow.editorEyebrow">Flow editor</span><div class="flow-name-wrap"><div id="flowNameView" class="flow-name-view" hidden><button id="flowNameText" class="flow-name-text" type="button" data-action="edit-flow-name" data-i18n-title="flow.editName" title="Edit Flow name"></button><button class="flow-name-edit" type="button" data-action="edit-flow-name" data-i18n-title="flow.editName" data-i18n-aria="flow.editName" title="Edit Flow name" aria-label="Edit Flow name">✎</button></div><input id="flowName" maxlength="100" data-i18n-placeholder="flow.namePlaceholder" data-i18n-title="flow.nameAliasHint" placeholder="My automation"></div></div></div>
|
||||
<div class="flow-editor-actions"><button class="secondary" type="button" data-action="flow-templates" data-i18n="flow.templates">Templates</button><button class="secondary" type="button" data-action="import-flow" data-i18n="flow.import">Import</button><button class="secondary" type="button" data-action="export-flow" data-i18n="flow.export">Export</button><button class="secondary" type="button" data-action="flow-dry-run" data-i18n="flow.dryRun">Dry-run</button><button class="secondary" type="button" data-action="flow-logs" data-i18n="flow.logs">Logs</button><label class="flow-enabled"><input type="checkbox" id="flowEnabled" checked><span data-i18n="common.enabled">Enabled</span></label><span id="flowCompileStatus" class="badge"></span><button class="primary" type="button" data-action="save-flow" data-i18n="actions.save">Save</button></div>
|
||||
</header>
|
||||
<div class="flow-editor-body">
|
||||
|
||||
+53
-7
@@ -111,12 +111,48 @@ function flowDraftFrom(flow) {
|
||||
};
|
||||
}
|
||||
|
||||
function flowCurrentName() {
|
||||
const input = $('#flowName');
|
||||
if (input && !input.hidden) return input.value.trim();
|
||||
return String(app.flowDraft?.name || '').trim();
|
||||
}
|
||||
|
||||
function renderFlowNameMode() {
|
||||
const input = $('#flowName'), view = $('#flowNameView'), text = $('#flowNameText');
|
||||
if (!input || !view || !text || !app.flowDraft) return;
|
||||
const name = String(app.flowDraft.name || '').trim();
|
||||
input.value = name; text.textContent = name || tr('flow.newDefaultName');
|
||||
const editing = app.flowNameEditing === true;
|
||||
input.hidden = !editing; view.hidden = editing;
|
||||
}
|
||||
|
||||
function editFlowName({ select = true } = {}) {
|
||||
if (!app.flowDraft) return;
|
||||
app.flowNameEditing = true; renderFlowNameMode();
|
||||
const input = $('#flowName');
|
||||
requestAnimationFrame(() => { input?.focus(); if (select) input?.select(); });
|
||||
}
|
||||
|
||||
function commitFlowName({ keepEditingOnEmpty = true } = {}) {
|
||||
if (!app.flowDraft) return false;
|
||||
const input = $('#flowName'); if (!input) return false;
|
||||
const name = input.value.trim();
|
||||
if (!name) {
|
||||
if (keepEditingOnEmpty) { app.flowNameEditing = true; input.focus(); }
|
||||
return false;
|
||||
}
|
||||
if (app.flowDraft.name !== name) { app.flowDraft.name = name; app.flowDirty = true; }
|
||||
app.flowNameEditing = false; renderFlowNameMode();
|
||||
return true;
|
||||
}
|
||||
|
||||
function openFlowEditor(id = '', { push = true } = {}) {
|
||||
const flow = id ? app.flows.find(item => item.id === id) : null;
|
||||
if (id && !flow) return toast(tr('flow.notFound'), true);
|
||||
app.flowDraft = flowDraftFrom(flow);
|
||||
app.flowSelectedNodeId = null; app.flowSelectedNodeIds = []; app.flowConnectFrom = null; app.flowDirty = false;
|
||||
$('#flowName').value = app.flowDraft.name || '';
|
||||
app.flowNameEditing = !flow;
|
||||
renderFlowNameMode();
|
||||
$('#flowEnabled').checked = app.flowDraft.enabled !== false;
|
||||
$('#flowEditor').hidden = false;
|
||||
document.body.classList.add('flow-editor-open');
|
||||
@@ -129,7 +165,7 @@ function closeFlowEditor({ push = true, force = false } = {}) {
|
||||
if (!force && app.flowDirty && !confirm(tr('confirm.discardChanges'))) return false;
|
||||
stopFlowSharedInputValueRefresh();
|
||||
$('#flowEditor').hidden = true; document.body.classList.remove('flow-editor-open');
|
||||
app.flowDraft = null; app.flowSelectedNodeId = null; app.flowSelectedNodeIds = []; app.flowConnectFrom = null; app.flowDirty = false;
|
||||
app.flowDraft = null; app.flowSelectedNodeId = null; app.flowSelectedNodeIds = []; app.flowConnectFrom = null; app.flowDirty = false; app.flowNameEditing = false;
|
||||
if (push) updateBrowserUrl('/flows');
|
||||
return true;
|
||||
}
|
||||
@@ -324,7 +360,7 @@ function renderFlowEditor() {
|
||||
}).join('');
|
||||
$('#flowEmptyHint').hidden = draft.nodes.length > 0;
|
||||
const selectionCount = $('#flowSelectionCount'); if (selectionCount) selectionCount.textContent = (app.flowSelectedNodeIds || []).length ? tr('flow.selectedCount', { count:(app.flowSelectedNodeIds || []).length }) : '';
|
||||
renderFlowEdges(); renderFlowInspector(); renderFlowInterpretation(); renderFlowRuntimeInfo(); refreshFlowSharedInputCurrentValues();
|
||||
renderFlowNameMode(); renderFlowEdges(); renderFlowInspector(); renderFlowInterpretation(); renderFlowRuntimeInfo(); refreshFlowSharedInputCurrentValues();
|
||||
const status = $('#flowCompileStatus');
|
||||
status.textContent = draft.draft ? tr('flow.draftStatus') : tr('flow.compileCount', { schedules: draft.compiled_schedule_ids?.length || 0, automations: draft.compiled_automation_ids?.length || 0 });
|
||||
status.classList.toggle('flow-draft-badge', draft.draft === true);
|
||||
@@ -526,7 +562,7 @@ function removeFlowEdge(id) {
|
||||
function flowSourcePayload() {
|
||||
if (!app.flowDraft) return null;
|
||||
return {
|
||||
name: ($('#flowName')?.value || app.flowDraft.name || '').trim(),
|
||||
name: flowCurrentName(),
|
||||
enabled: $('#flowEnabled')?.checked !== false,
|
||||
draft: app.flowDraft.draft === true,
|
||||
description: app.flowDraft.description || '',
|
||||
@@ -808,7 +844,7 @@ function applyFlowTemplate(key) {
|
||||
const graph = materializeFlowPreset(preset);
|
||||
app.flowDraft.nodes = graph.nodes; app.flowDraft.edges = graph.edges;
|
||||
app.flowDraft.description = flowPresetText(preset.description); app.flowSelectedNodeId = null; app.flowSelectedNodeIds = []; app.flowDirty = true;
|
||||
if (!app.flowDraft.id || $('#flowName').value === tr('flow.newDefaultName')) $('#flowName').value = flowPresetText(preset.name) || preset.id;
|
||||
if (!app.flowDraft.id || flowCurrentName() === tr('flow.newDefaultName')) { app.flowDraft.name = flowPresetText(preset.name) || preset.id; if (app.flowNameEditing) $('#flowName').value = app.flowDraft.name; renderFlowNameMode(); }
|
||||
markFlowPresetRecent(preset.id);
|
||||
$('#flowTemplateDialog')?.close(); renderFlowEditor();
|
||||
}
|
||||
@@ -906,14 +942,15 @@ async function persistFlowDraft(body) {
|
||||
|
||||
async function applySavedFlow(saved, messageKey) {
|
||||
const index = app.flows.findIndex(flow => flow.id === saved.id); if (index >= 0) app.flows[index] = saved; else app.flows.push(saved);
|
||||
app.flowDraft = flowDraftFrom(saved); app.flowDirty = false;
|
||||
app.flowDraft = flowDraftFrom(saved); app.flowDirty = false; app.flowNameEditing = false;
|
||||
$('#flowEnabled').checked = saved.enabled === true;
|
||||
renderFlows(); renderFlowEditor(); updateBrowserUrl(`/flows/${saved.id}`, true); await loadBootstrap(); toast(tr(messageKey));
|
||||
}
|
||||
|
||||
async function saveFlow() {
|
||||
if (!app.flowDraft) return;
|
||||
const name = $('#flowName').value.trim(); if (!name) return toast(tr('flow.nameRequired'), true);
|
||||
if (app.flowNameEditing && !commitFlowName()) return toast(tr('flow.nameRequired'), true);
|
||||
const name = flowCurrentName(); if (!name) return toast(tr('flow.nameRequired'), true);
|
||||
const body = { name, enabled: $('#flowEnabled').checked, draft: false, description: app.flowDraft.description || '', nodes: app.flowDraft.nodes, edges: app.flowDraft.edges };
|
||||
if (app.flowDraft.id) body.expected_revision = Number(app.flowDraft.revision || 0);
|
||||
try {
|
||||
@@ -1079,6 +1116,7 @@ document.addEventListener('click', event => {
|
||||
else if (action === 'flow-logs') openFlowLogs();
|
||||
else if (action === 'flow-select-all') selectAllFlowNodes();
|
||||
else if (action === 'flow-clear-selection') clearFlowSelection();
|
||||
else if (action === 'edit-flow-name') editFlowName();
|
||||
else if (action === 'flow-shared-input-settings') {
|
||||
if (!showView('homeassistant')) return;
|
||||
requestAnimationFrame(() => {
|
||||
@@ -1097,5 +1135,13 @@ document.addEventListener('change', event => {
|
||||
$('#flowImportFile')?.addEventListener('change', event => importFlowFile(event.target.files?.[0]));
|
||||
$('#flowTemplateSearch')?.addEventListener('input', event => { flowPresetSearch = event.target.value || ''; renderFlowPresetBrowser(flowPresetActiveCategory); });
|
||||
$('#flowName')?.addEventListener('input', () => { if (app.flowDraft) app.flowDirty = true; });
|
||||
$('#flowName')?.addEventListener('keydown', event => {
|
||||
if (event.key === 'Enter') { event.preventDefault(); commitFlowName(); }
|
||||
else if (event.key === 'Escape') { event.preventDefault(); $('#flowName').value = app.flowDraft?.name || ''; app.flowNameEditing = false; renderFlowNameMode(); }
|
||||
});
|
||||
$('#flowName')?.addEventListener('blur', () => {
|
||||
if (!app.flowDraft || !app.flowNameEditing) return;
|
||||
if ($('#flowName').value.trim()) commitFlowName();
|
||||
});
|
||||
$('#flowEnabled')?.addEventListener('change', () => { if (app.flowDraft) app.flowDirty = true; });
|
||||
window.addEventListener('resize', () => { if (!$('#flowEditor')?.hidden) renderFlowEdges(); });
|
||||
|
||||
+9
-1
@@ -6180,7 +6180,15 @@ body.flow-editor-open { overflow:hidden; }
|
||||
.flow-editor-bar { min-height:76px; display:flex; align-items:center; justify-content:space-between; gap:20px; padding:10px 18px; border-bottom:1px solid var(--line); background:var(--surface); }
|
||||
.flow-editor-title { display:flex; align-items:center; gap:12px; min-width:0; }
|
||||
.flow-editor-title > div { display:grid; gap:2px; min-width:0; }
|
||||
.flow-name-wrap { min-width:280px; min-height:36px; display:flex; align-items:center; }
|
||||
.flow-name-view { display:flex; align-items:center; gap:6px; min-width:0; }
|
||||
.flow-name-view[hidden] { display:none !important; }
|
||||
.flow-name-text { appearance:none; border:0; background:transparent; color:var(--text); font:inherit; font-weight:750; font-size:1.12rem; line-height:1.25; padding:4px 2px; min-width:0; max-width:min(52vw,620px); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; cursor:text; text-align:left; }
|
||||
.flow-name-text:hover { color:var(--accent); }
|
||||
.flow-name-edit { appearance:none; border:0; background:transparent; color:var(--muted); width:28px; height:28px; border-radius:7px; padding:0; cursor:pointer; display:grid; place-items:center; opacity:.62; transition:opacity .15s ease,background .15s ease,color .15s ease; }
|
||||
.flow-name-view:hover .flow-name-edit,.flow-name-edit:focus-visible { opacity:1; color:var(--accent); background:var(--accent-soft); outline:none; }
|
||||
.flow-editor-title input { border:1px solid var(--line-strong); background:var(--input-bg); color:var(--text); font-weight:750; font-size:1.12rem; padding:7px 10px; min-width:280px; outline:none; border-radius:9px; box-shadow:inset 0 0 0 1px transparent; transition:border-color .15s ease,box-shadow .15s ease,background .15s ease; }
|
||||
.flow-editor-title input[hidden] { display:none !important; }
|
||||
.flow-editor-title input:hover { border-color:var(--accent-border); background:var(--surface-2); }
|
||||
.flow-editor-title input:focus { border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); background:var(--input-bg); }
|
||||
.flow-draft-badge { border-color:var(--orange); background:color-mix(in srgb,var(--orange) 14%,var(--surface)); color:var(--text); }
|
||||
@@ -6236,7 +6244,7 @@ body.flow-editor-open { overflow:hidden; }
|
||||
|
||||
@media (max-width: 980px) {
|
||||
.flow-editor-body { grid-template-columns:180px minmax(360px,1fr) 260px; }
|
||||
.flow-editor-title input { min-width:180px; }
|
||||
.flow-name-wrap,.flow-editor-title input { min-width:180px; }
|
||||
}
|
||||
@media (max-width: 760px) {
|
||||
.flow-editor-bar { align-items:flex-start; flex-direction:column; }
|
||||
|
||||
Reference in New Issue
Block a user