This commit is contained in:
2026-09-12 18:16:27 +08:00
parent b7f55aa631
commit 397a7a8cc4
96 changed files with 1167 additions and 1259 deletions
@@ -133,11 +133,6 @@ is one of its children, so each renders inside the Main Panel's frame and menu b
<td>The machining chain on a canvas of its own, beside a left column that shows either a read-only identity panel or the chain's XML source — two states of one column, chosen with a GUI/XML toggle. A load button installs a chain file into the project. Carries no Page-menu entry and is reached by URL.</td>
</tr>
<tr>
<td><code>/controller/:tab?</code></td>
<td><code>controller</code></td>
<td>The superseded HardNcEnv controller surface. The optional segment mirrors the active tab.</td>
</tr>
<tr>
<td><code>/tool-house/:toolId(\d+)?/:tab?/:subtab?</code></td>
<td><code>tool-house</code></td>
<td>The tool library and the per-tool editor. The three optional segments carry the selected tool and the two nested tab levels.</td>
@@ -170,9 +165,9 @@ is one of its children, so each renders inside the Main Panel's frame and menu b
</tbody>
</table>
<p>The menu bar's Page dropdown holds every one of these that is menu-reachable, in setup order: Tool
House, General Setup and Execution, then File Explorer and Mechanism Builder below a separator,
then the legacy Controller below a second one. The Log Viewer has a button of its own rather than a
menu entry, and <code>/machine-tool</code> has neither — it is reached by URL.</p>
House, General Setup and Execution, then File Explorer and Mechanism Builder below a separator. The
Log Viewer has a button of its own rather than a menu entry, and <code>/machine-tool</code> has neither — it is
reached by URL.</p>
<p>The Tool House route's tool segment is constrained to digits, but all three of its segments are
optional, so a non-numeric segment in the tool position is not rejected: the router skips the tool
parameter and reads that segment as the tab, which is what makes <code>/tool-house/cutter</code> a working tab
@@ -193,6 +188,10 @@ moved into a Control Tree still lands on the editor.</p>
</thead>
<tbody>
<tr>
<td><code>/controller/:rest(.*)*</code></td>
<td><code>/general-setup?tree=equipment/controller</code> — any trailing path is discarded, the retired Controller page's <code>/&lt;tab&gt;</code> segment included, so every form lands on the branch root.</td>
</tr>
<tr>
<td><code>/spindle-capability/:tab?</code></td>
<td><code>/general-setup?tree=equipment/spindle</code>, with <code>/&lt;tab&gt;</code> appended when the segment is one of <code>thermal</code>, <code>gear-shift</code>, <code>dry-run</code>, <code>power</code>, <code>torque</code>. An unrecognised segment is dropped and the branch root is selected.</td>
</tr>
@@ -321,8 +320,9 @@ expansion set still unfolds the branches it names;</li>
<li>as the first step of <code>routeForTreeId</code>, so the id-to-page resolver never sees an unmigrated id.</li>
</ul>
<p>Note what the first rule implies: a bare <code>?tree=controller</code> selects the <code>equipment/controller</code>
branch — the current controller editor on the General Setup page — and has nothing to do with the
<code>/controller</code> route, which is the separate legacy HardNcEnv surface.</p>
branch — the controller editor on the General Setup page — and the redirect-only <code>/controller</code> path
above lands on the same branch, so a bookmark from the retired Controller page's era resolves in
either form.</p>
<h2 id="landing-an-id-on-its-page">Landing an Id on Its Page</h2>
<p><code>TREE_PAGE_ROOTS</code> lists the first segments that name a page: <code>execution</code>, <code>equipment</code> and
<code>toolhouse</code>. <code>spindle</code> is absent on purpose — migration folds it into <code>equipment/…</code> before any root
@@ -356,18 +356,18 @@ it, whereas the tool step is tested on its own, so a second segment that is not
can carry is discarded either way — an id pointing at a single flute contour under
<code>…/cutter/contours/fluting/…</code> lands on the nearest tab the URL can express. The same three name
lists are imported by the page itself, so the tab set and the translation cannot drift apart.</p>
<p>Once on the page, the tab segments are kept in step with the tabs by <code>useRouteTabs</code>, the composable
the Controller route uses as well. It gives each tab level one route param, a valid-name set and a
<p>Once on the page, the tab segments are kept in step with the tabs by <code>useRouteTabs</code>, a composable
whose only consumer this page is. It gives each tab level one route param, a valid-name set and a
default; a nested level may declare which parent values make it apply, and while its parent is
something else the level is <strong>dormant</strong> — its segment is dropped from the URL while its reference
quietly remembers the last value, so returning to that parent tab returns to the sub-tab it had.
The Tool House sub-tab level applies under <code>cutter</code> and <code>holder</code> only, and both its valid set and
its default depend on which of the two is showing. A segment the level does not recognise resolves
to that default rather than failing. Canonicalisation runs on the first mount and on every
keep-alive re-entry, which is why a bare <code>/controller</code> becomes <code>/controller/coordinate-table</code> and a
bare <code>/tool-house</code> acquires its tab segments. The tool segment is not one of the composable's
levels: the page fills it in itself, adopting the URL's tool when the project holds it and the first
tool in the list otherwise, then replacing the URL with what it adopted. That resolver reacts to the
keep-alive re-entry, which is why a bare <code>/tool-house</code> acquires its tab segments. The tool segment
is not one of the composable's levels: the page fills it in itself, adopting the URL's tool when the
project holds it and the first tool in the list otherwise, then replacing the URL with what it
adopted. That resolver reacts to the
<code>toolId</code> param and to the tool list rather than to page activation, so it also re-points the URL
when the list changes underneath it.</p>
<p>The Tool House page never reads or writes <code>?tree=</code>. A <code>toolhouse/…</code> id reaches it only by way of
@@ -452,8 +452,8 @@ and the retitle hook registered with the i18n module.</li>
<code>rawTreePathOfRoute</code>, <code>treePathOfRoute</code>, the two selection/URL watchers and the unguarded
controller-checkbox watcher beside them, <code>landingSelection</code>, <code>applyRouteSelection</code> and
<code>syncUrlBack</code>, plus the build-time reveal of a URL-named CSV or CL controller node.</li>
<li><code>wwwroot-src/src/composables/useRouteTabs.ts</code> — the tab-to-param sync used by the Tool House and
Controller routes, including dormant levels and the keep-alive re-entry canonicalisation.</li>
<li><code>wwwroot-src/src/composables/useRouteTabs.ts</code> — the tab-to-param sync the Tool House route uses,
including dormant levels and the keep-alive re-entry canonicalisation.</li>
<li><code>wwwroot-src/src/pages/ToolHousePage.vue</code> — consumes the shared tab lists, resolves the tool from
its path param, and navigates by route name when the tool changes.</li>
<li><code>wwwroot-src/src/pages/FileExplorerPage.vue</code> — mirrors the browsed location into the route's