deploy.
This commit is contained in:
@@ -87,7 +87,7 @@
|
||||
<article data-uid="Anatomy-ExecutionToolBar">
|
||||
<h1 id="execution-tool-bar">Execution Tool Bar</h1>
|
||||
|
||||
<p>The transport controls for the run. In the web application they sit atop the <a href="index.html">Execution Page</a>'s primary editor panel, shown for the Execution root and every node under it, and this sole instance registers the F5–F8 shortcuts.</p>
|
||||
<p>The transport controls for the run. In the web application they sit in the run header of the <a href="index.html">Execution Page</a>'s Control Tree pane — pinned above the tree, beside the run-state badge, on the Execution page only — and this sole instance registers the F5–F8 shortcuts.</p>
|
||||
<h2 id="layout">Layout</h2>
|
||||
<ul>
|
||||
<li><code>Execution Tool Bar</code>
|
||||
@@ -102,17 +102,19 @@
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>In the web application the status text moved out of the tool bar and onto the Execution tree item, which carries the run-state badge. The two single-advance buttons there share one <code>skip_next</code> icon and are separated by a letter drawn into the button's corner — <code>L</code> for the line button, <code>S</code> for the step button — rather than by colour; the tool-tips carry the key names.</p>
|
||||
<p>In the web application the status text is a run-state badge to the right of the button strip; the two share the Control Tree pane's run header, and when the tree column is narrowed the button strip scrolls while the badge keeps its width, so the run state is the last thing a resize hides. The two single-advance buttons share one <code>skip_next</code> icon and are separated by a letter drawn into the button's corner — <code>L</code> for the line button, <code>S</code> for the step button — rather than by colour; the tool-tips carry the key names.</p>
|
||||
<h2 id="behavior">Behavior</h2>
|
||||
<ul>
|
||||
<li>The webservice watches <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events to track <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer">PacePlayer</a> status changes.</li>
|
||||
<li>In the webservice, <code>ExecutionStatusService</code> subscribes to those events and broadcasts status changes over SignalR through <code>ExecutionStatusHub</code>.</li>
|
||||
<li>The frequently used buttons carry hotkeys: Start / Resume, Pause, Run One Line and Run One Step. The app's tool-tips are the only place those key bindings are written down.</li>
|
||||
<li>The background color of the <code>Status Text Field</code> follows the status:
|
||||
<li>The badge reads the status in lower case (<code>ready</code>, <code>running</code>, <code>paused</code>, <code>finished</code>, <code>no project</code>, <code>error</code>), and the background color of the <code>Status Text Field</code> follows it:
|
||||
<ul>
|
||||
<li>Warning style — Running</li>
|
||||
<li>Secondary style — Paused, No Project</li>
|
||||
<li>Success style — Finished, Ready</li>
|
||||
<li>Warning (amber) — Running</li>
|
||||
<li>Orange — Paused</li>
|
||||
<li>Positive (green) — Finished, Ready</li>
|
||||
<li>Negative (red) — Error</li>
|
||||
<li>Grey — No Project, and any status the client has no label for (its raw name is shown)</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -150,7 +152,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<p><strong>Neither single-advance button is enabled while the run is <code>Running</code></strong> — stepping is a <code>Ready</code>-or-<code>Paused</code> operation, so a moving run has to be paused before it can be stepped.</p>
|
||||
<p>The F5–F8 handler applies the same predicates before acting, and declines in two more cases: when the event target is an <code>input</code>, a <code>textarea</code> or a contenteditable element, and when the hosting page is deactivated. The second matters because the shell keep-alives the routed pages, so leaving the Execution route deactivates rather than unmounts this component; without the detach, F5 elsewhere in the app would drive the transport instead of reloading the browser. Every declined key falls through to the browser.</p>
|
||||
<p>The F5–F8 handler applies the same predicates before acting, and declines in two more cases: when the event target is an <code>input</code>, a <code>textarea</code> or a contenteditable element, and when the hosting page is deactivated. The second matters because the shell keep-alives the routed pages, so leaving the Execution route deactivates rather than unmounts this component; without the detach, F5 elsewhere in the app would drive the transport instead of reloading the browser. Collapsing the Control Tree row does not detach it: the dock keeps the tree pane mounted through a collapse. Every declined key falls through to the browser.</p>
|
||||
<div class="TIP">
|
||||
<h5>Tip</h5>
|
||||
<p>Use icons rather than text on the tool-bar buttons. Run One Line and Run One Step share an icon, so they need a second mark to tell them apart — this bar draws an <code>L</code> and an <code>S</code> in the button corner. The default colour is enough for the rest.</p>
|
||||
@@ -160,6 +162,9 @@
|
||||
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/execution/ExecutionToolBar.vue</code> — the buttons. All state and handlers come from the shared <code>useExecutionTransport</code> composable, so the component is pure markup.</li>
|
||||
<li><code>wwwroot-src/src/composables/useExecutionTransport.ts</code> — the enable rules, the API-calling handlers and the F5–F8 listener; the shared reset-in-flight flag lives here.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the Control Tree pane; its run header mounts the bar beside the run-state badge on the Execution page only, with the badge unshrinkable and the button strip the part that scrolls.</li>
|
||||
<li><code>wwwroot-src/src/utils/executionStatusPresent.ts</code> — the badge's label and color per status.</li>
|
||||
<li><code>Execution/ExecutionController.cs</code> — <code>POST /api/Execution/start | pause | resume | run-line | run-step | stop | reset</code>, and <code>GET /api/Execution/status</code>.</li>
|
||||
<li><code>Execution/ExecutionStatusHub.cs</code> + <code>Execution/ExecutionStatusService.cs</code> — the status broadcast.</li>
|
||||
</ul>
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
<article data-uid="Anatomy-Execution">
|
||||
<h1 id="execution-page">Execution Page</h1>
|
||||
|
||||
<p>The Execution page is the run cockpit: the simulation plays here, and every panel on it reads the run. It is the app's landing route — <code>/</code> redirects to <code>/execution</code> — and its Control Tree, the <strong>Execution</strong> root with <strong>Mission</strong> and <strong>Program</strong> beneath it, rides the <code>?tree=</code> query, so <code>/execution?tree=execution/mission</code> deep-links the Mission editor.</p>
|
||||
<p>The Execution page is the run cockpit: the simulation plays here, and every panel on it reads the run. It is the app's landing route — <code>/</code> redirects to <code>/execution</code> — and its Control Tree — two roots, <strong>Mission</strong> above <strong>Program</strong> — rides the <code>?tree=</code> query, so <code>/execution?tree=execution/mission</code> deep-links the Mission editor.</p>
|
||||
<div class="NOTE">
|
||||
<h5>Note</h5>
|
||||
<p>The app says <strong>Execution</strong> throughout: the route <code>/execution</code>, the REST endpoints (<code>/api/Execution/*</code>), the status hub (<code>/executionStatusHub</code>) and the stored layout (<code>UserConfig.ExecutionDivConfig</code>). The HiAPI engine keeps its own library vocabulary — <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> <small>(API)</small> and <a class="xref" href="../../api/Hi.Common.PacePlayer.html">PacePlayer</a> <small>(API)</small> — which is a different codebase's naming, not an inconsistency here.</p>
|
||||
@@ -101,16 +101,16 @@
|
||||
<h2 id="layout">Layout</h2>
|
||||
<p>Four columns, left to right. The two dock dividers are pixel-sized, so dragging one moves only that dock's edge while the flexible middle absorbs the change.</p>
|
||||
<ul>
|
||||
<li><strong>Left dock</strong> — the Control Tree over the primary editor panel for the selected tree node. The <a href="execution-tool-bar.html">Execution Tool Bar</a> — the transport buttons — sits atop that panel and is shown for the Execution root and every node under it.</li>
|
||||
<li><strong>Left dock</strong> — the Control Tree over the primary editor panel for the selected tree node. The tree pane opens with a run header pinned above its rows: the <a href="execution-tool-bar.html">Execution Tool Bar</a> — the transport buttons — with the live status badge to its right. The editor panel below holds the editor alone.</li>
|
||||
<li><strong>Main</strong> — the <a class="xref" href="../../technique/rendering/rendering-canvas.html">RenderingCanvas</a> over the <a class="xref" href="../shell/session-message-panel.html">Session Message Panel</a>, stacked as collapsible panels with a draggable divider between them. The canvas panel's header adopts the <a class="xref" href="../widget/renderingcanvas-tool-bar.html">RenderingCanvas Tool Bar</a> and the <a href="execution-extended-renderingcanvas-tool-bar.html">Execution Extended RenderingCanvas Tool Bar</a>.</li>
|
||||
<li><strong>Strip Charts</strong> — the strip-chart group bar over the three <a href="strip-charts.html">Strip Charts</a>: Availability Chart, Surface Roughness Chart and Color Index Time Chart.</li>
|
||||
<li><strong>Step Info</strong> — <em>Sentence Syntax</em> as its own region (an NC sentence need not map to any machining step, so it is not a member of the step-based panels), then the Step Info group bar, then <a href="selected-step-info-panel.html">Step Properties</a>, <em>CWE</em> (cutter–workpiece engagement) and the four <a href="cycle-line-charts.html">Cycle-Line Charts</a>.</li>
|
||||
</ul>
|
||||
<p>The four columns are toggled from the app menu bar; the panels inside them collapse in place from their own expansion headers. The canvas stays mounted while collapsed so its rendering connection survives, and its engine is paused rather than torn down. The page itself also stays mounted while the user is on another route: the shell wraps the router view in a <code>keep-alive</code> keyed on the project epoch, so navigating away pauses the canvas but keeps the page — and its connection — alive until the loaded project changes.</p>
|
||||
<h2 id="control-tree">Control Tree</h2>
|
||||
<p>The page hosts an <code>execution</code>-scoped Control Tree: an <strong>Execution</strong> root with the <strong>Mission</strong> branch above the <strong>Program</strong> branch. Selecting a node fills the primary editor pane below the tree, and the <a href="execution-tool-bar.html">Execution Tool Bar</a> is mounted on top of that pane whenever the selected id is <code>execution</code> or starts with <code>execution/</code> — so the transport stays reachable from every node of this tree.</p>
|
||||
<p><strong>Execution root</strong> is the cockpit's home: a short orientation panel, because the controls it would otherwise hold live where they act — the transport on the primary pane's header, the panel switches on each panel's own expansion header, the column switches on the nav bar. The live run state rides the tree itself: the Execution tree item carries a status badge fed by <code>/executionStatusHub</code>.</p>
|
||||
<p><strong>Mission</strong> (<code>execution/mission</code>) is the editable command list a run executes — the project's <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> <small>(API)</small>, always a list, with nested lists read as sub-trees. Its ItemType registry supplies the tree checkbox that decides whether a command runs. The branch root is the entry-list editor — Add Command over a drag-reorderable row list with up / down / duplicate / delete — each command entry gets a control bar over that kind's own editor, and each of the kind's remaining setting groups becomes a section child of the command node. Every command type has its own page under <a href="mission/index.html">Mission</a>.</p>
|
||||
<p>The page hosts an <code>execution</code>-scoped Control Tree with two roots and no wrapper node over them: the <strong>Mission</strong> branch above the <strong>Program</strong> branch. Node ids keep the <code>execution/</code> prefix (<code>execution/mission</code>, <code>execution/program/…</code>) because that first segment is the page-scope key — <code>?tree=</code> routing and the remembered last selection hang off it — not a parent row; a bare <code>?tree=execution</code> resolves to <code>execution/mission</code>, and a URL with no <code>?tree=</code> lands on the remembered selection or, failing that, on Mission. Selecting a node fills the primary editor pane below the tree; that pane holds nothing but the selected node's editor.</p>
|
||||
<p><strong>Run header.</strong> The tree pane opens, on this page only, with a row pinned above the tree scroller: the <a href="execution-tool-bar.html">Execution Tool Bar</a> — the page's sole transport, which therefore owns the F5–F8 shortcuts — and, to its right, the status badge fed by <code>/executionStatusHub</code>. It sits inside the pane rather than on the dock's expansion header because that header is shared with General Setup, which renders neither piece. The button strip is the only shrinkable child, so narrowing the tree column scrolls the buttons away while the badge stays in view; the dock keeps the tree row mounted while collapsed, so the transport and its shortcuts survive a collapsed row. The other controls the cockpit needs live where they act — the panel switches on each panel's own expansion header, the column switches on the app menu bar.</p>
|
||||
<p><strong>Mission</strong> (<code>execution/mission</code>) is the editable command list a run executes — the project's <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> <small>(API)</small>, always a list, with nested lists read as sub-trees. Its ItemType registry supplies the tree checkbox that decides whether a command runs. Every row-level structural op lives on the tree rows, not in a panel: each command row carries a drag handle and — revealed on hover and on the selected row — move up / move down / duplicate / delete; every list row, the Mission root included, carries an always-visible <strong>+</strong> (Add Command) that opens the command catalog and inserts the pick right after that list's focused command (the last selected or last added), else at the list's tail. The one panel-side insert is the Program File editor's <a href="mission/NcFileCommand-panel.html#multi-pick-fan-out">multi-pick fan-out</a>: each extra pick becomes a new Program File command right after that command in its own list, and the panel reports the insert range to the host, which treats it as a structural op like any row op — the same busy gate, the same carry-over of index-based ids onto the new siblings, the same rebuild scoped to the owning list. Dropping a dragged row on another command row's edge reorders it within its list or relocates it into the target row's list; dropping on a List row's middle band or on the Mission root row appends it into that list. The host runs all five ops through one path — a busy gate that holds tree selection, the checkboxes and further drags read-only while an op is in flight; the open editor's dirty-switch gate, which can refuse the op: a Script Command with unsaved edits asks <strong>Save & switch</strong> / <strong>Discard</strong> / <strong>Cancel</strong>, while an NC Code editor or a List title sends its pending save without asking, and either one answers no when the user cancels or the save does not land — a refused gate drops the op and toasts that the open editor keeps its unsaved edits, which is why a delete that was already confirmed can still leave its row in place; then the API call, a rebuild scoped to the list it rewrote (the nearest list above both, for a move across lists), then the selection. The selection moves only when it already rode on the acted-on row — that row, or a section or nested entry under it: it follows a moved command, lands on the clone of a duplicated one, and after a delete lands on the nearest surviving entry of that list or, once the list is empty, on the owning list row; a selection riding elsewhere stays on its own re-indexed row, and Add Command never moves it at all — only the Add focus moves, onto the new row, so a run of adds chains in order. The root's own panel is informational — what the tree cannot say: a no-project note while no project is loaded, otherwise the command count and, while it is zero, a prompt to click Add Command; the run-order hint closes it either way. A command node's panel is that kind's own editor (a List shows only its optional Title; its entries are its tree children), and each of the kind's remaining setting groups becomes a section child of the command node. Every command type has its own page under <a href="mission/index.html">Mission</a>.</p>
|
||||
<p><strong>Program</strong> (<code>execution/program</code>) is the read-only inspection twin of Mission: one node per NC source file the session read, its passes and execution marks filled in from run data rather than typed in. Its nodes, its per-pass line and mark views, and the status changes that rebuild it are on <a href="program.html">Program Branch</a>.</p>
|
||||
<p>Selection and URL are synced two ways through the <code>tree</code> query argument: the URL's <code>?tree=</code> is adopted once the tree is built, and every selection change replaces it. A <code>?tree=</code> id belonging to another page's tree redirects to that page (<code>routeForTreeId</code>), and <code>/mission</code> lands on <code>/execution?tree=execution/mission</code>.</p>
|
||||
<h2 id="renderingcanvas-behavior">RenderingCanvas Behavior</h2>
|
||||
@@ -129,18 +129,19 @@
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/pages/ExecutionPage.vue</code> — the routed page at <code>/execution</code>: the four columns, their pixel / ratio splitters, the panel-expansion stacks, and the <code>execution</code>-scoped Control Tree host it provides.</li>
|
||||
<li><code>wwwroot-src/src/router/routes.ts</code> — the <code>/</code> → <code>execution</code> redirect, the <code>execution</code> route, and the <code>/mission</code> redirect to <code>/execution?tree=execution/mission</code>.</li>
|
||||
<li><code>wwwroot-src/src/router/treeRoutes.ts</code> — <code>routeForTreeId</code>, which lands a <code>?tree=</code> id on the page that owns that branch.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the Control Tree state machine: <code>buildExecutionRoot()</code> builds the <code>execution</code> root holding <code>execution/mission</code> above <code>execution/program</code>, syncs <code>?tree=</code>, and re-reads the Program branch whenever the broadcast execution status changes.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreeDock.vue</code> — the left dock: the Control Tree row over the primary editor row.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree pane; carries the live execution-status badge on the Execution tree item.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — the primary editor pane for the selected node; mounts the Execution Tool Bar on top whenever the selection is <code>execution</code> or a descendant.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ExecutionRootPanel.vue</code> — the editor panel of the Execution root node.</li>
|
||||
<li><code>wwwroot-src/src/router/treeRoutes.ts</code> — <code>migrateLegacyTreeId</code>, which folds legacy ids onto the current ones (a bare <code>execution</code> becomes <code>execution/mission</code>), and <code>routeForTreeId</code>, which runs that migration first and then lands a <code>?tree=</code> id on the page that owns its first segment.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the Control Tree state machine: <code>buildExecutionRoots()</code> builds the two roots, <code>execution/mission</code> above <code>execution/program</code>; <code>landingSelection()</code> picks the remembered selection or the first root; the <code>?tree=</code> sync; the Program branch re-read on every broadcast execution-status change; and the five mission row ops — add, drag move, step, duplicate, delete — through one <code>missionRowOp</code> helper that owns the busy gate, the dirty-switch gate (a refusal drops the op and toasts it), the scoped rebuild and the post-op selection.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useMissionTreeDrag.ts</code> — the HTML5 drag-and-drop bookkeeping between Mission rows: the edge / into drop modes and the row indicator classes; the move itself is the host's.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreeDock.vue</code> — the left dock: the Control Tree row over the primary editor row, each kept mounted while collapsed; the tree row's expansion header is the same on both tree pages, so nothing run-specific rides it.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree pane; on the Execution page it pins the run header — the Execution Tool Bar and the live status badge — above the tree scroller, and renders the Mission rows' drag handle, the hover-revealed row ops and the Add Command <strong>+</strong> on every list row.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first command catalog the <strong>+</strong> opens, fed by <code>GET /api/Mission/command-catalog</code>; one pick per opening.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — the primary editor pane shared by both tree pages: it mounts the selected node's registry panel, or one of the three inline root panels it carries for General Setup's equipment roots (Machine Tool, Fixture, Workpiece — object management plus a summary), which no Execution node ever selects; here it shows the registry panel alone, and hands that panel's dirty-switch gate to the host.</li>
|
||||
</ul>
|
||||
<p>Mission branch:</p>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — the branch's ItemType registry and the per-command enable ticks.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — the entry-list editor of a list command, serving the branch root and every nested list.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the per-command editor host.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — the Mission root's informational panel: a no-project note while no project is loaded, otherwise the command count and a “No commands yet” prompt while it is zero, and the run-order hint in every state.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the per-command editor host; a List command shows only its optional Title.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionSectionPanel.vue</code> — one setting section of a command.</li>
|
||||
</ul>
|
||||
<p>Program branch (see the dedicated anatomy page for details):</p>
|
||||
@@ -150,7 +151,7 @@
|
||||
<p>Panels and canvas:</p>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/RenderingCanvas.vue</code> — the browser canvas and its <code>/renderingHub</code> connection.</li>
|
||||
<li><code>wwwroot-src/src/components/execution/ExecutionToolBar.vue</code> — the transport controls.</li>
|
||||
<li><code>wwwroot-src/src/components/execution/ExecutionToolBar.vue</code> — the transport controls; the page's one instance, mounted in the tree pane's run header, registers F5–F8.</li>
|
||||
<li><code>wwwroot-src/src/components/execution/ExecutionExtendedToolBar.vue</code> — the view and rendering-flag controls adopted onto the canvas panel's header.</li>
|
||||
<li><code>wwwroot-src/src/components/execution/SelectedStepInfoPanel.vue</code> — Step Properties.</li>
|
||||
<li><code>wwwroot-src/src/components/execution/StepVolumePanel.vue</code> — the CWE panel.</li>
|
||||
@@ -173,7 +174,7 @@
|
||||
<p>Backends:</p>
|
||||
<ul>
|
||||
<li><code>Execution/ExecutionController.cs</code> — <code>POST /api/Execution/start | pause | resume | run-line | run-step | stop | reset</code>; <code>GET status</code>, <code>status/{connectionId}</code>, <code>project-status</code>, <code>selected-step-info</code> and <code>cl-strip-dots</code>; the canvas actions <code>initialize/{connectionId}</code> (binds the displayee and calls <code>SetViewToHomeView</code>) and <code>fit-view/{connectionId}</code>; and the <code>step-volume/{connectionId}</code> family behind the CWE panel.</li>
|
||||
<li><code>Execution/ExecutionStatusHub.cs</code> + <code>Execution/ExecutionStatusService.cs</code> — <code>/executionStatusHub</code>, the run-state broadcast that drives the transport and the tree badge.</li>
|
||||
<li><code>Execution/ExecutionStatusHub.cs</code> + <code>Execution/ExecutionStatusService.cs</code> — <code>/executionStatusHub</code>, the run-state broadcast that drives the transport and the run header's badge.</li>
|
||||
<li><code>Execution/SessionSinkHub.cs</code> + <code>Execution/SessionSinkBroadcastService.cs</code> — one hub per message sink (<code>/shellMessageHub</code>, <code>/ncDiagnosticHub</code>, <code>/stepDiagnosticHub</code>, <code>/ncManipulationDiagnosticHub</code>), so a client subscribes to exactly the sink it wants.</li>
|
||||
<li><code>Execution/SelectedStepInfoService.cs</code> — the selected-step payload. It has no hub of its own: the “selection changed” push rides <code>/clStripHub</code>.</li>
|
||||
<li><code>Execution/ClStripController.cs</code> + <code>Execution/ClStripHub.cs</code> + <code>Execution/ClStripBroadcastService.cs</code> — CL-strip range state and the zoom / pan / select / enter broadcasts.</li>
|
||||
@@ -197,10 +198,10 @@
|
||||
</ol>
|
||||
</div>
|
||||
<h2 id="pages">Pages</h2>
|
||||
<p>Ordered as the cockpit reads: the two tool bars across the top, the step column and the charts down
|
||||
the side, the menus and dialogs they open, then the Control-Tree branch the page hosts.</p>
|
||||
<p>Ordered as the cockpit reads: the two tool bars — the transport pinned in the Control Tree pane's run header, the extended controls on the canvas panel's header — then the step column and the charts down
|
||||
the side, the menus and dialogs they open, then the two Control-Tree branches the page hosts.</p>
|
||||
<ul>
|
||||
<li><a href="execution-tool-bar.html">Execution Tool Bar</a> — The transport controls on the primary panel header, and the status they read</li>
|
||||
<li><a href="execution-tool-bar.html">Execution Tool Bar</a> — The transport controls in the Control Tree pane's run header, and the status they read</li>
|
||||
<li><a href="execution-extended-renderingcanvas-tool-bar.html">Execution Extended RenderingCanvas Tool Bar</a> — The run-specific canvas controls: the CL strip, fit view and the Scene menu</li>
|
||||
<li><a href="selected-step-info-panel.html">Selected-Step Info Panel</a> — The Step Properties panel in the Step Info column</li>
|
||||
<li><a href="strip-charts.html">Strip Charts</a> — The whole-program charts in the Strip Charts column</li>
|
||||
|
||||
@@ -94,11 +94,12 @@ with everything nested under it — the wrapper yields nothing while its flag is
|
||||
own command is always a list, so the <a class="xref" href="mission-root-panel.html">Mission branch root</a> <em>is</em> a
|
||||
list, and every nested one is the same shape one level down.</p>
|
||||
<p><code>List</code> is an ordinary catalog kind — category Flow — so a list is added the way any command is, and
|
||||
adding one grows a sub-tree: the node's children are its own entries, and its panel embeds the same
|
||||
entry-list editor the branch root uses, scoped to the nested list.</p>
|
||||
adding one grows a sub-tree: the node's children are its own entries, edited on their own Control
|
||||
Tree rows, and the list's own panel holds only its optional title, beneath the Disabled Caption
|
||||
while the command is unticked.</p>
|
||||
<p>This page covers what a list is, how its title reads, and what moving commands in and out of one
|
||||
costs. The entry-list editor itself — Add Command, the row actions, the three drag landings — is
|
||||
documented once, on <a class="xref" href="mission-root-panel.html">Mission Root Panel</a>.</p>
|
||||
costs. The Control Tree row affordances every list shares — Add Command, the row buttons, the three
|
||||
drag landings — are documented once, on <a class="xref" href="mission-root-panel.html">Mission Root Panel</a>.</p>
|
||||
<h2 id="key-models">Key Models</h2>
|
||||
<ul>
|
||||
<li><strong>Primary</strong>: <a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a> — <a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html#Hi_SessionCommands_ListCommand_Title">Title</a>
|
||||
@@ -121,72 +122,92 @@ and <a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html#Hi_Se
|
||||
<ul>
|
||||
<li>List Entry Panel
|
||||
<ul>
|
||||
<li>Control Bar
|
||||
<li>Disabled Caption
|
||||
<ul>
|
||||
<li>Up / Down / Duplicate / Delete — labelled buttons for the operations that rewrite the
|
||||
<strong>parent</strong> list. Delete asks for confirmation in a dialog naming the command.</li>
|
||||
<li>At the bar's left, a caption while the command is disabled: skipped during play, still
|
||||
editable.</li>
|
||||
<li>Present only while the command is disabled: skipped during play, still editable.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Title (optional) Input</li>
|
||||
<li>Embedded Entry-List Editor
|
||||
<ul>
|
||||
<li>This list's own entries, scoped to the node's path.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>The Title input holds the <strong>raw</strong> title — empty when unset — while the label the row and the tree
|
||||
show is composed by the engine: <code>List</code> when the title is blank, <code>List [title]</code> when it is not. A
|
||||
<p>Nothing else is on the panel. The list's entries are the node's children in the tree, and the
|
||||
operations that rewrite the <strong>parent</strong> list — Move up, Move down, Duplicate, Delete — are the
|
||||
buttons on the list's own tree row, revealed on hover and on the selected row, and always shown on
|
||||
a touch or pen device, where there is no hover; Delete asks for confirmation in a dialog naming the
|
||||
command. The <code>+</code> on that row adds a command into this list.</p>
|
||||
<p>The Title input holds the <strong>raw</strong> title — empty when unset — while the label the tree row shows is
|
||||
composed by the engine: <code>List</code> when the title is blank, <code>List [title]</code> when it is not. A
|
||||
titled list still says what it is. A whitespace-only title counts as unset and is never written into
|
||||
the project file, so it cannot come back as a changed title on the next load.</p>
|
||||
<p>Keystrokes debounce into one title save. The pending save is flushed before anything that shifts the
|
||||
entry paths — a structural operation, a duplicate, a selection change — and cancelled on delete and
|
||||
on unmount, so a late write cannot land on whichever command slid into the old path. Once it is
|
||||
saved the tree label refreshes in place rather than by rebuilding the branch, which would remount
|
||||
the open editor mid-edit.</p>
|
||||
the project file: it reloads as the empty title, and the label reads <code>List</code> both before and after,
|
||||
so a save cannot come back as a different label on the next load.</p>
|
||||
<p>Keystrokes debounce into one title save. The same dirty gate flushes the pending save — and awaits a
|
||||
save already on the wire — on two occasions: before every Control Tree row op, whose rebuild
|
||||
remounts the panel and can shift the entry paths, and before a selection change, which switches
|
||||
the panel away; unmount cancels it, so a late write cannot land on whichever command slides into
|
||||
the old path. A flush whose save fails refuses the op or the switch, and a refused op says so in a
|
||||
notice; a save that was already on the wire when the gate ran is only waited for — its failure
|
||||
raises a notice of its own, and the op then proceeds regardless, leaving the title unsaved. Once
|
||||
it is saved the tree label refreshes in place rather than by rebuilding the branch, which would
|
||||
remount the open editor mid-edit.</p>
|
||||
<p>The root list is the one list without a title input: the branch root reads <code>Mission</code>.</p>
|
||||
<h2 id="enabling-and-what-a-disabled-list-skips">Enabling, and What a Disabled List Skips</h2>
|
||||
<p>The enable switch is the checkbox on the command's own Control Tree item, not a control in the entry
|
||||
row. It decides only whether the command <strong>runs</strong>: while it is clear the row and the tree node dim,
|
||||
and the editor stays open and fully editable. Unticking a list dims its whole sub-tree — the dim
|
||||
rides ancestor propagation in the tree while each nested entry keeps its own flag, which is exactly
|
||||
what the run does: a disabled entry is skipped with everything under it.</p>
|
||||
<p>The enable switch is the checkbox on the command's own Control Tree row, not a control on its panel
|
||||
and not one of the row's buttons. It decides only whether the command <strong>runs</strong>: while it is clear
|
||||
the tree row dims, and the editor stays open and fully editable. The checkboxes are read-only while
|
||||
a mission row op, or a tick's own writes, are in flight. Unticking a list dims its whole sub-tree —
|
||||
the dim rides ancestor propagation in the tree while each nested entry keeps its own flag, which is
|
||||
exactly what the run does: a disabled entry is skipped with everything under it.</p>
|
||||
<h2 id="paths">Paths</h2>
|
||||
<p>A command node's key is its Mission API path — <code>"0"</code>, <code>"1"</code>, nested <code>"0.2"</code> for entry 2 inside the
|
||||
list at index 0. Every structural change re-mints them: deleting entry 2 slides the next command
|
||||
into path <code>"2"</code>. Each branch build therefore stamps its nodes, so the editor panel remounts onto the
|
||||
new path instead of going on showing the command that used to live there.</p>
|
||||
new path instead of going on showing a command the path no longer names. The host carries its own
|
||||
index-based ids — the expansion set, the Add focus and the selection — through each row op, so they
|
||||
follow the rows rather than the slots: a selection riding on the acted-on row follows it — the
|
||||
stepped or dropped row at its new index, or the clone a Duplicate makes — except on Delete, where
|
||||
no row remains to follow: it lands on the nearest remaining entry of that list, the index clamped
|
||||
to the new count, or on the owning list node once the list is empty, where Add Command waits. Any
|
||||
other selection keeps its own re-indexed row.</p>
|
||||
<h2 id="moving-commands-in-and-out">Moving Commands In and Out</h2>
|
||||
<ul>
|
||||
<li><strong>Into a list</strong> — drag a row onto the middle band of a list row; that row's outer quarters still
|
||||
reorder around it.</li>
|
||||
<li><strong>Out of a list</strong> — drag onto the drop-out zone of a nested list's editor, which is visible only
|
||||
while a row inside that editor is being dragged. The entry lands right after the list command
|
||||
itself in the owning list.</li>
|
||||
<li><strong>Into a list</strong> — drag a command's tree row — the whole row drags; the handle icon at its left
|
||||
only marks it as draggable — onto the middle band of a list row; that row's outer quarters still
|
||||
reorder around it. The Mission root row is all middle band: a drop anywhere on it lands in the
|
||||
root list. Either way the entry lands at that list's tail.</li>
|
||||
<li><strong>Out of a list</strong> — drop the row on the edge of a command row in another list, before or after it;
|
||||
the lower quarter of the list command's own row lands the entry right after the list in the
|
||||
owning list.</li>
|
||||
</ul>
|
||||
<p>Both are the same reparent call. The server resolves the source list and the target list to object
|
||||
references before it mutates either, so the index shift the removal causes cannot misroute the
|
||||
insert, and it refuses to move a list into itself or into one of its own descendants. That guard
|
||||
compares identity rather than path-string prefixes, because <code>"02"</code>, <code>"+2"</code> and <code>" 2"</code> all parse to
|
||||
index 2.</p>
|
||||
<p>Which call a landing makes depends on whether the entry changes list, not on where the pointer
|
||||
sat. A landing that changes the list — the middle band of a list the entry is not in, or an edge in
|
||||
another list — is the reparent call; a landing that keeps the list — an edge in the entry's own
|
||||
list, or the middle band of the list row (the Mission root row included) that already holds it,
|
||||
which sends it to the tail — is the reorder call, sent as the list's whole new order. The server
|
||||
resolves the source list and the target list to object references before it mutates either, so the
|
||||
index shift the removal causes cannot misroute the insert, and it refuses to move a list into itself
|
||||
or into one of its own descendants. That guard compares identity rather than path-string prefixes,
|
||||
because <code>"02"</code>, <code>"+2"</code> and <code>" 2"</code> all parse to index 2.</p>
|
||||
<p>Two more properties of a list follow from the same API:</p>
|
||||
<ul>
|
||||
<li><strong>A new command lands at the end</strong> of the list it was added to, root or nested. Nothing is pinned;
|
||||
the order is entirely the user's, changed with the row's up / down buttons or by dragging.</li>
|
||||
<li><strong>A new command lands right after the focused command</strong> when that command is a direct entry of
|
||||
the list the <code>+</code> belongs to, root or nested, and at that list's tail otherwise. The focus is one
|
||||
for the whole Mission tree — the last selected or last added command, whichever list it sits in
|
||||
— so each list row's <code>+</code>, scoped to its own list, ignores a focus that lies in another list.
|
||||
Nothing is pinned; the order is entirely the user's, changed with the row's Move up / Move down
|
||||
buttons or by dragging.</li>
|
||||
<li><strong>Duplicate is a deep copy.</strong> The entry is cloned through the same XML round-trip the project file
|
||||
uses, so a nested list copies with its whole sub-tree, and the clone lands right after the source.</li>
|
||||
</ul>
|
||||
<p>Dragging serves rearrangement only: a drag carrying text or files is ignored, because the row's drag
|
||||
handling returns as soon as the drag did not start on a row. To bring several program files in at
|
||||
once, open a <a class="xref" href="NcFileCommand-panel.html">Program File</a> command's picker and pick them
|
||||
<p>Dragging serves rearrangement only: a row accepts a drop only while a mission row is being dragged,
|
||||
so a drag carrying text or files keeps the browser's no-drop cursor. To bring several program files
|
||||
in at once, open a <a class="xref" href="NcFileCommand-panel.html">Program File</a> command's picker and pick them
|
||||
together — the first pick lands on that command and each further pick becomes another Program File
|
||||
command right after it, in pick order, inside the same list at any depth.</p>
|
||||
<h2 id="which-commands-a-list-can-hold">Which Commands a List Can Hold</h2>
|
||||
<p>The addable set is the server's command catalog: every engine command carrying <code>[CommandCatalog]</code>,
|
||||
reflected into the picker Add Command opens, which searches by display label, kind key and alias.
|
||||
reflected into the picker Add Command opens, which searches by display label, kind key and alias
|
||||
and takes one pick per opening.
|
||||
<code>List</code> is one of those commands, which is what makes nesting an ordinary act rather than a special
|
||||
case. The frontend contributes an icon per kind, and its own label where it has one; the server
|
||||
supplies the localized label otherwise, so a newly attributed engine command becomes addable with no
|
||||
@@ -196,50 +217,74 @@ creation. General Config is the one such command with an editor of its own: it i
|
||||
settings bundle, so a project file storing one loads as the individual setting commands it stands
|
||||
for and saving never writes the bundle back — editable when a project still constructs one through
|
||||
the API, and absent from the catalog.</p>
|
||||
<p>Selecting an entry row selects that command's tree node, and the command's editor opens on that
|
||||
node — the kind's own panel when one exists, otherwise a generic editor built from the scalar fields
|
||||
the command declares. Selection is one row at a time: there is no multi-selection here, and every
|
||||
action acts on the row that carries it. Because the server composes every entry label, a command
|
||||
carrying no title of its own still reads as its localized display name.</p>
|
||||
<p>There is no second column inside this editor: the entry list is a single column in the tree's editor
|
||||
pane. The draggable vertical divider on screen belongs to the Execution page, between the left dock
|
||||
— the Control Tree over the editor panel — and the central area; a second divider inside that dock
|
||||
drags the height between the tree and the editor.</p>
|
||||
<p>Selecting a command's tree row opens that command's editor on its node — the kind's own panel when
|
||||
one exists, otherwise a generic editor built from the scalar fields the command declares. Selection
|
||||
is one row at a time: there is no multi-selection here, and every row button acts on the row that
|
||||
carries it, whether or not that row is the selected one. Because the server composes every entry
|
||||
label, a command carrying no title of its own still reads as its localized display name.</p>
|
||||
<p>A list's entries never appear in the editor pane: they are the node's children in the Control Tree,
|
||||
and the pane below the tree shows only the selected command's panel. The left-most of the Execution
|
||||
page's three draggable vertical dividers sits between the left dock — the Control Tree over the
|
||||
editor panel — and the central area; the divider inside that dock drags the height between the tree
|
||||
and the editor.</p>
|
||||
<h2 id="source-code-path">Source Code Path</h2>
|
||||
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
|
||||
<h3 id="web-application">Web Application</h3>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — a list entry's panel: the
|
||||
control bar, the optional Title input with its debounce / flush / cancel discipline, the embedded
|
||||
entry-list editor of a list entry, and the bespoke-or-generic editor choice for every other kind.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — the entry-list editor embedded
|
||||
here and serving the branch root: the rows and their actions, the three drag landings, and the
|
||||
drop-out zone shown only during a drag inside a nested editor.</li>
|
||||
disabled caption, the optional Title input with its debounce / flush / cancel discipline and the
|
||||
dirty gate it answers to the host, and the bespoke-or-generic editor choice for every other kind.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree rows: the draggable row
|
||||
with its handle icon, the Move up / Move down / Duplicate / Delete buttons on every command row
|
||||
(revealed on hover and on the selected row, always shown on a touch or pen device), the <code>+</code>
|
||||
on every list row (the Mission root included) and the Add Command dialog it opens, and the
|
||||
drop-indicator styles.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useMissionTreeDrag.ts</code> — the drag bookkeeping between
|
||||
mission rows: which rows drag, which receive, and the before / after / into landing read from the
|
||||
pointer's position on the row.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — the branch root's panel, the one
|
||||
without a title input: the command count and the run-order hint.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first catalog picker;
|
||||
one pick per opening.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — the child builders that recurse
|
||||
into a list's own entries, the per-kind editor override map, the kind and category icons, and the
|
||||
per-build stamp that forces the panel remount.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — which nodes show a checkbox, the
|
||||
dim that flows down a disabled command's sub-tree, the enable write, and the in-place label
|
||||
refresh after a title edit or a language switch.</li>
|
||||
into a list's own entries, the per-kind editor override map, and the per-build stamp that forces
|
||||
the panel remount.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/missionKindIcons.ts</code> — the kind and category icons the
|
||||
picker shows.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the five row ops — add, drag
|
||||
move, step, duplicate, delete — through one <code>missionRowOp</code> helper (the busy gate, the open panel's
|
||||
dirty flush, the API call, the scoped rebuild, the post-op selection), the insert-after-focus rule
|
||||
scoped to the <code>+</code>'s own list, and the index translation that carries the expansion set, the Add
|
||||
focus and the selection through each op; which nodes show a checkbox, the dim that flows down a
|
||||
disabled command's sub-tree, the enable write, and the in-place label refresh after a title edit
|
||||
or a language switch.</li>
|
||||
<li><code>wwwroot-src/src/api/mission.ts</code> — the typed wrapper over the Mission API and the path convention
|
||||
(<code>root</code> or empty = the root list, <code>0.2</code> = a nested entry).</li>
|
||||
(<code>root</code> or empty = the root list, <code>0.2</code> = a nested entry); <code>addEntry</code> takes the optional insert
|
||||
index and resolves to the new entry's path.</li>
|
||||
<li><code>wwwroot-src/src/components/mission/GenericCommandPanel.vue</code> — the editor a catalog kind gets when
|
||||
it ships no bespoke panel, built from the command's declared scalar fields.</li>
|
||||
<li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code> — the multi-pick file dialog: the
|
||||
first pick lands on the command, each further pick becomes another Program File command right
|
||||
after it.</li>
|
||||
<li><code>wwwroot-src/src/pages/ExecutionPage.vue</code> — the page-level splitter between the left dock and the
|
||||
central area.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the <code>tree.mission.*</code> strings: the kind names, the drop-out
|
||||
zone, the run-order hint, the disabled hint and the operation labels.</li>
|
||||
<li><code>wwwroot-src/src/pages/ExecutionPage.vue</code> — the page-level splitters; the left-most parts the left
|
||||
dock from the central area.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreeDock.vue</code> — the left dock's two rows and the
|
||||
height divider between the tree and the editor.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the <code>tree.mission.*</code> strings: the kind names, the run-order
|
||||
hint that names the row affordances, the disabled hint, the cancelled-op notice and the operation
|
||||
labels.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/common.ts</code> — the row buttons' titles and the Title (optional) label.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/dialog.ts</code> — the Delete Command confirmation.</li>
|
||||
<li><code>Missions/MissionController.cs</code> — the entry lifecycle: <code>GET list-command/entries</code> (recursive),
|
||||
<code>POST list-command/entries</code> and <code>POST list-command/entries/{path}</code> (append at the tail of the root
|
||||
or of a nested list), <code>DELETE list-command/entries/{path}</code>,
|
||||
<code>POST list-command/entries/{path}/move</code>, <code>PUT list-command/reorder</code>,
|
||||
<code>POST list-command/entries/{path}/duplicate</code> (the XML-round-trip deep clone),
|
||||
<code>POST list-command/entries/{path}/reparent</code> (drag-into-list and drop-out, with the self/descendant
|
||||
guard), <code>PUT commands/{path}/listcommand</code> for the title, and <code>PUT commands/{path}/enabled</code> for an
|
||||
entry's enable flag. <code>GetCommandTitle</code> composes every entry label the tree shows.</li>
|
||||
<code>POST list-command/entries</code> and <code>POST list-command/entries/{path}</code> (into the root or a nested
|
||||
list, at an optional <code>insertIndex</code> clamped to the list and otherwise at its tail, answering the
|
||||
new entry's index and path), <code>DELETE list-command/entries/{path}</code>,
|
||||
<code>POST list-command/entries/{path}/move</code> (the row's Move up / Move down), <code>PUT list-command/reorder</code>
|
||||
(a drop that keeps the owning list), <code>POST list-command/entries/{path}/duplicate</code> (the
|
||||
XML-round-trip deep clone), <code>POST list-command/entries/{path}/reparent</code> (a drop that changes the
|
||||
owning list, with the self/descendant guard), <code>PUT commands/{path}/listcommand</code> for the title, and
|
||||
<code>PUT commands/{path}/enabled</code> for an entry's enable flag. <code>GetCommandTitle</code> composes every entry
|
||||
label the tree shows.</li>
|
||||
<li><code>Missions/MissionCommandCatalog.cs</code> — reflects the <code>[CommandCatalog]</code> commands into the addable
|
||||
set and constructs the picked kind.</li>
|
||||
</ul>
|
||||
@@ -260,7 +305,7 @@ a loaded project expands a stored one into the split setting commands.</li>
|
||||
</ul>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a class="xref" href="mission-root-panel.html">Mission Root Panel</a> — the entry-list editor this command embeds, documented once</li>
|
||||
<li><a class="xref" href="mission-root-panel.html">Mission Root Panel</a> — the branch root, and the Control Tree row affordances every list shares, documented once</li>
|
||||
<li><a href="../../../manual/run/building-a-mission.html">Building a Mission</a> — the task this command serves: grouping a mission and moving entries between groups</li>
|
||||
<li><a href="index.html">Mission</a> — the rest of the command panels</li>
|
||||
</ul>
|
||||
|
||||
@@ -100,9 +100,13 @@ program name the run log shows, which is why the model defaults it to the comman
|
||||
<code>NC Code</code>, rather than to an empty string. It is also the detail the mission row brackets: the row
|
||||
reads <code>NC Code</code> while the title is empty or still that default, and <code>NC Code [title]</code> once it says
|
||||
something else.</p>
|
||||
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control
|
||||
Tree, below the move / duplicate / delete control bar. A single-purpose kind like this one embeds
|
||||
its whole editor on that node rather than growing section child nodes.</p>
|
||||
<p>The panel renders on the command's own node under the Mission root of the Execution page's Control
|
||||
Tree. The editor pane holds nothing but the editor: the command's move up / move down / duplicate /
|
||||
delete buttons and its drag handle sit on its tree row, and the Add Command <code>+</code> sits on the row of
|
||||
the list that holds it. A single-purpose kind like this one embeds its whole editor on that node
|
||||
rather than growing section child nodes. Its tree checkbox only decides whether the run plays the
|
||||
command; a disabled command is skipped during play — a caption above the title says so — and its
|
||||
editor stays usable.</p>
|
||||
<h2 id="layout">Layout</h2>
|
||||
<ul>
|
||||
<li>NcCodeCommand Panel
|
||||
@@ -124,7 +128,7 @@ folder is the <a class="xref" href="script-command-panel.html">Script command</a
|
||||
CodeMirror with a C# grammar, this one ships a text area.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Stats and Actions Row (web)
|
||||
<li>Stats and Actions Row
|
||||
<ul>
|
||||
<li>Line count and character count, both recomputed as the text changes.</li>
|
||||
<li>Trim Blank Lines Button — trims every line and drops the ones left empty, then saves at once.</li>
|
||||
@@ -137,11 +141,32 @@ CodeMirror with a C# grammar, this one ships a text area.</li>
|
||||
</ul>
|
||||
<h2 id="saving">Saving</h2>
|
||||
<p>Typing in either field schedules one save 400 ms after the last keystroke, so a burst of typing
|
||||
costs one request instead of one per character. Trim Blank Lines and Clear save immediately rather
|
||||
than through that timer.</p>
|
||||
costs one request instead of one per character. The title and the NC text share that timer, and the
|
||||
save carries every field edited since the last one. Trim Blank Lines and Clear save immediately
|
||||
rather than through that timer.</p>
|
||||
<p>The write is a single patch endpoint carrying the NC text and the title. Each field is applied only
|
||||
when the body actually carries it, which is why the client sends the field it changed and a null for
|
||||
the one it did not.</p>
|
||||
when the body actually carries it, which is why the client sends the fields it edited and a null
|
||||
for the rest. The endpoint carries no content hash, so nothing on the server refuses a save that
|
||||
arrives late. After each save the tree relabels the command's node in place rather than rebuilding
|
||||
the branch, which would remount the editor mid-edit.</p>
|
||||
<p>The panel snapshots its command path at mount, and every load and save targets that snapshot
|
||||
rather than the live selection. The path is an index-based entry path which every structural op
|
||||
re-points, so the panel hands the Control Tree host a switch gate that runs before the selection
|
||||
moves off the command and before every mission row op — move, duplicate, delete, drag, Add Command
|
||||
— wherever in the tree that op acts: the gate first lets a save already on the wire land, then
|
||||
sends the edit still waiting in the timer while the path is still the command's own. The gate is
|
||||
there because an op rebuilds the list it rewrites — a drag between two lists rebuilds the nearest
|
||||
list above both — and that rebuild re-mints the build stamp of every node under the rebuilt list.
|
||||
Only one command editor is ever mounted, the selected node's, and its mount key carries that stamp,
|
||||
so the editor remounts when its command sits inside the rebuilt list; the host does not ask whether
|
||||
it does before running the gate — an op in a list that does not hold this command leaves the
|
||||
editor mounted, and its staged edit is flushed all the same. A save that fails refuses the op, and
|
||||
the host drops it with a notice.
|
||||
Unmount cancels the timer instead of flushing it, so no save from a retired instance can land on
|
||||
whichever command has slid into its path. Selection and the tick checkboxes are read-only while a
|
||||
row op is in flight, and equally while a tick's own PUTs are on the wire: the host holds one busy
|
||||
gate for both, so an enable toggle refuses a selection change and ignores further ticks until its
|
||||
writes have landed, exactly as a row op does.</p>
|
||||
<p>NC text is not validated while it is edited: there is no parse at edit time and no error surface on
|
||||
the panel — the server stores whatever string arrives. Errors surface when the mission plays the
|
||||
text.</p>
|
||||
@@ -152,15 +177,35 @@ text.</p>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/mission/NcCodeCommandPanel.vue</code> — this panel: the Title input, the
|
||||
18-row monospace text area, the 400 ms debounced saves, the live line and character stats, Trim
|
||||
Blank Lines, and Clear behind a confirm dialog.</li>
|
||||
Blank Lines, and Clear behind a confirm dialog; the path snapshot taken at mount, the switch gate
|
||||
that waits for a save on the wire and then drains the timer, and the unmount that cancels rather
|
||||
than flushes.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the command node's
|
||||
slave panel: mounts this editor on the entry path, forwards its switch gate to the host, and
|
||||
shows the disabled caption above the title.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — mounts the one editor pane, the
|
||||
selected node's, under a key that carries the node's build stamp; a rebuild that re-mints the
|
||||
stamp remounts it.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree rows: the drag handle
|
||||
and the move / duplicate / delete buttons on the command's row, and the Add Command <code>+</code> on the
|
||||
row of its list.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — funnels every selection change
|
||||
and every mission row op through the active panel's switch gate; holds the one busy gate that
|
||||
keeps selection and the tick checkboxes read-only while a row op, or a tick's own PUTs, are in
|
||||
flight; a refused gate drops the op with a notice, and a save relabels the command's node in
|
||||
place.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>nccode</code> kind to this
|
||||
panel, and states the rule it belongs to: a single-purpose kind embeds its whole editor on the
|
||||
command node.</li>
|
||||
command node; mints the per-build stamp every command node under a rebuilt list carries.</li>
|
||||
<li><code>wwwroot-src/src/api/mission.ts</code> — <code>loadNcCode</code> and <code>setNcCode</code>, and the command shape the panel
|
||||
edits (NC code plus title).</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: the NC Code label, the character
|
||||
count, Trim Blank Lines, and the line count it shares with the other panels.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/common.ts</code> — the shared strings the panel borrows: the “Title
|
||||
(optional)” label on the Title Field and the Clear button's label.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/dialog.ts</code> — the Clear confirmation's title and message.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the disabled caption and the notice a refused gate raises on
|
||||
a row op.</li>
|
||||
<li><code>Missions/MissionController.cs</code> — the single patch PUT for this command, whose NC-code and title
|
||||
fields are each applied when the body carries them, and the command-snapshot arm that returns both
|
||||
back to the panel.</li>
|
||||
@@ -178,9 +223,9 @@ how this command's NC text persists with the project.</li>
|
||||
</ul>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a class="xref" href="NcFileCommand-panel.html">NcFileCommand Panel</a> — the other Program command: a path to a file instead of text stored in the project</li>
|
||||
<li><a class="xref" href="NcFileCommand-panel.html">NcFileCommand Panel</a> — the other NC program command among the three kinds the Program catalog category holds (Program File, NC Code, Script): a path to a file instead of text stored in the project</li>
|
||||
<li><a class="xref" href="script-command-panel.html">Script Command Panel</a> — the rich editor this folder does have, and why this command ships a plain text area instead</li>
|
||||
<li><a href="../../../manual/run/playing-a-program.html">Playing a Program</a> — the task these two commands serve</li>
|
||||
<li><a href="../../../manual/run/playing-a-program.html">Playing a Program</a> — the task the two NC program commands, Program File and NC Code, serve; the Script command has its own manual page</li>
|
||||
<li><a href="index.html">Mission</a> — the rest of the command panels</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -99,9 +99,13 @@ command: at play time <a class="xref" href="../../../api/Hi.MachiningProcs.Sessi
|
||||
together with the project's own base directory to the local project service, and that is where a
|
||||
relative path acquires its root; the convention behind it is the
|
||||
<a class="xref" href="../../conventions/gui-file-path-assignment.html">Load Pattern</a>.</p>
|
||||
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control
|
||||
Tree, below the move / duplicate / delete control bar. This command has no title of its own, so the
|
||||
row and tree label read <code>Program File [path]</code>, the path being the detail the label brackets.</p>
|
||||
<p>The panel renders on the command's own node under the Mission root of the Execution page's Control
|
||||
Tree. The editor pane holds the editor and, while the command's tree checkbox is off, a one-line
|
||||
disabled hint above it — nothing structural: the command's move up / move down / duplicate / delete
|
||||
buttons and its drag handle sit on its tree row, and the Add Command <code>+</code> sits on the row of the
|
||||
list that holds it. This command has no editable Title field — unlike NC Code, Script and List —
|
||||
so its tree row label is composed from the path alone: <code>Program File [path]</code>, the path being the
|
||||
detail the label brackets.</p>
|
||||
<div class="NOTE">
|
||||
<h5>Note</h5>
|
||||
<p>The GUI labels this command “Program File”: it plays NC, CL (CLSF) and CSV files — the runner is
|
||||
@@ -178,11 +182,17 @@ browser to preserve. It is the backstop for a brand extension the NC group does
|
||||
Auto routes to the CL and CSV runners, and everything else falls through to brand NC.</p>
|
||||
<h2 id="multi-pick-fan-out">Multi-Pick Fan-Out</h2>
|
||||
<p>The dialog is multi-select, and this is the one command editor that grows the mission. The first
|
||||
picked file lands on this command. Each further pick becomes a <strong>new</strong> Program File command, added
|
||||
to the list this command sits in and moved into place directly after it, in pick order — the same
|
||||
list, so a command inside a nested list fans out inside that nested list. The panel then reports a
|
||||
structure change, which rebuilds the owning list's branch around the new rows and leaves the
|
||||
selection on this command.</p>
|
||||
picked file lands on this command. Each further pick becomes a <strong>new</strong> Program File command,
|
||||
inserted into the list this command sits in at the index directly after it, in pick order — one
|
||||
insert per pick, each at the next index, and the same list, so a command inside a nested list fans
|
||||
out inside that nested list. The panel then reports the insert range — the first new index and
|
||||
the count — and the command's slave panel scopes it to the owning list and names this command as
|
||||
the selection. The Control Tree host takes that insert on its structure-changed path, which shares
|
||||
two things with its own row ops — it holds the busy gate for the rebuild (a change arriving while
|
||||
another op is in flight is not rebuilt) and carries the index-based ids (the expansion set and the
|
||||
Add focus) over the new siblings — and not the third: the open panel's dirty gate, which every
|
||||
row op runs first, is not part of this path. It then rebuilds the owning list's branch around the
|
||||
new rows and leaves the selection on this command, whose own index is unchanged.</p>
|
||||
<h2 id="where-the-program-text-is-edited">Where the Program Text Is Edited</h2>
|
||||
<p>The command stores a path, and the panel does not edit the file. It assigns the path, picks the
|
||||
runner, reports what the server knows about the file, and previews its first 100 lines read-only.
|
||||
@@ -203,14 +213,27 @@ command stores.</li>
|
||||
from; an empty extension list means all files.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>ncfile</code> kind to this
|
||||
panel. A kind absent from that map is served by the generic field editor instead.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the command node's
|
||||
slave panel: mounts this editor on the entry path, and re-scopes the fan-out's structure change
|
||||
to the owning list, with the insert range and this command as the selection.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree rows: the drag handle
|
||||
and the move / duplicate / delete buttons on the command's row, and the Add Command <code>+</code> on the
|
||||
row of its list.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — takes the fan-out's insert on
|
||||
its structure-changed path: the busy gate held for the rebuild, the index-based ids carried over
|
||||
the new siblings (the two guarantees shared with the row ops; the dirty gate is not one of them),
|
||||
the rebuild scoped to the owning list, and the selection the payload names.</li>
|
||||
<li><code>wwwroot-src/src/api/mission.ts</code> — <code>loadNcFile</code>, <code>setNcFilePath</code>, <code>setNcFileNcKind</code>,
|
||||
<code>getNcFileInfo</code> and <code>previewNcFile</code>, plus the kind union and the file-info shape.</li>
|
||||
<code>getNcFileInfo</code> and <code>previewNcFile</code>, plus the kind union and the file-info shape; <code>addEntry</code>,
|
||||
which the fan-out calls with the insert index and which answers the new entry's path.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: the path hint, the Play As hint, the
|
||||
four filter labels, the banner's found and not-found lines, and the preview titles.</li>
|
||||
<li><code>Missions/MissionController.cs</code> — four endpoints serve this command: a PUT for the path, a PUT for
|
||||
the NC kind, and the two server-side reads behind the banner and the preview (both POSTs, both
|
||||
resolving a relative path against the project folder). The command-snapshot builder emits the file
|
||||
path and the NC kind for this kind of command.</li>
|
||||
resolving a relative path against the project folder). The fan-out's extra picks go through the
|
||||
list-entry POST, which lands the new entry at the requested insert index — clamped to the list,
|
||||
the tail when none is given — and answers its index and dotted path. The command-snapshot builder
|
||||
emits the file path and the NC kind for this kind of command.</li>
|
||||
</ul>
|
||||
<h3 id="hiapi-engine">HiAPI Engine</h3>
|
||||
<ul>
|
||||
|
||||
@@ -90,17 +90,24 @@
|
||||
<p>The Mission branch root of the <a class="xref" href="../index.html">Execution page</a>'s Control Tree: route
|
||||
<code>/execution</code>, Control-Tree path <code>execution/mission</code>, panel <code>MissionRootPanel.vue</code>. <code>/mission</code>
|
||||
resolves to the same place — it redirects onto <code>/execution?tree=execution/mission</code>.</p>
|
||||
<p>The panel edits one list of commands: the mission's own command, which is always a
|
||||
<a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a>. The branch root is therefore a list editor — Add Command, the
|
||||
entries in run order, and the operations that rewrite the list. Editing a command is not this
|
||||
panel's job: clicking a row selects that command's tree node, and the command's own editor renders
|
||||
on that node's panel.</p>
|
||||
<p>The node roots one list of commands: the mission's own command, which is always a
|
||||
<a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a>. Its entries are the node's tree children, in run order, and
|
||||
the row operations that rewrite the list — Add Command, drag, move up, move down, duplicate, delete —
|
||||
live on the Control Tree rows and run in the tree host; no panel carries a second copy of them. The
|
||||
one panel-side insert is the Program File editor's multi-pick: picking several files at once keeps
|
||||
the first on that command and adds one Program File command per further file right after it, in its
|
||||
own list, then hands the host the inserted range so the same busy gate and id translation cover the
|
||||
rebuild. The root's own panel is informational: the command count and the run-order hint. Editing a
|
||||
command is not this node's job either: selecting a command row opens that command's own editor on
|
||||
its node's panel.</p>
|
||||
<p>Command nodes are addressed by index-derived tree ids and by dotted API paths (<code>"0"</code>, <code>"1"</code>, nested
|
||||
<code>"0.2"</code>). A command node id extends its parent's, so a root entry is <code>execution/mission/{index}</code> and
|
||||
an entry inside a nested list is <code>execution/mission/{index}/{index}</code>; a command's section children
|
||||
extend it once more, as <code>execution/mission/{index}/{id}</code> keyed on the section. Both forms shift on
|
||||
every structural change — deleting entry 2 slides the next command into path <code>"2"</code> — so each branch
|
||||
build stamps its nodes afresh and the editor panels remount onto the new paths.</p>
|
||||
build stamps its nodes afresh and the editor panels remount onto the new paths, and the host carries
|
||||
its own index-based ids — the expansion set, the Add focus and the selection — through every row op
|
||||
so they follow the rows rather than the slots.</p>
|
||||
<h2 id="key-models">Key Models</h2>
|
||||
<ul>
|
||||
<li><strong>Primary</strong>: <a class="xref" href="../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> — the mission's command,
|
||||
@@ -122,17 +129,19 @@ top-down.</li>
|
||||
<ul>
|
||||
<li>Mission Root Panel
|
||||
<ul>
|
||||
<li>Head Line
|
||||
<li>No-Project Caption
|
||||
<ul>
|
||||
<li>Add Command Button
|
||||
<ul>
|
||||
<li>Opens the Add Command dialog. Disabled while no project is open.</li>
|
||||
<li>“No project loaded. Open or create a project first.” while nothing is open; the head line,
|
||||
separator and empty state are withheld with it.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Head Line
|
||||
<ul>
|
||||
<li>Commands Caption</li>
|
||||
<li>Command Count Badge
|
||||
<ul>
|
||||
<li>Outlined, and grey rather than primary while the list is empty.</li>
|
||||
<li>The root list's own entries — the node's command children. Outlined, and grey rather than
|
||||
primary while the list is empty.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -140,56 +149,101 @@ top-down.</li>
|
||||
<li>Separator</li>
|
||||
<li>Empty State
|
||||
<ul>
|
||||
<li>“No project loaded” while nothing is open; otherwise “No commands yet”, naming Add Command.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>(Each) Command Row
|
||||
<ul>
|
||||
<li>Drag Handle Icon
|
||||
<ul>
|
||||
<li>The whole row is draggable; the handle is the affordance for it.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Command Label
|
||||
<ul>
|
||||
<li>The command's title as the engine composes it: the kind's localized display name, with a
|
||||
title the user typed appended as <code>Name [title]</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Move Up Button / Move Down Button
|
||||
<ul>
|
||||
<li>Disabled at the ends of the list.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Duplicate Button</li>
|
||||
<li>Delete Button</li>
|
||||
<li>A disabled command's row is dimmed, and its buttons stay live.</li>
|
||||
<li>Clicking the row anywhere but on a button selects that command's tree node.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Drop-Out Zone
|
||||
<ul>
|
||||
<li>Present in a nested list editor only, and shown only while a row is being dragged. It sits
|
||||
below the rows, so the rows do not shift under the pointer at drag start.</li>
|
||||
<li>“No commands yet. Click Add Command to create one.” while the list is empty.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Run-Order Hint
|
||||
<ul>
|
||||
<li>Commands run top-down, and the checkbox on each command's tree item enables or disables it.</li>
|
||||
<li>Always present. It names the row affordances: commands run top-down in the Control Tree; add
|
||||
one with + on the Mission or a List row; drag a row to reorder it; a row's own buttons move,
|
||||
duplicate or delete it; its checkbox enables or disables it.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Mission Root Row (Control Tree)
|
||||
<ul>
|
||||
<li>Add Command Button
|
||||
<ul>
|
||||
<li>The <code>+</code>, always visible and pinned to the row's right edge. Opens the Add Command dialog
|
||||
scoped to the root list. Disabled while no project is open, and while the busy gate is held —
|
||||
a mission op, or a checkbox toggle's save, in flight.</li>
|
||||
<li>The row carries no drag handle and no command ops. It is a drop target: anywhere on its height
|
||||
lands the dragged command in the root list.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>(Each) Command Row
|
||||
<ul>
|
||||
<li>Enable Checkbox
|
||||
<ul>
|
||||
<li>The tree's tick, and the command's enable switch; a disabled command's label is dimmed.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Drag Handle Icon
|
||||
<ul>
|
||||
<li>The whole row is draggable; the handle is the affordance for it. Plain and List command rows
|
||||
carry one; the root row does not.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Command Label
|
||||
<ul>
|
||||
<li>A real link to the node's <code>?tree=</code> URL, so the browser's context menu can open it in a new
|
||||
tab, while a plain click keeps the in-app selection. The text is the command's title as the
|
||||
engine composes it: the kind's localized display name, with the command's key value appended
|
||||
in brackets where the kind has one — a List's or Script's typed title, a Program File's file,
|
||||
a resolution's millimetres, a switch's On / Off.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Move Up Button / Move Down Button / Duplicate Button / Delete Button
|
||||
<ul>
|
||||
<li>Hidden at rest, revealed on hover and on the selected row, and always shown where there is no
|
||||
hover to reveal them with (touch). Move Up is disabled on the first entry and Move Down on the
|
||||
last; all four while the busy gate is held — a mission op, or a checkbox toggle's save, in
|
||||
flight.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Add Command Button
|
||||
<ul>
|
||||
<li>On a List row only: the same <code>+</code>, scoped to that list, to the right of the row buttons.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Drop Indicator
|
||||
<ul>
|
||||
<li>A primary edge line for a before / after landing, a tinted row for a landing into a list; the
|
||||
dragged row itself dims.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Enable/disable is not a control on this panel. It is the tree item's checkbox on the command node; a
|
||||
disabled command is skipped when the mission plays and stays fully editable.</p>
|
||||
<p>Enable/disable is not a control on any panel. It is the tree item's checkbox on the command node; a
|
||||
disabled command is skipped when the mission plays and stays fully editable. A toggle PUTs straight
|
||||
to the Mission API and flips the node's own state, with no rebuild; on failure the checkbox snaps
|
||||
back. The toggle holds the same busy gate as the structural ops while its save is on the wire — a
|
||||
row op sent meanwhile could be applied first server-side and land the flag on whichever command
|
||||
slid into the ticked path — so until the save lands every row button and <code>+</code> is disabled, no drag
|
||||
starts, the tree selection is refused, an op that still reaches the host returns silently, and a
|
||||
further checkbox click snaps back. The gate holds in the other direction too: the checkboxes and
|
||||
the tree selection are read-only while a mission op is in flight, since a tick would address the
|
||||
node's pre-op path.</p>
|
||||
<h2 id="add-command">Add Command</h2>
|
||||
<p>The button opens a search-first picker. The search box matches a command's display label, its kind
|
||||
key, or one of its declared aliases — each alias searchable both by its English key and by its word
|
||||
in the request language. Arrow keys walk the results and Enter takes the highlighted one. Results
|
||||
are grouped by category, in the catalog's own display order.</p>
|
||||
<p>The picked command is appended to the list this editor is scoped to, and the branch rebuilds in
|
||||
place: the selection stays on the list rather than jumping into the new command's panel.</p>
|
||||
<p>The <code>+</code> on the Mission root row, or on any List row, opens a search-first picker. The search box
|
||||
matches a command's display label, its kind key, or one of its declared aliases — each alias
|
||||
searchable both by its English key and by its word in the request language. Arrow keys walk the
|
||||
results and Enter takes the highlighted one. Results are grouped by category, in the catalog's own
|
||||
display order. One pick per opening: a second click or Enter before the dialog has closed adds
|
||||
nothing.</p>
|
||||
<p>The picked command is inserted right after the focused command when that command is a direct
|
||||
entry of the list the <code>+</code> is scoped to, and at that list's tail otherwise. The focus is one for the
|
||||
whole mission, not one per list: the most recently selected command anywhere in the tree (a section
|
||||
row counts for its owning command), or the last command an Add landed on. So the Mission row's <code>+</code>
|
||||
never chases a focus inside a nested list — and once a nested command has been selected, the root
|
||||
row's <code>+</code> appends at the root's tail rather than after whichever root command was selected before
|
||||
it. The branch rebuilds in place, the new row is revealed and becomes the focus, so a run of adds
|
||||
lands in order below it, and the selection stays where it was rather than jumping into the new
|
||||
command's panel.</p>
|
||||
<p>The addable set is served by the backend rather than mirrored in a frontend menu. Every engine
|
||||
command carrying <code>[CommandCatalog]</code> is reflected into the catalog, so attributing a new engine
|
||||
command is all it takes for it to appear in the dialog. Thirteen kinds ship:</p>
|
||||
@@ -207,42 +261,64 @@ Failure, Physics</li>
|
||||
can override that choice.</p>
|
||||
</div>
|
||||
<h2 id="ordering-duplicating-and-deleting">Ordering, Duplicating and Deleting</h2>
|
||||
<p>Every structural op runs through one path in the tree host: a busy gate that holds every row
|
||||
affordance, the tree selection and the checkboxes read-only while the op is in flight — the one
|
||||
gate a checkbox toggle also holds while its save is on the wire, so an op and a tick never
|
||||
interleave on the server; the open editor's dirty flush — an editor with staged edits (Script, NC
|
||||
Code, a List's title) saves or resolves them first, waiting for a save already on the wire, and a
|
||||
refused flush drops the op with a notice rather than silently; the API call; a rebuild scoped to
|
||||
the list the op rewrote; then the post-op selection. The selection follows the acted-on row only
|
||||
when it already rode on it — that row, or a node under it — and otherwise stays on its own
|
||||
re-indexed row, so the editor the user is in is left alone.</p>
|
||||
<p>Move Up and Move Down move an entry within its own list; they never change which list owns it.
|
||||
Duplicate deep-clones the entry through the same XML round-trip the project file uses — so a nested
|
||||
list copies with its whole subtree — and the clone lands right after the source. Delete asks for
|
||||
confirmation in a dialog naming the command.</p>
|
||||
list copies with its whole subtree — and the clone lands right after the source; a selection riding
|
||||
on the source moves onto the clone. Delete asks for confirmation in a dialog naming the command,
|
||||
before the dirty gate runs, so a cancelled delete forces no save prompt on the open editor; a
|
||||
selection riding on the deleted row lands on the nearest remaining entry of that list, or on the
|
||||
list node itself once the list is empty, where Add Command waits.</p>
|
||||
<p>Dragging a row has three landings:</p>
|
||||
<ul>
|
||||
<li>On another row — reorder within this list. A plain row splits at its midline into before and
|
||||
after, and the whole new order is sent as one ordered path list.</li>
|
||||
<li>On the middle band of a <code>list</code> row — move the entry inside that list. That row's outer quarters
|
||||
still reorder around it.</li>
|
||||
<li>On the drop-out zone of a nested list editor — move the entry out, landing right after the list
|
||||
command itself in the owning list.</li>
|
||||
<li>On a command row's edge — before or after it. A plain command row splits at its midline; a List
|
||||
row's outer quarters are its edges. When both rows share a list this is a reorder, and the whole
|
||||
new order is sent as one ordered path list; when they do not, the entry relocates into the
|
||||
target's list at that slot — which is also the way out of a nested list.</li>
|
||||
<li>On the middle band of a List row — move the entry inside that list, at its tail.</li>
|
||||
<li>On the Mission root row — anywhere on its height moves the entry into the root list, at its tail.</li>
|
||||
</ul>
|
||||
<p>The last two are the same reparent call. The server resolves both lists to object references before
|
||||
it mutates either, so the index shift the removal causes cannot misroute the insert, and it refuses
|
||||
to move a list into itself or into one of its own descendants.</p>
|
||||
<p>Which call a landing makes depends on whether the entry changes list, not on where the pointer
|
||||
sat. A landing that keeps the list — an edge in the entry's own list, or an into-landing on the
|
||||
list that already holds it (a List row's middle band, or the Mission root row for a root entry),
|
||||
which sends it to the tail — is the reorder call, the whole new order as one ordered path list; a
|
||||
landing that changes the list — into a list the entry is not in, or an edge in another list — is
|
||||
the reparent call. The client refuses to drop a row onto itself or into its own subtree, starts no
|
||||
drag while the busy gate is held — an op, or a checkbox toggle's save, in flight — and abandons a
|
||||
drop whose row was re-stamped by a rebuild mid-drag. The server resolves both lists to object
|
||||
references before it mutates either, so the index shift the removal causes cannot misroute the
|
||||
insert, and it refuses to move a list into itself or into one of its own descendants. A move across
|
||||
lists rebuilds from the nearest list above both, and the selection follows the dragged command when
|
||||
it rode on it.</p>
|
||||
<h2 id="nesting">Nesting</h2>
|
||||
<p>A <code>list</code> entry grows the same structure one level down: its children are its own entries, so nested
|
||||
lists read as sub-trees at any depth, and the very same panel edits them. The differences are the
|
||||
scope — the root list, versus the node's own dotted path — and the drop-out zone, which appears only
|
||||
in a nested editor. A nested list's node adds an optional title above the embedded editor, and that
|
||||
title is appended to the List name in the row and tree label.</p>
|
||||
<p>Because the mission's own command is always a list, the root and a nested list are one editor at two
|
||||
scopes. A project file whose stored command is something else loads with that command wrapped into
|
||||
the root list, so the panel always has a list to edit.</p>
|
||||
lists read as sub-trees at any depth, and the very same row affordances act on them. The difference
|
||||
is the scope — the root list, versus the node's own dotted path: each List row's <code>+</code> inserts into
|
||||
its own list, and a drop into either lands there. A nested list's panel is the optional title alone,
|
||||
and that title is appended to the List name in the tree label.</p>
|
||||
<p>Because the mission's own command is always a list, the root and a nested list are one row shape at
|
||||
two scopes. A project file whose stored command is something else loads with that command wrapped
|
||||
into the root list, so the branch always has a list to root.</p>
|
||||
<h2 id="where-a-command-is-edited">Where a Command Is Edited</h2>
|
||||
<p>A command's editor renders on its own tree node, below the control bar carrying the operations that
|
||||
rewrite the parent list (Up, Down, Duplicate, Delete):</p>
|
||||
<p>A command's editor renders on its own tree node; the row operations that rewrite the parent list stay
|
||||
on the tree row:</p>
|
||||
<ul>
|
||||
<li>Nine kinds have a bespoke editor: General Config, Machining Motion Resolution,
|
||||
<a class="xref" href="NcFileCommand-panel.html">Program File</a>, <a class="xref" href="NcCodeCommand-panel.html">NC Code</a>,
|
||||
<a class="xref" href="script-command-panel.html">Script</a>, <a class="xref" href="NcOptOption-panel.html">NC Optimization Config</a>,
|
||||
<a class="xref" href="PostExecutionCommand-panel.html">Post-Execution</a>, Record Meshed Geometry and Export Meshed
|
||||
Geometry.</li>
|
||||
<li><code>list</code> is edited inline by the control-bar panel: the optional title over the embedded
|
||||
<a class="xref" href="ListCommand-panel.html">list editor</a>.</li>
|
||||
<li><code>list</code> shows only its optional title on its node; its entries are its tree children, and
|
||||
<a class="xref" href="ListCommand-panel.html">List Command Panel</a> covers what a list is and what moving in and
|
||||
out of one costs.</li>
|
||||
<li>The four remaining Setup kinds — Machining Resolution, Collision Detection, Pause on Failure and
|
||||
Physics — are served by the generic field editor, which renders the command's reflected
|
||||
<code>[CommandField]</code> scalars with server-localized labels. That is what the app does instead of
|
||||
@@ -254,38 +330,59 @@ reads a command, but the catalog does not offer it: a project file that stores t
|
||||
the individual commands it stands for, and the panel serves projects that construct one through the
|
||||
API.</p>
|
||||
<p>The multi-card kinds — General Config, NC Optimization Config and Post-Execution — put their extra
|
||||
cards on section child nodes of the command, one node per card, with the card's own enable flag
|
||||
surfaced as that section node's tree checkbox. Post-Execution's Shot Files Output and Optimization
|
||||
Output sections appear only while the physics preference is on.</p>
|
||||
cards on section child nodes of the command, one node per card. Where a card has its own enable
|
||||
flag — General Config's Meshed Geometry section and each of Post-Execution's five — that flag is the
|
||||
section node's tree checkbox; NC Optimization Config's five sections (Distances, Feedrate, Motion
|
||||
Dynamics, Force & Safety, Compensation) carry no checkbox — its enable switches sit on the command
|
||||
node's own panel instead. Post-Execution's Shot Files Output and Optimization Output sections appear
|
||||
only while the physics preference is on.</p>
|
||||
<h2 id="source-code-path">Source Code Path</h2>
|
||||
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
|
||||
<h3 id="web-application">Web Application</h3>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — this panel: Add Command, the entry
|
||||
rows and their four actions, the three drag landings, and the delete confirmation. It serves the
|
||||
Mission root and, embedded under a command's control bar, every nested <code>list</code> node.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first catalog picker.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — this panel, informational only:
|
||||
whether a project is open, the command count, the empty state and the run-order hint. It changes
|
||||
nothing and emits nothing.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree pane that renders the
|
||||
Mission rows' affordances: the drag handle, the hover-revealed move / duplicate / delete buttons on
|
||||
every command row, the <code>+</code> on every list row (the Mission root included) and the Add Command
|
||||
dialog it opens, plus the drop-indicator styles.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useMissionTreeDrag.ts</code> — the HTML5 drag-and-drop
|
||||
bookkeeping between Mission rows: which rows drag, which receive, the before / after / into mode
|
||||
from the pointer position, and the stamp check that abandons a drop after a mid-drag rebuild.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — builds the page's two roots,
|
||||
Mission above Program; owns the five mission row ops — add, drag move, step, duplicate, delete —
|
||||
through one <code>missionRowOp</code> helper (the busy gate, the open panel's dirty flush, the API call, the
|
||||
scoped rebuild, the post-op selection) and the index translation that carries the expansion set,
|
||||
the Add focus and the selection through each op; drives the command and section checkboxes,
|
||||
holding the same busy gate while a tick's PUTs are on the wire.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first catalog picker;
|
||||
one pick per opening.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — one entry's panel: the
|
||||
move / duplicate / delete control bar over the kind's editor, or over the title input and embedded
|
||||
list editor of a <code>list</code> entry.</li>
|
||||
kind's editor, or the optional title input alone for a <code>list</code> entry. It forwards the editor's
|
||||
dirty-switch gate — and flushes a pending title save — to the host, and relays the Program File
|
||||
editor's multi-pick as a structure change on the parent list carrying the inserted range.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionSectionPanel.vue</code> — the panel of a command's
|
||||
section child, rendering that one card.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — the Mission wave of the Control
|
||||
Tree: the item types, the child builders that carry the recursion, the per-kind editor map, the
|
||||
section definitions and their enable flags, and the kind and category icons.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — builds the Execution root with
|
||||
the Mission branch node above the Program branch, and drives the command and section checkboxes.</li>
|
||||
Tree: the item types, the child builders that carry the recursion, the per-kind editor map, and
|
||||
the section definitions and their enable flags.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/missionKindIcons.ts</code> — the kind and category icons the
|
||||
Add Command dialog shows.</li>
|
||||
<li><code>wwwroot-src/src/api/mission.ts</code> — typed wrapper over <code>/api/Mission/*</code>: <code>listCommandEntries</code>,
|
||||
<code>addEntry</code>, <code>removeEntry</code>, <code>moveEntry</code>, <code>duplicateEntry</code>, <code>reparentEntry</code>, <code>reorderEntries</code>,
|
||||
<code>setListTitle</code>, <code>getCommandCatalog</code>, <code>loadCommandFields</code> / <code>setCommandField</code>, and the per-kind
|
||||
readers and writers.</li>
|
||||
<code>addEntry</code> (with an optional insert index, resolving to the new entry's path), <code>removeEntry</code>,
|
||||
<code>moveEntry</code>, <code>duplicateEntry</code>, <code>reparentEntry</code>, <code>reorderEntries</code>, <code>setListTitle</code>,
|
||||
<code>getCommandCatalog</code>, <code>loadCommandFields</code> / <code>setCommandField</code>, and the per-kind readers and
|
||||
writers.</li>
|
||||
<li><code>wwwroot-src/src/components/mission/GenericCommandPanel.vue</code> — the fallback editor for a catalog
|
||||
kind with no bespoke panel: the command's reflected <code>[CommandField]</code> scalars.</li>
|
||||
<li>The bespoke editors:
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/mission/PreSettingCommandPanel.vue</code></li>
|
||||
<li><code>wwwroot-src/src/components/mission/MachiningMotionResolutionCommandPanel.vue</code></li>
|
||||
<li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code></li>
|
||||
<li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code> — also the one panel-side
|
||||
insert: its multi-pick adds the extra files as new Program File commands right after its own,
|
||||
through <code>addEntry</code> at an insert index.</li>
|
||||
<li><code>wwwroot-src/src/components/mission/NcCodeCommandPanel.vue</code></li>
|
||||
<li><code>wwwroot-src/src/components/mission/ScriptCommandPanel.vue</code></li>
|
||||
<li><code>wwwroot-src/src/components/mission/NcOptOptionCommandPanel.vue</code></li>
|
||||
@@ -294,18 +391,24 @@ kind with no bespoke panel: the command's reflected <code>[CommandField]</code>
|
||||
<li><code>wwwroot-src/src/components/mission/ExportMeshedGeomCommandPanel.vue</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the <code>tree.mission.*</code> strings this panel renders: Add Command,
|
||||
the Commands caption, the no-commands-yet state, the drop-out zone, the run-order hint, the kind
|
||||
display names, the section names and the operation labels.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the <code>tree.mission.*</code> strings: Add Command, the Commands
|
||||
caption, the no-commands-yet state, the run-order hint that names the row affordances, the
|
||||
disabled-command hint, the cancelled-op notice, the kind display names, the section names and the
|
||||
op-context phrases.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/common.ts</code> — the row buttons' titles (Move up, Move down, Duplicate,
|
||||
Delete), the List title's label and the no-project caption.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/dialog.ts</code> — the Delete Command confirmation.</li>
|
||||
<li><code>wwwroot-src/src/router/routes.ts</code> — resolves <code>/mission</code> onto <code>/execution?tree=execution/mission</code>.</li>
|
||||
<li><code>Missions/MissionController.cs</code> — the entry lifecycle (<code>GET list-command/entries</code>,
|
||||
<code>POST list-command/entries</code> and <code>POST list-command/entries/{path}</code> to add at the root or inside a
|
||||
nested list, <code>DELETE list-command/entries/{path}</code>, <code>POST list-command/entries/{path}/move</code>,
|
||||
nested list — at an optional <code>insertIndex</code>, answering the new entry's index and path —
|
||||
<code>DELETE list-command/entries/{path}</code>, <code>POST list-command/entries/{path}/move</code>,
|
||||
<code>PUT list-command/reorder</code>, <code>POST list-command/entries/{path}/duplicate</code> and
|
||||
<code>POST list-command/entries/{path}/reparent</code>), the <code>GET command-catalog</code> the Add Command dialog
|
||||
reads, and the per-command endpoints including the generic <code>commands/{path}/fields[/{key}]</code> pair.
|
||||
<code>reparent</code> is what backs both drag-into-a-list and drop-out-to-the-parent, and it is the endpoint
|
||||
that rejects moving a list into itself or its own descendants.</li>
|
||||
<code>reparent</code> is what backs a drop that changes the entry's list — into another list, or an edge in
|
||||
another list — and it is the endpoint that rejects moving a list into itself or its own
|
||||
descendants; a drop that keeps the list, the tail landing included, goes through <code>reorder</code>.</li>
|
||||
<li><code>Missions/MissionCommandCatalog.cs</code> — reflects every <code>[CommandCatalog]</code> command into the addable
|
||||
set served to Add Command, and creates the picked kind.</li>
|
||||
<li><code>Missions/MissionCommandFields.cs</code> — the reflection layer behind the generic field endpoints: it
|
||||
@@ -326,8 +429,8 @@ one when a project is read.</li>
|
||||
<ul>
|
||||
<li><a class="xref" href="../program.html">Program Branch</a> — the read-only inspection twin of this list: what a
|
||||
run actually read, one node per NC source file</li>
|
||||
<li><a class="xref" href="ListCommand-panel.html">List Command Panel</a> — the same editor one level down, and what moving an entry in or out of a nested list costs</li>
|
||||
<li><a href="../../../manual/run/building-a-mission.html">Building a Mission</a> — the task this panel serves, as a procedure</li>
|
||||
<li><a class="xref" href="ListCommand-panel.html">List Command Panel</a> — the same rows one level down, and what moving an entry in or out of a nested list costs</li>
|
||||
<li><a href="../../../manual/run/building-a-mission.html">Building a Mission</a> — the task this branch serves, as a procedure</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||
@@ -93,14 +93,16 @@
|
||||
the project file, so the script travels with the project. <code>Run</code> evaluates the text against the
|
||||
session shell as the globals object, and when the script returns a sequence of actions that sequence
|
||||
is yielded into the run.</p>
|
||||
<p>The title is what the mission row and the tree node show: the label is composed as <code>Script [title]</code>,
|
||||
falling back to a bare <code>Script</code> while the title is empty. A newly added command starts empty on both
|
||||
clients — no title, no text.</p>
|
||||
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control
|
||||
Tree, below the move / duplicate / delete control bar. A single-purpose kind like this one embeds its
|
||||
whole editor on that node rather than growing section child nodes. Its tree checkbox only decides
|
||||
whether the run plays the command; a disabled script is skipped during play and its editor stays
|
||||
fully usable.</p>
|
||||
<p>The title is what the command's tree row shows: the label is composed as <code>Script [title]</code>, falling
|
||||
back to a bare <code>Script</code> while the title is empty. A newly added command starts empty — no title, no
|
||||
text.</p>
|
||||
<p>The panel renders on the command's own node under the Mission root of the Execution page's Control
|
||||
Tree. The editor pane holds nothing but the editor: the command's move up / move down / duplicate /
|
||||
delete buttons and its drag handle sit on its tree row, and the Add Command <code>+</code> sits on the row of
|
||||
the list that holds it. A single-purpose kind like this one embeds its whole editor on that node
|
||||
rather than growing section child nodes. Its tree checkbox only decides whether the run plays the
|
||||
command; a disabled script is skipped during play — a caption above the title says so — and its
|
||||
editor stays fully usable.</p>
|
||||
<h2 id="layout">Layout</h2>
|
||||
<ul>
|
||||
<li>Head Line
|
||||
@@ -163,9 +165,20 @@ save handed back. Each field is applied only when the body carries it. The respo
|
||||
hash to chain into the next save.</p>
|
||||
<p>Two prompts guard the edges, each with three buttons because neither is a yes/no question:</p>
|
||||
<ul>
|
||||
<li><strong>Unsaved Changes</strong>, raised when the Control Tree tries to move the selection off a command whose
|
||||
save is still pending: Save & switch flushes and then allows the switch, Discard drops the pending
|
||||
write, Cancel keeps the selection where it is.</li>
|
||||
<li><strong>Unsaved Changes</strong>, raised by the switch gate the panel hands the Control Tree host, which runs
|
||||
it before the selection moves off the command and before every mission row op — move, duplicate,
|
||||
delete, drag, Add Command. The op rebuilds the list it acted on, and that rebuild remounts the
|
||||
panel whenever this command sits inside that list (a nested List included); when the panel
|
||||
survives instead, the discard below has only put the autosave to sleep, and the next keystroke
|
||||
resumes it on the same, still-valid path. The gate first lets a save already on the wire land,
|
||||
and prompts only when edits are still staged after it: Save & switch flushes and proceeds only
|
||||
when that save landed — a conflict answered with Cancel leaves the edit staged and refuses the
|
||||
switch; Discard reverts the editor to the last confirmed value and puts the autosave to sleep
|
||||
until the next edit; Cancel keeps the selection where it is. A refused gate drops a row op and
|
||||
says so in a notice ("Cancelled — the open editor keeps its unsaved edits."). A row op cannot
|
||||
reach the prompt while another is in flight — the host's busy gate refuses it first — but a
|
||||
selection change holds no such gate, so a <code>?tree=</code> change arriving while a tree click's prompt is
|
||||
up shares the pending answer instead of replacing it.</li>
|
||||
<li><strong>Script changed elsewhere</strong>, raised when the server rejects the save because the hash no longer
|
||||
matches — another tab, or a project reload, changed the command underneath. The rejection carries
|
||||
the server's current text, title and hash, so the panel can offer Discard & reload, Force
|
||||
@@ -173,8 +186,10 @@ overwrite, or Cancel without a second round trip.</li>
|
||||
</ul>
|
||||
<p>The panel snapshots its command path at mount, and the autosave closes over that snapshot rather
|
||||
than over the live selection, so a flush can never land on whichever command happens to be selected
|
||||
when it fires. After each successful save the tree relabels the node in place instead of rebuilding
|
||||
the branch, which would remount the editor mid-edit.</p>
|
||||
when it fires. That path is an index-based entry path which every structural op re-points, which is
|
||||
why the row ops run the gate above before their rebuild; an op on another row leaves the selection
|
||||
on this editor's own row, re-indexed. After each successful save the tree relabels the node in
|
||||
place instead of rebuilding the branch, which would remount the editor mid-edit.</p>
|
||||
<h2 id="the-compile-gate">The Compile Gate</h2>
|
||||
<p>A script that does not compile does nothing at run time: the command reports the compile failure
|
||||
into the run's message stream and yields no work, so the run continues without it. Starting a run
|
||||
@@ -190,8 +205,15 @@ the whole mission.</p>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/mission/ScriptCommandPanel.vue</code> — this panel: the title row sharing
|
||||
its line with the autosave indicator, the editor below it, the 500 ms autosave, the two
|
||||
three-button prompts, the path snapshot taken at mount, and the change notice that relabels the
|
||||
three-button prompts, the path snapshot taken at mount, the switch gate that waits for a save on
|
||||
the wire and hands a second caller the pending prompt, and the change notice that relabels the
|
||||
tree node.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the command node's
|
||||
slave panel: mounts this editor on the entry path, forwards its switch gate to the host, and
|
||||
shows the disabled caption above the title.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree rows: the drag handle
|
||||
and the move / duplicate / delete buttons on the command's row, and the Add Command <code>+</code> on its
|
||||
list's row.</li>
|
||||
<li><code>wwwroot-src/src/components/widgets/TextEditor.vue</code> — the CodeMirror 6 wrapper: language and
|
||||
read-only swapped through compartments, CRLF normalised on the way in so an unedited file cannot
|
||||
dirty the autosave, an opt-in completion source that overrides the language's own, and a widened
|
||||
@@ -208,14 +230,23 @@ kind union that maps straight onto CodeMirror's completion types.</li>
|
||||
loader, the save that carries the expected hash, and the conflict error that carries the server's
|
||||
current copy.</li>
|
||||
<li><code>wwwroot-src/src/composables/useAutoSave.ts</code> — the debounce, the state machine and the conflict
|
||||
recovery behind the panel's saving, saved and error states.</li>
|
||||
recovery behind the panel's saving, saved and error states; the discard that reverts the editor
|
||||
and sleeps the autosave until the next edit, and the wait for a save already on the wire.</li>
|
||||
<li><code>wwwroot-src/src/components/widgets/AutoSaveIndicator.vue</code> — the status pill beside the title.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — funnels every selection change
|
||||
through the active panel's switch gate, which is how the Unsaved Changes prompt gets its say.</li>
|
||||
and every mission row op through the active panel's switch gate, which is how the Unsaved
|
||||
Changes prompt gets its say; selection is read-only while a row op is in flight, and a refused
|
||||
gate drops the op with a notice.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>script</code> kind to this
|
||||
panel and gives it no section children, so the whole editor lives on the command node.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: both prompts, their buttons, and the
|
||||
load and save error contexts.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: both prompts' titles and messages,
|
||||
the Save & switch, Force overwrite and Discard & reload buttons, and the load and save error
|
||||
contexts.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/common.ts</code> — the shared strings the panel borrows: the “Title
|
||||
(optional)” label, the Cancel button both prompts carry, and the Unsaved Changes prompt's
|
||||
Discard.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the disabled caption and the notice a refused gate raises on
|
||||
a row op.</li>
|
||||
<li><code>Missions/ScriptCompletionController.cs</code> — <code>POST /api/script/completions</code>: a thin wrapper that
|
||||
returns the items, 499 on cancellation and 500 with the message on failure.</li>
|
||||
<li><code>Missions/ScriptCompletionService.cs</code> — the singleton holding one workspace, built from the same
|
||||
|
||||
@@ -87,8 +87,9 @@
|
||||
<article data-uid="Anatomy-ProgramBranch">
|
||||
<h1 id="program-branch">Program Branch</h1>
|
||||
|
||||
<p>Program is the lower of the two Control-Tree branches the Execution page hosts: route <code>/execution</code>,
|
||||
Control-Tree path <code>execution/program</code>, one node per NC source file the session read. It is a
|
||||
<p>Program is the lower of the two roots of the Execution page's Control Tree, Mission being the upper:
|
||||
route <code>/execution</code>, Control-Tree path <code>execution/program</code>, one node per NC source file the session
|
||||
read. It is a
|
||||
read-only view of a run — the file's text, the passes that went over it, the per-line marks the run
|
||||
left behind, and the writeback files the run wrote — assembled from session data rather than from
|
||||
anything typed into it. Its node ids are positional, so an id addresses a node without surviving the
|
||||
@@ -97,9 +98,12 @@ branch growing around it.</p>
|
||||
<p>Mission is what a run executes; Program is what the run read. That one difference sets the rest of
|
||||
the branch:</p>
|
||||
<ul>
|
||||
<li>Mission's nodes edit the project. Program's item types declare a panel and a child builder and
|
||||
nothing else — no enable checkbox (the tree hides the tick on every node that is not a Mission
|
||||
command or an enable-bearing Mission section), no control bar, no add, delete, move or duplicate.</li>
|
||||
<li>Mission's nodes edit the project. Program's item types declare a panel — and, on the root and the
|
||||
file node, a child builder — and nothing else: no enable checkbox (the tree hides the tick on
|
||||
every node that is not a Mission command or an enable-bearing Mission section), none of the row
|
||||
affordances a Mission row carries (no drag handle, no add, delete, move or duplicate button), and
|
||||
no counterpart to Mission's one panel-side structural edit, the multi-pick insert of the
|
||||
<a class="xref" href="mission/NcFileCommand-panel.html">Program File editor</a>.</li>
|
||||
<li>Mission's shape is authored. Program's shape is a consequence: a subprogram file appears on it
|
||||
only because a run followed a call into it.</li>
|
||||
<li>Mission belongs to the project. Program's contents belong to the session — the index behind it is
|
||||
@@ -115,10 +119,10 @@ merge uses, and they share one namespace, so a Program File path and an NC Code
|
||||
alike collapse into one node. A Program File command whose path is still unset is skipped and seeds
|
||||
nothing. A placeholder carries no invocations, so its panel shows the file's text with no marks and
|
||||
an empty, disabled pass selector.</p>
|
||||
<p>The transport bar is the one control the branch does carry, and it is not the branch's own: the
|
||||
primary editor pane pins the <a href="execution-tool-bar.html">Execution Tool Bar</a> above the panel of the
|
||||
Execution root and of every node beneath it, so a run can be started, stepped and reset while a
|
||||
program file is on screen.</p>
|
||||
<p>The branch carries no transport of its own either. The <a href="execution-tool-bar.html">Execution Tool Bar</a>
|
||||
sits in the Control Tree pane's run header — above the tree scroller, beside the execution-status
|
||||
badge, on the Execution page only — so a run can be started, stepped and reset while a program file
|
||||
is on screen, and the editor pane below the tree shows nothing but the selected node's panel.</p>
|
||||
<h2 id="the-nodes-the-branch-mints">The Nodes the Branch Mints</h2>
|
||||
<p>Three item types, each keyed by position rather than by identity.</p>
|
||||
<p><strong>The branch root</strong> (<code>execution/program</code>) carries the summary panel and the child builder that
|
||||
@@ -229,8 +233,8 @@ when it mounts — or through a watcher, when it was already the selected panel.
|
||||
before the first page of text resolves is parked again and re-applied once the line array is sized.</p>
|
||||
<h2 id="when-the-branch-is-rebuilt">When the Branch Is Rebuilt</h2>
|
||||
<ul>
|
||||
<li><strong>Page initialization.</strong> Building the Execution root builds the branch, and only when a project is
|
||||
loaded; without one it stays empty.</li>
|
||||
<li><strong>Page initialization.</strong> Building the Execution page's two roots builds the branch, and only when
|
||||
a project is loaded; without one the root stands with no children.</li>
|
||||
<li><strong>Any change in the broadcast execution status.</strong> The status the hub reports is one of
|
||||
<code>NoProject</code>, <code>Ready</code>, <code>Running</code>, <code>Paused</code> and <code>Finished</code>, and the host re-reads the branch
|
||||
whenever that value changes. It deliberately does not take the structural-change path used
|
||||
@@ -239,9 +243,10 @@ keep re-opening a branch the reader had closed. The panels pick up <strong>part<
|
||||
the replaced nodes: the path caption, the pass selector, the inline wording and the executed-line
|
||||
count are all derived from the node, but the file text is not — it is fetched once per page on
|
||||
mount and on scroll, with no watcher on the path, and the panel is not remounted because its key
|
||||
is built from the node id, which is positional and therefore unchanged. A rebuild that puts a
|
||||
different file at the same index leaves the previous file's text on screen under the new node's
|
||||
caption and marks.</li>
|
||||
— the node id, the node key and the mission stamp — reduces on a Program node to the id alone,
|
||||
the other two parts being empty, and the id is positional and therefore unchanged. A rebuild that
|
||||
puts a different file at the same index leaves the previous file's text on screen under the new
|
||||
node's caption and marks.</li>
|
||||
<li><strong>The refresh button on the root panel.</strong> This one does take the structural-change path: it
|
||||
re-reads the file tree from the current session and expands the branch.</li>
|
||||
</ul>
|
||||
@@ -315,16 +320,18 @@ selector, the Follow toggle, the paged line viewer, the execution marks, the ste
|
||||
converted-line badges, and the cursor and hover wiring.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ProgramConversionFilePanel.vue</code> — one written file: the
|
||||
paged line viewer and the source-line links back into the file panel.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — declares the branch root under
|
||||
the Execution root, re-reads it on every execution-status change without expanding it, and hides
|
||||
the tick on every node that is not a Mission command or an enable-bearing Mission section.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — declares the branch root as the
|
||||
Execution page's second root, below Mission, re-reads it on every execution-status change without
|
||||
expanding it, and hides the tick on every node that is not a Mission command or an enable-bearing
|
||||
Mission section.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/itemTypes.ts</code> — the node shape carrying the program
|
||||
bookkeeping, the merged item-type registry, and the eager subtree builder.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree pane that renders the
|
||||
branch's nodes and binds the tree's strict tick strategy.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — mounts the selected node's panel,
|
||||
forwards its selection request to the host, and pins the transport bar above every Execution-scope
|
||||
node.</li>
|
||||
branch's nodes, binds the tree's strict tick strategy, and pins the run header — the transport bar
|
||||
and the execution-status badge — above the tree on the Execution page.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — mounts the selected node's panel
|
||||
under a key built from the node id, the node key and the mission stamp — the last two empty on
|
||||
every Program node — and forwards its selection request to the host.</li>
|
||||
<li><code>wwwroot-src/src/api/ncProgram.ts</code> — the typed client for the file tree, the paged lines, the line
|
||||
marks, the syntax piece, the sentence-to-step mapping and both directions of conversion links.</li>
|
||||
<li><code>wwwroot-src/src/api/clStrip.ts</code> — the step-select and step-enter posts a line click and a line
|
||||
@@ -363,8 +370,11 @@ inline node and whose text is that node's only source.</li>
|
||||
</ul>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a class="xref" href="mission/mission-root-panel.html">Mission Root Panel</a> — the editable twin: the command list this branch reports on, and
|
||||
the only place the NC file list is changed</li>
|
||||
<li><a class="xref" href="mission/mission-root-panel.html">Mission Root Panel</a> — the editable twin: the command list this branch reports on. Its
|
||||
Add Command, drag, move, duplicate and delete ops live on the Control Tree rows and act on
|
||||
commands of any kind; the root's own panel is informational — a no-project note when no project
|
||||
is loaded, otherwise the command count with an Add Command prompt while that count is zero, and
|
||||
the run-order hint in either case</li>
|
||||
<li><a class="xref" href="index.html">Execution Page</a> — the page that hosts both branches, and the transport, canvas and charts
|
||||
the branch's selections drive</li>
|
||||
</ul>
|
||||
|
||||
@@ -92,8 +92,9 @@ page at <code>/execution</code> and the General Setup page at <code>/general-set
|
||||
host — <code>useControlTreeHost('execution')</code> or <code>useControlTreeHost('equipment')</code> — provides it to its
|
||||
panes under one injection key, and the host owns everything after that: the node graph, the branch
|
||||
builders, the selection and the <code>?tree=</code> query that carries it, the editor panel a selection resolves
|
||||
to, and the mission enable ticks. The Tool House page at <code>/tool-house</code> reuses the same node shape and
|
||||
the same item-type registry but renders a branch as nested tabs and creates no host.</p>
|
||||
to, the mission enable ticks, and every structural operation on the Mission branch. The Tool House
|
||||
page at <code>/tool-house</code> reuses the same node shape and the same item-type registry but renders a branch
|
||||
as nested tabs and creates no host.</p>
|
||||
<div class="IMPORTANT">
|
||||
<h5>Important</h5>
|
||||
<p>Node ids are role paths, not identities that survive a version change. Anatomy makes no claim that
|
||||
@@ -105,7 +106,10 @@ for the migration hop that keeps an older link resolving.</p>
|
||||
<ul>
|
||||
<li><code>id</code> — the node's role path, slash-separated, whose first segment is the owning page's scope
|
||||
(<code>execution/…</code>, <code>equipment/…</code>, <code>toolhouse/…</code>). This is the addressing surface: the <code>?tree=</code> query,
|
||||
the persisted expansion list and the persisted last selection all hold ids.</li>
|
||||
the persisted expansion list and the persisted last selection all hold ids. The General Setup
|
||||
page's root carries its scope as its own id, <code>equipment</code>; the Execution page has no node with the
|
||||
bare <code>execution</code> id — its two roots are <code>execution/mission</code> and <code>execution/program</code>, and the
|
||||
segment is a scope key only.</li>
|
||||
<li><code>label</code>, <code>labelKey</code>, <code>labelParams</code> — the display text; see <a href="#display-labels">Display Labels</a>.</li>
|
||||
<li><code>itemType</code> — the registry key that decides the node's editor and its child builder.</li>
|
||||
<li><code>key</code> — the bound object. In the geometry and equipment branches it is an IndexService key,
|
||||
@@ -126,7 +130,9 @@ therefore survives a rebuild, which is why expansion state, the URL and the land
|
||||
keyed on ids. Two id families are positional rather than role-based: Mission entries are
|
||||
<code>${parentId}/${index}</code> and Program files are <code>${parentId}/${index}</code>, so moving or deleting a mission
|
||||
command renumbers its siblings and a link to one names a position in the list rather than that
|
||||
command.</p>
|
||||
command. The host keeps three id sets of its own that must follow the rows rather than the numbers —
|
||||
the persisted expansion list, the Add Command focus and the selection — and translates all three
|
||||
through every mission row operation it runs; see <a href="#the-structure-changed-event">the row operations</a>.</p>
|
||||
<h2 id="the-item-type-registry">The Item-Type Registry</h2>
|
||||
<p><code>ITEM_TYPES</code> maps an <code>itemType</code> string onto a <code>TreeItemDef</code> carrying up to three members:</p>
|
||||
<ul>
|
||||
@@ -144,10 +150,11 @@ binds it to the node's key. The two composite geometry kinds do not embed nested
|
||||
<code>TransformationGeom</code> grows an inner-geometry and an
|
||||
inner-transformer slot, and <code>GeomCombination</code> grows one slot per item, so the tree owns the structure
|
||||
and every panel stays shallow.</p>
|
||||
<p>The map is one flat namespace assembled in <code>itemTypes.ts</code>: the <code>Group</code> stem type, the geometry,
|
||||
transformer, workpiece-leaf, thermal-condition and spindle entries, and the Execution root's own type
|
||||
are written inline, and five per-wave registries are spread in beside them. The three roots the panel
|
||||
host renders itself — Machine Tool, Fixture and Workpiece — have no entry here at all.</p>
|
||||
<p>The map is one flat namespace assembled in <code>itemTypes.ts</code>: the <code>Group</code> stem type and the geometry,
|
||||
transformer, workpiece-leaf, thermal-condition and spindle entries are written inline, and five
|
||||
per-wave registries are spread in beside them. The Execution page's two roots are registry types —
|
||||
<code>MissionRoot</code> and <code>ProgramRoot</code>, from their waves — and no wrapper type stands over them. The three
|
||||
roots the panel host renders itself — Machine Tool, Fixture and Workpiece — have no entry here at all.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -160,7 +167,7 @@ host renders itself — Machine Tool, Fixture and Workpiece — have no entry he
|
||||
<tr>
|
||||
<td>Mission</td>
|
||||
<td><code>missionItemTypes.ts</code></td>
|
||||
<td><code>MissionRoot</code>, <code>MissionCommand</code>, <code>MissionSection</code>; section children at <code>${command.id}/${sectionId}</code>; the per-kind bespoke editors, with a generic field editor as the fallback</td>
|
||||
<td><code>MissionRoot</code>, whose panel is informational — the command count and the run-order hint that names the row affordances; <code>MissionCommand</code>, whose panel is the kind's editor, or only a Title field for a List; <code>MissionSection</code>; section children at <code>${command.id}/${sectionId}</code>; the per-kind bespoke editors, with a generic field editor as the fallback</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Program</td>
|
||||
@@ -219,15 +226,50 @@ correct only while the change stays inside the emitting panel's own branch.</li>
|
||||
<li><code>selectId</code> — the selection to adopt afterwards. It is assigned directly, <strong>bypassing the
|
||||
dirty-switch gate</strong>, because the emitting panel is being replaced on purpose. A <code>null</code> clears the
|
||||
selection.</li>
|
||||
<li><code>inserted</code> — entries a panel inserted into a mission list itself: the list node's id, the child
|
||||
index the run starts at and its count. The host then treats the rebuild as a mission operation —
|
||||
it holds the busy gate and slides its index-based ids past the new siblings — rather than as a
|
||||
plain branch refresh.</li>
|
||||
</ul>
|
||||
<p>A mission command's move, duplicate and delete re-scope to the parent list, because those operations
|
||||
rewrite the parent's children, and they name the post-operation selection: the clone's slot after a
|
||||
duplicate, the neighbouring index after a delete, the parent list when the delete emptied it. Moving
|
||||
an entry out of a nested list re-scopes to the grandparent. The controller brand switch and the
|
||||
runner's Object-Management install re-scope to the controller root. The Tool House type selectors and
|
||||
a flute add re-scope to their own node; everything that rewrites the tool collection — a new tool, a
|
||||
duplicate, a delete, an id rename, an Object-Management install — re-scopes to the tool-house root,
|
||||
and a flute delete re-scopes to its fluting parent.</p>
|
||||
<p>One command editor emits the event: the Program File editor, whose multi-pick turns every extra file
|
||||
into a new Program File command inserted right after it, in pick order; the command panel hosting it
|
||||
re-scopes the event to the parent list, keeps that command selected and passes the insert range
|
||||
along. Two panels emit it with no payload and so take the default scope, their own node: the Program
|
||||
root panel's refresh button, which re-reads the file tree from the current session and rebuilds the
|
||||
Program branch through <code>rebuildBranch</code>, so the branch opens under it; and the <code>GeomCombination</code>
|
||||
item panel after an item add, an item remove or a clear, since its item slots must be regrown. The
|
||||
controller brand switch and the runner's Object-Management install re-scope to the controller
|
||||
root. The Tool House type selectors and a flute add re-scope to their own node; everything that
|
||||
rewrites the tool collection — a new tool, a duplicate, a delete, an id rename, an
|
||||
Object-Management install — re-scopes to the tool-house root, and a flute delete re-scopes to its
|
||||
fluting parent.</p>
|
||||
<p>Every other structural change to the Mission branch is an operation of the host itself, not an
|
||||
event, because the tree rows are the only surface that offers it: Add Command, a drag between rows,
|
||||
Move up / Move down, Duplicate and Delete. A drag is HTML5 drag-and-drop between mission rows; every
|
||||
command row drags, the Mission root row only receives, and where the pointer sits in the target row
|
||||
decides the operation. A plain command row has no edge band: it splits at its midline, the upper
|
||||
half putting the dragged command before that row and the lower half after it — a reorder when both
|
||||
share a list, a relocation across lists otherwise. A List row keeps that before / after reading only
|
||||
in its top and bottom quarters; its middle half, and the whole of the Mission root row, take the
|
||||
command into that list, at the tail. A drop onto the dragged row's own subtree is
|
||||
refused, and a drop aborts when a rebuild mid-drag re-stamped the dragged node, since its id may then
|
||||
name another command. All five run through one helper that holds a busy gate
|
||||
(one operation at a time), runs the open panel's dirty-switch gate, calls the Mission API, translates
|
||||
the expansion list and the Add Command focus through the operation, rebuilds the branch of the list
|
||||
or lists it rewrote — the one list, or the nearest list above both ends of a cross-list drag — and
|
||||
only then translates the selection and names any post-operation selection, since the ids it names
|
||||
exist only after the rebuild. A refused gate drops the operation and says so in a notification
|
||||
("Cancelled — the open editor keeps its unsaved edits."); the delete's own confirm dialog runs
|
||||
before the gate, so a cancelled delete forces no save prompt on the open editor.</p>
|
||||
<p>The selection moves only when it rides on the acted-on row — that row itself, or a section or
|
||||
nested entry under it. Then it follows a stepped or dragged command, lands on the clone after a
|
||||
duplicate, and after a delete lands on the nearest remaining entry of that list, or on the list
|
||||
node itself once the list is empty. Otherwise the editor the user is in stays on its own,
|
||||
re-indexed row. Add Command never moves the selection: it reveals the new row and makes it the
|
||||
focus, so a run of adds lands in order. The focus is the command most recently selected — a section
|
||||
row counts for its owning command — or the last one added, and an Add Command from a list row's <code>+</code>
|
||||
inserts right after that focus when the focus is a direct entry of that list, and at the list's
|
||||
tail otherwise; the Mission root row's <code>+</code> therefore never chases a focus inside a nested list.</p>
|
||||
<h3 id="whole-tree-rebuilds-and-the-refreshes-that-are-not-rebuilds">Whole-tree rebuilds, and the refreshes that are not rebuilds</h3>
|
||||
<p><code>rebuildTree()</code> replaces the root array outright, and runs after an Object-Management swap of the
|
||||
machine tool or the fixture, after a blank machining chain is created, and after either runner-suit
|
||||
@@ -258,30 +300,38 @@ to the model, and the pages' canvases draw that model; the group stems and the M
|
||||
Workpiece roots have no field editor to commit for at all.</p>
|
||||
<h2 id="selection-and-the-dirty-switch-gate">Selection and the Dirty-Switch Gate</h2>
|
||||
<p>Every selection change funnels through <code>requestSelect(id)</code>. It returns immediately when the id is
|
||||
already selected; otherwise it awaits the mounted panel's optional <code>tryConsumeBeforeSwitch()</code> and
|
||||
abandons the switch when that returns false.</p>
|
||||
already selected; it refuses outright while a mission row operation, or a tick's own writes, are in
|
||||
flight — the operation ends by naming the post-operation selection, which would silently undo a
|
||||
change landed during its rebuild; otherwise it awaits the mounted panel's optional
|
||||
<code>tryConsumeBeforeSwitch()</code> and abandons the switch when that returns false.</p>
|
||||
<p>Three entrances use it: a click in the tree, a change to the URL's <code>?tree=</code> value, and a <code>select-node</code>
|
||||
event from the mounted panel — the wire the panel host puts on every registry panel, so a group stem's
|
||||
child list, a mission list's entry row and the Program branch's conversion jumps all arrive through
|
||||
that one. A fourth path — the <code>selectId</code> of a structure change — assigns the selection directly and
|
||||
skips the gate.</p>
|
||||
child list and the Program branch's conversion jumps both arrive through that one. Two paths assign
|
||||
the selection directly and skip the gate: the <code>selectId</code> of a structure change, and the
|
||||
post-operation selection of a mission row operation, which has already run the gate itself.</p>
|
||||
<p>There is no “nothing selected” state. Re-clicking the selected row makes the tree yield <code>null</code>, and
|
||||
that is ignored; an empty <code>?tree=</code> lands on the persisted last selection for that page when the built
|
||||
tree still contains it, and on the page's root otherwise. The editor row is therefore always alive,
|
||||
tree still contains it, and otherwise on the page's root — General Setup on the equipment host, and
|
||||
Mission, the first of its two roots, on the execution host. The editor row is therefore always alive,
|
||||
and reclaiming its height is the row's own collapse toggle rather than a deselection.</p>
|
||||
<p>The gate itself is registered by the panel host: the mounted registry panel is handed to the host
|
||||
through a template ref, and the host asks that instance for <code>tryConsumeBeforeSwitch</code>. Panels that
|
||||
write one field per request need no gate and register none. One panel exposes it —
|
||||
<code>MissionCommandSlavePanel</code>:</p>
|
||||
<ul>
|
||||
<li>on a <code>list</code> entry it flushes the debounced title save while the command path is still live, then
|
||||
allows the switch;</li>
|
||||
<li>on any other entry it forwards its inner editor's gate. Today only the script editor has one: with
|
||||
unsaved text it asks save, discard or cancel, returning false on cancel and on a flush that ends in
|
||||
an error.</li>
|
||||
<li>on a <code>list</code> entry it waits for a title save already on the wire, then flushes the debounced title
|
||||
save while the command path is still live, and allows the switch only when that save landed;</li>
|
||||
<li>on any other entry it forwards its inner editor's gate. Two editors have one. The Script editor
|
||||
first lets a save already on the wire land, then with unsaved text asks save, discard or cancel:
|
||||
cancel returns false, discard reverts to the last confirmed text and puts the autosave to sleep
|
||||
until the next keystroke, and save proceeds only when the flush landed — a conflict answered with
|
||||
Cancel leaves the edit staged and the switch refused. The NC Code editor waits for a save on the
|
||||
wire, drains its debounced field save, and returns false when that save failed.</li>
|
||||
</ul>
|
||||
<p>The same gate is run before duplicating a command, so the clone is made from what has just been typed
|
||||
rather than from the last saved state.</p>
|
||||
<p>The same gate runs before every mission row operation, not only before a selection change, because
|
||||
the operation's rebuild remounts the open editor and mission paths are index-based: a debounced save
|
||||
that outlived the remount would land on whichever command slid into the path it captured at mount.
|
||||
For the same reason both the NC Code editor and the list title cancel, never flush, on unmount.</p>
|
||||
<h2 id="display-labels">Display Labels</h2>
|
||||
<p><code>nodeDisplayLabel(n)</code> returns the translation of <code>labelKey</code> — with <code>labelParams</code> interpolated — when
|
||||
one is set, and the verbatim <code>label</code> otherwise. <code>labelKey</code> is therefore the form every role label the
|
||||
@@ -316,10 +366,14 @@ the selection's type registers no panel.</li>
|
||||
key, and the mission stamp where the node has one. So the editor remounts when the selection moves,
|
||||
when the bound object's key is re-minted, and when the Mission branch was rebuilt beneath it. That
|
||||
third term is exactly why the mission label refresh above mutates the node instead of rebuilding.</p>
|
||||
<p>On the Execution page the editor row grows a header: the transport bar is pinned above the scroll area
|
||||
whenever the Execution root or any of its descendants is selected, so the run controls never scroll
|
||||
away; that one instance also owns the transport's function-key shortcuts, which are attached for as
|
||||
long as it is mounted.</p>
|
||||
<p>The editor row carries nothing but the editor. The run controls sit in the tree pane instead: on the
|
||||
Execution page the Control Tree pane pins a run header above its tree scroller — the transport bar
|
||||
and the live execution-status badge — whatever the selection is. It rides the pane's content rather
|
||||
than the dock's expansion header because that header is the same component on General Setup, which
|
||||
renders neither piece. This is the page's sole <code>ExecutionToolBar</code>, so it owns the F5–F8 shortcuts,
|
||||
and because the dock keeps the tree pane mounted while its row is collapsed, a collapsed tree row
|
||||
does not drop them. When the tree column narrows, the six-button strip scrolls horizontally and the
|
||||
badge never shrinks, so the run state is the last thing a resize can hide.</p>
|
||||
<p>A pure <code>Group</code> stem is not a node without an editor. <code>Group</code> registers <code>GroupInfoPanel</code>, whose body is
|
||||
the stem's intro line followed by a clickable list of its children; a row click emits <code>select-node</code>
|
||||
and the host moves the selection there. The General Setup root, the two Anchor stems, the workpiece
|
||||
@@ -341,7 +395,10 @@ a mission section that carries its own enable flag. Writing the ticked set walks
|
||||
any depth: a command whose state changed is PUT to the Mission API and, on success, has the new state
|
||||
copied onto its section children; a section whose state changed is dispatched to its kind's writer. A
|
||||
failed write raises a toast and leaves the model untouched, so the getter re-derives the old value and
|
||||
the box snaps back.</p>
|
||||
the box snaps back. The ticks share the mission operations' busy gate in both directions: a tick
|
||||
during a row operation is ignored — it would write to the node's pre-operation path — and the box
|
||||
snaps back the same way, while a tick's own writes hold the gate so no row operation can overtake
|
||||
them on the server and land the enable flag on whichever command slid into the ticked path.</p>
|
||||
<p>A row dims when it is itself disabled — a disabled command, or a section whose own flag is off — or
|
||||
when an ancestor command is disabled, which is how a disabled command greys its whole subtree while
|
||||
each descendant keeps its own state. The switch decides only whether the command runs: a disabled
|
||||
@@ -350,17 +407,43 @@ command stays fully editable.</p>
|
||||
<ul>
|
||||
<li>Left Dock — both tree pages, one nav-bar button toggling the whole column
|
||||
<ul>
|
||||
<li><strong>Control Tree</strong> Expansion Row — collapses in place, keeping its header; stays mounted while
|
||||
collapsed, so the tree keeps its scroll position
|
||||
<li><strong>Control Tree</strong> Expansion Row — collapses in place, keeping its header, which is the same
|
||||
page-neutral header on both pages; stays mounted while collapsed, so the tree keeps its scroll
|
||||
position and the run header keeps its shortcuts
|
||||
<ul>
|
||||
<li>Tree — one root row per page: <strong>Execution</strong> or <strong>General Setup</strong>
|
||||
<li>Run Header — Execution page only, pinned above the tree scroller and separated from it by a
|
||||
rule
|
||||
<ul>
|
||||
<li>Execution Transport Bar — the six transport buttons; the strip scrolls horizontally when the
|
||||
column is narrower than it</li>
|
||||
<li>Execution Status Badge — the status label in its status colour; never shrinks</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Tree — the Execution page has two root rows, <strong>Mission</strong> above <strong>Program</strong>; the General Setup
|
||||
page has one, <strong>General Setup</strong>
|
||||
<ul>
|
||||
<li>Drag Handle — on every mission command row, List rows included, immediately before the
|
||||
label. It is the first thing the row's own header renders, but the tree puts the expand
|
||||
arrow, on a row with children, and then the enable checkbox ahead of that header, so the
|
||||
handle sits to the checkbox's right rather than at the row's left edge. The Mission root row
|
||||
has none. While a drag is under way the dragged row dims, a line along the target row's top
|
||||
or bottom edge marks a before / after drop, and a tinted target row marks a drop into that
|
||||
list</li>
|
||||
<li>Node Row — the label is a real link to this node's <code>?tree=</code> URL on the page, so the browser's
|
||||
context menu offers open-in-new-tab and copy-link; a plain left click keeps the in-app
|
||||
selection instead of navigating, while a modified or middle click opens a tab and leaves the
|
||||
current selection where it is. No icons are rendered.</li>
|
||||
current selection where it is. No node icons are rendered.</li>
|
||||
<li>Node CheckBox — mission command rows, and mission section rows carrying an enable flag</li>
|
||||
<li>Execution Status Badge — on the <strong>Execution</strong> root row only</li>
|
||||
<li>Row Operations — on every mission command row, right-aligned: <strong>Move up</strong>, <strong>Move down</strong>,
|
||||
<strong>Duplicate</strong> and <strong>Delete</strong>. Absent from the layout at rest, so a resting label keeps the
|
||||
column's full width, and shown on the hovered row and on the selected row; on a device with
|
||||
no hover they are always shown. Move up is disabled on a list's first entry, Move down on its
|
||||
last, and all four while an operation is in flight</li>
|
||||
<li>Add Command — the <code>+</code> at the right edge of the Mission root row and of every List row,
|
||||
always visible, scoped to that row's list; disabled without an open project and while an
|
||||
operation is in flight. It opens the Add Command dialog — a search box over the command
|
||||
catalog, grouped by category, which fetches the catalog on every opening and accepts one
|
||||
pick per opening</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Spinner and “Loading project…” — shown instead of the tree until the first build lands</li>
|
||||
@@ -372,7 +455,6 @@ down to a 120 px editor floor and a 100 px tree floor</li>
|
||||
<li><strong>Editor</strong> Expansion Row — its header carries the selection breadcrumb, the node path joined with
|
||||
slashes, and falls back to <strong>Editor</strong>; stays mounted while collapsed
|
||||
<ul>
|
||||
<li>Execution Transport Bar — Execution page, while an Execution-scope node is selected</li>
|
||||
<li>The selected node's editor panel, or “Select an item in the Control Tree to edit it here.”</li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -405,17 +487,28 @@ when the project changes, and a host is therefore created once per project per p
|
||||
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the host: the two scopes' root
|
||||
builders, the selection gate, the <code>?tree=</code> sync, the mission ticks, the rebuild entry points, the
|
||||
re-index and Object-Management handlers, and the reactive surface the panes consume.</li>
|
||||
builders, the selection gate, the <code>?tree=</code> sync, the mission ticks, the five mission row
|
||||
operations with their shared busy gate and id translation, the rebuild entry points, the re-index
|
||||
and Object-Management handlers, and the reactive surface the panes consume.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useMissionTreeDrag.ts</code> — the drag-and-drop bookkeeping
|
||||
between mission rows: which rows drag, the drop mode from the pointer's position in the target
|
||||
row, and the row classes behind the drop indicators.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/itemTypes.ts</code> — the <code>ControlNode</code> and <code>TreeItemDef</code> shapes,
|
||||
the <code>SlotCtx</code> hooks, the structure-change payload, <code>nodeDisplayLabel</code> / <code>nodeDisplayInfo</code>, the
|
||||
geometry and transformer builders, the <code>ITEM_TYPES</code> map and <code>buildSubtree</code>.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree column: the node anchors,
|
||||
the click handling that keeps a plain click in-app, and the execution-status badge.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree column: the Execution
|
||||
page's run header with the transport bar and the execution-status badge, the node anchors, the
|
||||
click handling that keeps a plain click in-app, the drag handles, the row operations, the Add
|
||||
Command <code>+</code> and the dialog it opens.</li>
|
||||
<li><code>wwwroot-src/src/components/execution/ExecutionToolBar.vue</code> — the six transport buttons, and the
|
||||
F5–F8 shortcuts the sole instance registers.</li>
|
||||
<li><code>wwwroot-src/src/utils/executionStatusPresent.ts</code> — the badge's status label and colour.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first command picker
|
||||
over the server-served catalog.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ControlTreeDock.vue</code> — the two-row dock and the height
|
||||
divider that sets the editor row's stored pixel height.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — the panel host: the three inline
|
||||
root types, the registry lookup, the remount key, the gate registration and the transport header.</li>
|
||||
root types, the registry lookup, the remount key and the gate registration.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ContentSlavePanel.vue</code> — the General Setup content column
|
||||
and its unkeyed content panel.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/GroupInfoPanel.vue</code> — a group stem's intro and its
|
||||
@@ -433,10 +526,22 @@ the core leaves every runner grows, and the snapshot flags that decide which bra
|
||||
<li><code>wwwroot-src/src/components/controlTree/toolHouseItemTypes.ts</code> — the Tool House wave and its
|
||||
<code>tool-<id></code> role paths.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/runnerSuitItemTypes.ts</code> — the two runner-suit leaves.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the command control bar, and
|
||||
the only panel that exposes a dirty-switch gate.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — the Mission root's informational
|
||||
panel: the command count and the run-order hint.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/ProgramRootPanel.vue</code> — the Program root's summary panel
|
||||
and the refresh button that emits a payload-less <code>structure-changed</code>.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/GeomCombinationTreePanel.vue</code> — the combination's item list,
|
||||
whose add, remove and clear emit the same payload-less event.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — a command's editor host: a
|
||||
List's Title field with its debounced save, and the only panel that exposes a dirty-switch gate.</li>
|
||||
<li><code>wwwroot-src/src/components/mission/ScriptCommandPanel.vue</code> — the autosaving editor whose gate is
|
||||
forwarded, with its save / discard / cancel prompt.</li>
|
||||
<li><code>wwwroot-src/src/composables/useAutoSave.ts</code> — the Script editor's autosave: the flush, the wait
|
||||
for a save on the wire, and the discard that sleeps the instance until the next edit.</li>
|
||||
<li><code>wwwroot-src/src/components/mission/NcCodeCommandPanel.vue</code> — the second forwarded gate: the
|
||||
debounced field save it drains, and the unmount that cancels instead of flushing.</li>
|
||||
<li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code> — the one command editor that emits
|
||||
<code>structure-changed</code>, with the <code>inserted</code> range of its multi-pick.</li>
|
||||
<li><code>wwwroot-src/src/components/panels/PanelExpansion.vue</code> — the expansion row both dock rows are built
|
||||
from.</li>
|
||||
<li><code>wwwroot-src/src/composables/useViewPrefs.ts</code> — the device-local expansion list, last selections,
|
||||
|
||||
@@ -148,7 +148,7 @@ A bump discards every cached page and rebuilds it, so each page initializes on i
|
||||
watching for project changes itself.</li>
|
||||
<li>Bottom footer — the routine-progress bar: the latest foreground message with a recent-messages history menu on the left, the live session status in the middle, and in-flight background job progress on the right. See <a class="xref" href="bottom-message-bar.html">Message Section on Main Panel</a>.</li>
|
||||
</ul>
|
||||
<p>The menu bar carries no run tool bars at all: the transport controls ride the <a class="xref" href="../execution/index.html">Execution Page</a>‘s primary panel header and the view controls ride its canvas panel header. What the menu bar keeps instead is the page's set of column quick-toggles, the connection badge, the active page's title, the <code>Show Log</code> button and — when authentication is on — the logout button. The toggles follow whichever tree page is current: four on the Execution page (control dock, canvas, strip charts, step info) and three on General Setup (control dock, content, canvas); the Tool House page lays itself out with plain splitters and gets none. The connection badge is Execution-only — the other pages’ canvases carry their own in-panel badges.</p>
|
||||
<p>The menu bar carries no run tool bars at all: the transport controls and the execution status badge ride the run header the <a class="xref" href="../execution/index.html">Execution Page</a>‘s Control Tree pane pins above its tree, and the view controls ride its canvas panel header. What the menu bar keeps instead is the page's set of column quick-toggles, the connection badge, the active page's title, the <code>Show Log</code> button and — when authentication is on — the logout button. The toggles follow whichever tree page is current: four on the Execution page (control dock, canvas, strip charts, step info) and three on General Setup (control dock, content, canvas); the Tool House page lays itself out with plain splitters and gets none. The connection badge is Execution-only — the other pages’ canvases carry their own in-panel badges.</p>
|
||||
<h2 id="project-menu-behavior">Project Menu Behavior</h2>
|
||||
<p>The <code>Project Path Text Field</code> displays the current project path when a project is loaded. It is implemented as a pure text field (not a button) that allows users to select and copy the path.</p>
|
||||
<p>The <code>Project</code> Menu manages <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a> with the following operations:</p>
|
||||
|
||||
Reference in New Issue
Block a user