feat(mgc): consume shared icon-picker visuals + modernize editor menu
* compact-fields.js (new): trimmed to MGC-only output-format pickers (processOutputFormat / dbaseOutputFormat). The logger toggle/level and physical-position visuals now come from generalFunctions' shared iconHelpers, auto-injected via /machineGroupControl/menu.js. * mode-cards.js: strategy cards re-styled — Most-efficient (BEP bell with dot on the curve peak), Priority (clean staircase), Maintenance (Font Awesome fa-wrench). Rendezvous toggle flips Active / Inactive label dynamically. * mgc.html: dropped the duplicated .mgc-icon-* CSS rules (now live in the shared iconHelpers stylesheet). Strategy + rendezvous CSS stays local (MGC-specific). Output picker holders switched to the shared .evolv-icon-picker class. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
84
mgc.html
84
mgc.html
@@ -15,24 +15,41 @@
|
||||
dependency order: index.js (namespace + helpers) → modules → oneditprepare. -->
|
||||
<script src="/machineGroupControl/editor/index.js"></script>
|
||||
<script src="/machineGroupControl/editor/mode-cards.js"></script>
|
||||
<script src="/machineGroupControl/editor/compact-fields.js"></script>
|
||||
<script src="/machineGroupControl/editor/oneditprepare.js"></script>
|
||||
|
||||
<style>
|
||||
/* Mode-card picker. Three cards stack horizontally; on a narrow editor pane
|
||||
they wrap. Selected card gets a thick #50a8d9 (Unit-colour) border. */
|
||||
.mgc-mode-cards { display:flex; gap:8px; flex-wrap:wrap; margin:6px 0 4px 0; }
|
||||
.mgc-mode-card {
|
||||
flex:1 1 0; min-width:140px; box-sizing:border-box;
|
||||
/* MGC-specific UI: strategy mode cards + rendezvous toggle.
|
||||
Generic .evolv-icon-picker / .evolv-icon-option styles for the
|
||||
output-format pickers come from generalFunctions' iconHelpers (auto-
|
||||
injected by /menu.js). */
|
||||
.mgc-mode-cards,
|
||||
.mgc-toggle-row { display:flex; gap:6px; flex-wrap:wrap; margin:6px 0 4px 0; }
|
||||
.mgc-mode-card,
|
||||
.mgc-toggle-card {
|
||||
width:94px; height:86px; box-sizing:border-box;
|
||||
border:2px solid #d0d0d0; border-radius:4px; background:#fafafa;
|
||||
padding:6px 8px 8px 8px; cursor:pointer; user-select:none;
|
||||
display:flex; flex-direction:column; gap:4px;
|
||||
padding:4px; cursor:pointer; user-select:none;
|
||||
display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px;
|
||||
transition:border-color 80ms ease-out, background 80ms ease-out;
|
||||
}
|
||||
.mgc-mode-card:hover { border-color:#86bbdd; background:#f5fafd; }
|
||||
.mgc-mode-card-on { border-color:#50a8d9; background:#eaf4fb; }
|
||||
.mgc-mode-card-svg svg { width:100%; height:auto; max-height:90px; display:block; }
|
||||
.mgc-mode-card-label { font-weight:600; font-size:12px; color:#333; }
|
||||
.mgc-mode-card-caption { font-size:10px; color:#666; line-height:1.3; }
|
||||
.mgc-mode-card:hover,
|
||||
.mgc-toggle-card:hover { border-color:#86bbdd; background:#f5fafd; }
|
||||
.mgc-mode-card:focus,
|
||||
.mgc-toggle-card:focus { outline:2px solid #1F4E79; outline-offset:2px; }
|
||||
.mgc-mode-card-on,
|
||||
.mgc-toggle-card-on { border-color:#50a8d9; background:#eaf4fb; }
|
||||
.mgc-mode-card-svg,
|
||||
.mgc-toggle-card-svg { width:100%; height:54px; display:flex; align-items:center; justify-content:center; }
|
||||
.mgc-mode-card-svg svg,
|
||||
.mgc-toggle-card-svg svg { width:100%; height:100%; display:block; }
|
||||
.mgc-mode-card-label,
|
||||
.mgc-toggle-card-label { font-size:10px; line-height:1; font-weight:600; color:#333; white-space:nowrap; letter-spacing:0; }
|
||||
.mgc-toggle-card:not(.mgc-toggle-card-on) .mgc-toggle-card-svg { opacity:0.45; filter:grayscale(1); }
|
||||
.mgc-toggle-card:not(.mgc-toggle-card-on) .mgc-toggle-card-label { color:#888; }
|
||||
.mgc-hidden-checkbox { position:absolute; opacity:0; width:1px; height:1px; pointer-events:none; }
|
||||
.mgc-section-divider { border:0; border-top:1px solid #d6d6d6; margin:12px 0; }
|
||||
.mgc-output-row > label { white-space:nowrap; width:130px; }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@@ -89,7 +106,7 @@
|
||||
// Initialize the menu data for the node, then the visual modules.
|
||||
// Both attach to window.EVOLV.nodes.machineGroupControl.* — the
|
||||
// menu endpoint populates loggerMenu/positionMenu/initEditor; the
|
||||
// editor scripts populate editor.modeCards/demandContract.
|
||||
// editor scripts populate editor.modeCards/rendezvousToggle/compactFields.
|
||||
const waitForMenuData = () => {
|
||||
if (window.EVOLV?.nodes?.machineGroupControl?.initEditor) {
|
||||
window.EVOLV.nodes.machineGroupControl.initEditor(self);
|
||||
@@ -133,48 +150,39 @@
|
||||
role="radiogroup" aria-label="Control strategy mode">
|
||||
<!-- mode-cards.js renders three card divs here -->
|
||||
</div>
|
||||
|
||||
<p style="margin-top:8px;color:#666;font-size:11px;">
|
||||
Demand is self-describing per <code>set.demand</code> message: a bare number is
|
||||
treated as % of group capacity; <code>{value, unit}</code> with a flow unit
|
||||
(<code>m3/h</code>, <code>l/s</code>, <code>m3/s</code>, …) is dispatched
|
||||
in absolute terms. Negative value stops all pumps.
|
||||
</p>
|
||||
<hr class="mgc-section-divider" />
|
||||
|
||||
<h3>Rendezvous planner</h3>
|
||||
<div class="form-row" style="display:flex;align-items:center;gap:8px;">
|
||||
<input type="checkbox" id="node-input-useRendezvous"
|
||||
style="width:auto;margin:0;vertical-align:middle;" />
|
||||
<label for="node-input-useRendezvous" style="width:auto;margin:0;cursor:pointer;">
|
||||
Same-time landing
|
||||
</label>
|
||||
<div class="form-row mgc-toggle-row">
|
||||
<input type="checkbox" id="node-input-useRendezvous" class="mgc-hidden-checkbox" />
|
||||
<div id="mgc-rendezvous-toggle" class="mgc-toggle-card"
|
||||
role="switch" tabindex="0" aria-label="Same-time landing"
|
||||
aria-checked="false" title="Same-time landing"></div>
|
||||
</div>
|
||||
<p style="margin-top:4px;color:#666;font-size:11px;">
|
||||
When enabled (default), every dispatch is routed through the rendezvous
|
||||
planner regardless of control strategy: per-pump moves are delayed so all
|
||||
pumps reach their setpoint at the same wall-clock instant
|
||||
<code>t* = max(eta<sub>i</sub>)</code>. When disabled, every
|
||||
<code>flowmovement</code> fires immediately and each pump ramps at its
|
||||
own configured reaction speed (legacy behaviour).
|
||||
</p>
|
||||
<hr class="mgc-section-divider" />
|
||||
|
||||
<h3>Output Formats</h3>
|
||||
<div class="form-row">
|
||||
<div class="form-row mgc-output-row">
|
||||
<label for="node-input-processOutputFormat"><i class="fa fa-random"></i> Process Output</label>
|
||||
<select id="node-input-processOutputFormat" style="width:60%;">
|
||||
<select id="node-input-processOutputFormat" class="evolv-native-hidden" style="width:60%;">
|
||||
<option value="process">process</option>
|
||||
<option value="json">json</option>
|
||||
<option value="csv">csv</option>
|
||||
</select>
|
||||
<div id="mgc-process-output-picker" class="evolv-icon-picker"
|
||||
role="radiogroup" aria-label="Process output format"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-row mgc-output-row">
|
||||
<label for="node-input-dbaseOutputFormat"><i class="fa fa-database"></i> Database Output</label>
|
||||
<select id="node-input-dbaseOutputFormat" style="width:60%;">
|
||||
<select id="node-input-dbaseOutputFormat" class="evolv-native-hidden" style="width:60%;">
|
||||
<option value="influxdb">influxdb</option>
|
||||
<option value="json">json</option>
|
||||
<option value="csv">csv</option>
|
||||
</select>
|
||||
<div id="mgc-dbase-output-picker" class="evolv-icon-picker"
|
||||
role="radiogroup" aria-label="Database output format"></div>
|
||||
</div>
|
||||
<hr class="mgc-section-divider" />
|
||||
|
||||
<!-- Logger fields injected here -->
|
||||
<div id="logger-fields-placeholder"></div>
|
||||
|
||||
Reference in New Issue
Block a user