Archived
deploy.
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bottom Message Bar | HiAPI-C# 2025 </title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="title" content="Bottom Message Bar | HiAPI-C# 2025 ">
|
||||
|
||||
|
||||
<link rel="icon" href="../../img/HiAPI.favicon.ico">
|
||||
<link rel="stylesheet" href="../../public/docfx.min.css">
|
||||
<link rel="stylesheet" href="../../public/main.css">
|
||||
<meta name="docfx:navrel" content="../../toc.html">
|
||||
<meta name="docfx:tocrel" content="toc.html">
|
||||
|
||||
<meta name="docfx:rel" content="../../">
|
||||
|
||||
|
||||
|
||||
<meta name="loc:inThisArticle" content="In this article">
|
||||
<meta name="loc:searchResultsCount" content="{count} results for "{query}"">
|
||||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||||
<meta name="loc:tocFilter" content="Filter by title">
|
||||
<meta name="loc:nextArticle" content="Next">
|
||||
<meta name="loc:prevArticle" content="Previous">
|
||||
<meta name="loc:themeLight" content="Light">
|
||||
<meta name="loc:themeDark" content="Dark">
|
||||
<meta name="loc:themeAuto" content="Auto">
|
||||
<meta name="loc:changeTheme" content="Change theme">
|
||||
<meta name="loc:copy" content="Copy">
|
||||
<meta name="loc:downloadPdf" content="Download PDF">
|
||||
|
||||
<script type="module" src="./../../public/docfx.min.js"></script>
|
||||
|
||||
<script>
|
||||
const theme = localStorage.getItem('theme') || 'auto'
|
||||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
|
||||
<header class="bg-body border-bottom">
|
||||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||||
<div class="container-xxl flex-nowrap">
|
||||
<a class="navbar-brand" href="../../index.html">
|
||||
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
|
||||
|
||||
</a>
|
||||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<i class="bi bi-three-dots"></i>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navpanel">
|
||||
<div id="navbar">
|
||||
<form class="search" role="search" id="search">
|
||||
<i class="bi bi-search"></i>
|
||||
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="container-xxl">
|
||||
<div class="toc-offcanvas">
|
||||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<nav class="toc" id="toc"></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="actionbar">
|
||||
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
|
||||
<nav id="breadcrumb"></nav>
|
||||
</div>
|
||||
|
||||
<article data-uid="Anatomy-MessageSection">
|
||||
<h1 id="bottom-message-bar">Bottom Message Bar</h1>
|
||||
|
||||
<p>The Bottom Message Bar displays application-level notifications at the bottom of the Main Panel. This is the <strong>UI Error Notification</strong> channel — see <a class="xref" href="../../technique/api-foundations/message-management.html">Message Management</a> for how it fits into the overall message architecture.</p>
|
||||
<h2 id="message-handling">Message Handling</h2>
|
||||
<p>The Bottom Message Bar is connected to <a class="xref" href="../../api/Hi.Common.Messages.MessageBoardUtil.html">MessageBoardUtil</a> (or <code>ILogger</code> with level-filtered treatment). When a notification is triggered:</p>
|
||||
<ol>
|
||||
<li>The <code>Brief Message Text Field</code> content is updated</li>
|
||||
<li>The message is appended to the daily log file at <code>logs/log-{DateTime.Now:yyyy-MM-dd}.txt</code></li>
|
||||
</ol>
|
||||
<p>The second step belongs to the logging path rather than to the bar, and only one client shares it.
|
||||
The WPF brief field is fed by a logger provider, so a message that reaches the field has already
|
||||
gone to the file sink. The web footer is fed by the routine-progress store instead: what lands there
|
||||
is client-side, and it reaches the server's daily log only when the server logged it too — no part
|
||||
of the shell posts a message to the log-append endpoint.</p>
|
||||
<h3 id="message-types">Message Types</h3>
|
||||
<p>The <a class="xref" href="../../api/Hi.Common.Messages.MessageFlag.html">MessageFlag</a> determines the display behavior:</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Flag</th>
|
||||
<th>Display Behavior</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.Common.Messages.MessageFlag.html#Hi_Common_Messages_MessageFlag_Exception">Exception</a></td>
|
||||
<td>Alert style, shown in Message Bar</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.Common.Messages.MessageFlag.html#Hi_Common_Messages_MessageFlag_Warning">Warning</a> and above</td>
|
||||
<td>Shown in Message Bar</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.Common.Messages.MessageFlag.html#Hi_Common_Messages_MessageFlag_Info">Info</a> and below</td>
|
||||
<td>Logged only, not shown in Message Bar</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="NOTE">
|
||||
<h5>Note</h5>
|
||||
<p>When the message is an <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.exception">Exception</a>, the brief message shows <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.exception.message">Message</a> while the full exception details are logged to file.</p>
|
||||
</div>
|
||||
<h2 id="platform-specific-layouts">Platform-Specific Layouts</h2>
|
||||
<h3 id="wpf-application">WPF Application</h3>
|
||||
<p>The WPF version uses a fixed bottom bar:</p>
|
||||
<ul>
|
||||
<li><strong>Message Section Bottom Bar</strong>
|
||||
<ul>
|
||||
<li>Brief Message Text Field (selectable for copy)</li>
|
||||
<li>Show Log Button</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 id="web-application">Web Application</h3>
|
||||
<p>The web version docks a single dense bar along the bottom of the layout — <code>AppFooter.vue</code>, not a
|
||||
stack of toasts:</p>
|
||||
<ul>
|
||||
<li><strong>Routine Progress Footer Bar</strong>
|
||||
<ul>
|
||||
<li>Brief Message Text Field — the latest foreground message behind its severity glyph, reading
|
||||
<code>Ready</code> while there is none, with the full text and caption on hover</li>
|
||||
<li>Recent Messages Button — a history menu over the capped foreground list, with a clear action</li>
|
||||
<li>Session Status Strip — the live execution cursor and latest session message, rendering nothing
|
||||
at all until there is activity</li>
|
||||
<li>Background Progress Zone — one in-flight job's spinner or progress ring and its message, which
|
||||
disappears when the job ends</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Transient notifications are a second channel beside the bar rather than the bar itself: toasts are
|
||||
Quasar notifications, anchored bottom-right and auto-hiding on a timeout that does not vary with
|
||||
severity. A boot patch mirrors every one of them into the footer's foreground history, which is what
|
||||
keeps a toast reviewable after it fades.</p>
|
||||
<h2 id="show-log-button">Show Log Button</h2>
|
||||
<p>The <code>Show Log</code> button is the only entrance to the log screen, and the two clients answer it
|
||||
differently.</p>
|
||||
<p>In the web application it is a router link in the menu bar's right-hand group — not on this bar —
|
||||
and it opens the Log Viewer as a full page inside the shell. See
|
||||
<a class="xref" href="../platform/log-viewer.html">Log Viewer Page</a> for that screen's toolbar, its auto-refresh interval, its
|
||||
copy and download actions and the states of its text area.</p>
|
||||
<p>In the WPF client the button sits at the right end of this bar. It looks for the current day's file
|
||||
under the client's own <code>logs</code> folder and, when it is there, opens it with whatever application the
|
||||
operating system associates with the file type; when it is not, it reports that in a message box
|
||||
instead of opening anything.</p>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a class="xref" href="main-panel.html">Main Panel</a> — the window frame this bar is docked in</li>
|
||||
<li><a class="xref" href="session-message-panel.html">Session Message Panel</a> — the session-scoped message surface, as distinct from this app-level one</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||
<div class="contribution d-print-none">
|
||||
</div>
|
||||
|
||||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="affix">
|
||||
<nav id="affix"></nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="container-xxl search-results" id="search-results"></div>
|
||||
|
||||
<footer class="border-top text-secondary">
|
||||
<div class="container-xxl">
|
||||
<div class="flex-fill">
|
||||
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,134 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>App Shell | HiAPI-C# 2025 </title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="title" content="App Shell | HiAPI-C# 2025 ">
|
||||
|
||||
|
||||
<link rel="icon" href="../../img/HiAPI.favicon.ico">
|
||||
<link rel="stylesheet" href="../../public/docfx.min.css">
|
||||
<link rel="stylesheet" href="../../public/main.css">
|
||||
<meta name="docfx:navrel" content="../../toc.html">
|
||||
<meta name="docfx:tocrel" content="toc.html">
|
||||
|
||||
<meta name="docfx:rel" content="../../">
|
||||
|
||||
|
||||
|
||||
<meta name="loc:inThisArticle" content="In this article">
|
||||
<meta name="loc:searchResultsCount" content="{count} results for "{query}"">
|
||||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||||
<meta name="loc:tocFilter" content="Filter by title">
|
||||
<meta name="loc:nextArticle" content="Next">
|
||||
<meta name="loc:prevArticle" content="Previous">
|
||||
<meta name="loc:themeLight" content="Light">
|
||||
<meta name="loc:themeDark" content="Dark">
|
||||
<meta name="loc:themeAuto" content="Auto">
|
||||
<meta name="loc:changeTheme" content="Change theme">
|
||||
<meta name="loc:copy" content="Copy">
|
||||
<meta name="loc:downloadPdf" content="Download PDF">
|
||||
|
||||
<script type="module" src="./../../public/docfx.min.js"></script>
|
||||
|
||||
<script>
|
||||
const theme = localStorage.getItem('theme') || 'auto'
|
||||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
|
||||
<header class="bg-body border-bottom">
|
||||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||||
<div class="container-xxl flex-nowrap">
|
||||
<a class="navbar-brand" href="../../index.html">
|
||||
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
|
||||
|
||||
</a>
|
||||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<i class="bi bi-three-dots"></i>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navpanel">
|
||||
<div id="navbar">
|
||||
<form class="search" role="search" id="search">
|
||||
<i class="bi bi-search"></i>
|
||||
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="container-xxl">
|
||||
<div class="toc-offcanvas">
|
||||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<nav class="toc" id="toc"></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="actionbar">
|
||||
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
|
||||
<nav id="breadcrumb"></nav>
|
||||
</div>
|
||||
|
||||
<article data-uid="Anatomy-Shell">
|
||||
<h1 id="app-shell">App Shell</h1>
|
||||
|
||||
<p>The frame every route renders inside. <code>MainLayout.vue</code> is mounted once and stays mounted: the menu
|
||||
bar across the top, the notification bar along the bottom, and a router outlet between them that
|
||||
each page fills. Nothing here belongs to one screen, and nothing here disappears when the route
|
||||
changes.</p>
|
||||
<p>Ordered outward from the window frame: the panel that hosts every route, then the bars it docks,
|
||||
then the menus it drops.</p>
|
||||
<h2 id="pages">Pages</h2>
|
||||
<ul>
|
||||
<li><a href="main-panel.html">Main Panel</a> — The window itself: the menu bar, the router outlet, and the chrome that stays put while pages come and go</li>
|
||||
<li><a href="bottom-message-bar.html">Bottom Message Bar</a> — The UI-notification channel docked at the bottom of the Main Panel, and how a message reaches it</li>
|
||||
<li><a href="session-message-panel.html">Session Message Panel</a> — The four session message sinks and the tabbed panel that presents them; a runtime reset clears three of them and leaves the NC Manipulation sink standing</li>
|
||||
<li><a href="preference-menu.html">Preference Menu</a> — The Preference dropdown: the settings it carries, and where the web client keeps the ones it does not</li>
|
||||
<li><a href="language-selection-submenu.html">Language Selection SubMenu</a> — The nested language picker, and when the chosen locale is applied</li>
|
||||
</ul>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a href="../conventions/index.html">Conventions</a> — the rules the shell applies, message handling first</li>
|
||||
<li><a href="../widget/index.html">Widgets</a> — the reusable controls the shell and every page embed</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||
<div class="contribution d-print-none">
|
||||
</div>
|
||||
|
||||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="affix">
|
||||
<nav id="affix"></nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="container-xxl search-results" id="search-results"></div>
|
||||
|
||||
<footer class="border-top text-secondary">
|
||||
<div class="container-xxl">
|
||||
<div class="flex-fill">
|
||||
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,178 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Language Selection SubMenu | HiAPI-C# 2025 </title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="title" content="Language Selection SubMenu | HiAPI-C# 2025 ">
|
||||
|
||||
|
||||
<link rel="icon" href="../../img/HiAPI.favicon.ico">
|
||||
<link rel="stylesheet" href="../../public/docfx.min.css">
|
||||
<link rel="stylesheet" href="../../public/main.css">
|
||||
<meta name="docfx:navrel" content="../../toc.html">
|
||||
<meta name="docfx:tocrel" content="toc.html">
|
||||
|
||||
<meta name="docfx:rel" content="../../">
|
||||
|
||||
|
||||
|
||||
<meta name="loc:inThisArticle" content="In this article">
|
||||
<meta name="loc:searchResultsCount" content="{count} results for "{query}"">
|
||||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||||
<meta name="loc:tocFilter" content="Filter by title">
|
||||
<meta name="loc:nextArticle" content="Next">
|
||||
<meta name="loc:prevArticle" content="Previous">
|
||||
<meta name="loc:themeLight" content="Light">
|
||||
<meta name="loc:themeDark" content="Dark">
|
||||
<meta name="loc:themeAuto" content="Auto">
|
||||
<meta name="loc:changeTheme" content="Change theme">
|
||||
<meta name="loc:copy" content="Copy">
|
||||
<meta name="loc:downloadPdf" content="Download PDF">
|
||||
|
||||
<script type="module" src="./../../public/docfx.min.js"></script>
|
||||
|
||||
<script>
|
||||
const theme = localStorage.getItem('theme') || 'auto'
|
||||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
|
||||
<header class="bg-body border-bottom">
|
||||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||||
<div class="container-xxl flex-nowrap">
|
||||
<a class="navbar-brand" href="../../index.html">
|
||||
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
|
||||
|
||||
</a>
|
||||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<i class="bi bi-three-dots"></i>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navpanel">
|
||||
<div id="navbar">
|
||||
<form class="search" role="search" id="search">
|
||||
<i class="bi bi-search"></i>
|
||||
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="container-xxl">
|
||||
<div class="toc-offcanvas">
|
||||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<nav class="toc" id="toc"></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="actionbar">
|
||||
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
|
||||
<nav id="breadcrumb"></nav>
|
||||
</div>
|
||||
|
||||
<article data-uid="Anatomy-LanguageSelectionSubmenu">
|
||||
<h1 id="language-selection-submenu">Language Selection SubMenu</h1>
|
||||
|
||||
<p>The submenu locates on the <a class="xref" href="preference-menu.html">Preference Menu Dropdown</a>. It is the only
|
||||
place either client offers for changing the interface language. What that choice sets in motion in
|
||||
the web client — the message bundles, the locale applied before the first frame, the single switch
|
||||
function and everything that re-renders behind it — is
|
||||
<a class="xref" href="../platform/i18n.html">Internationalization</a>; this page covers the gesture.</p>
|
||||
<p>The web submenu's model is the application-state store rather than a service handed down by the
|
||||
parent component: it reads the current code and the available-code list from that store and calls
|
||||
the store's language action. Both values are hydrated by the store's server-preferences load, which
|
||||
the shell layout runs on mount — a separate path from the one that decides which locale the first
|
||||
painted frame uses. The WPF client resolves its language manager during start-up, and the manager
|
||||
reads the persisted code out of the user configuration as it is constructed.</p>
|
||||
<h2 id="layout">Layout</h2>
|
||||
<p>The two clients draw the submenu differently.</p>
|
||||
<ul>
|
||||
<li><p>Language Selection SubMenu — WPF application</p>
|
||||
<ul>
|
||||
<li>English RadioButton</li>
|
||||
<li>Simplified Chinese RadioButton</li>
|
||||
<li>Traditional Chinese RadioButton</li>
|
||||
</ul>
|
||||
<p>Three fixed rows in one radio group, ticked at start-up to match the current language.</p>
|
||||
</li>
|
||||
<li><p>Language Selection SubMenu — web application</p>
|
||||
<ul>
|
||||
<li>Language Row — one plain row per code in the store's available-code list, so the rows are
|
||||
whatever the server reports rather than a fixed set of three. Each carries the language's own
|
||||
name from a hard-coded label map, falling back to the raw code for anything the map does not
|
||||
name, with that code beneath it as a caption; the row matching the current language is drawn in
|
||||
the active state. No row carries a radio button or a checkbox.</li>
|
||||
</ul>
|
||||
<p>The parent entry captions the current language, so it reads without opening the submenu.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Choosing a row in the web client closes the popup and makes one call, the store's language action.
|
||||
The store writes the new code optimistically, POSTs it, adopts the current and available lists the
|
||||
server echoes back, and only then switches the live catalogue — so the interface text flips after
|
||||
the server has accepted the value, and the confirmation toast already reads in the language just
|
||||
picked. A rejected write rolls the store back and changes no interface text at all. In the WPF
|
||||
client picking a radio swaps the merged string dictionary in place and saves the code to the user
|
||||
configuration, and the labels follow without a restart.</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>
|
||||
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/AppMenuBar.vue</code> — the nested <code>Preference → Language ▸</code> popup: the row
|
||||
loop over the available codes, the hard-coded self-name map, the active-row marker, and the
|
||||
handler whose single call is the store's language action.</li>
|
||||
<li><code>wwwroot-src/src/stores/appState.ts</code> — the current-code and available-code state, the language
|
||||
action with its optimistic write, its POST-then-apply order and its rollback, and the
|
||||
server-preferences load the shell layout runs on mount.</li>
|
||||
<li><code>wwwroot-src/src/api/preference.ts</code> — the typed wrappers over the two language endpoints.</li>
|
||||
<li><code>Environments/PreferenceController.cs</code> — <code>GET /api/preference/language</code> and its <code>POST</code> twin, both
|
||||
answering <code>success</code>, <code>current</code> and <code>available</code>; <code>languageCode</code> is the name of a field in the POST
|
||||
request body only. An unlisted code is rejected with 400, and an accepted one is written to the
|
||||
persisted <code>UserConfig.LanguageCode</code> and saved.</li>
|
||||
</ul>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a class="xref" href="../conventions/translation-remarks.html">Translation Remarks</a> — the terminology every translated label is held to</li>
|
||||
<li><a class="xref" href="preference-menu.html">Preference Menu Dropdown</a> — the dropdown this sub-menu hangs from</li>
|
||||
<li><a class="xref" href="../platform/i18n.html">Internationalization</a> — the bundles and the switch point this menu drives</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||
<div class="contribution d-print-none">
|
||||
</div>
|
||||
|
||||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="affix">
|
||||
<nav id="affix"></nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="container-xxl search-results" id="search-results"></div>
|
||||
|
||||
<footer class="border-top text-secondary">
|
||||
<div class="container-xxl">
|
||||
<div class="flex-fill">
|
||||
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,306 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Main Panel | HiAPI-C# 2025 </title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="title" content="Main Panel | HiAPI-C# 2025 ">
|
||||
|
||||
|
||||
<link rel="icon" href="../../img/HiAPI.favicon.ico">
|
||||
<link rel="stylesheet" href="../../public/docfx.min.css">
|
||||
<link rel="stylesheet" href="../../public/main.css">
|
||||
<meta name="docfx:navrel" content="../../toc.html">
|
||||
<meta name="docfx:tocrel" content="toc.html">
|
||||
|
||||
<meta name="docfx:rel" content="../../">
|
||||
|
||||
|
||||
|
||||
<meta name="loc:inThisArticle" content="In this article">
|
||||
<meta name="loc:searchResultsCount" content="{count} results for "{query}"">
|
||||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||||
<meta name="loc:tocFilter" content="Filter by title">
|
||||
<meta name="loc:nextArticle" content="Next">
|
||||
<meta name="loc:prevArticle" content="Previous">
|
||||
<meta name="loc:themeLight" content="Light">
|
||||
<meta name="loc:themeDark" content="Dark">
|
||||
<meta name="loc:themeAuto" content="Auto">
|
||||
<meta name="loc:changeTheme" content="Change theme">
|
||||
<meta name="loc:copy" content="Copy">
|
||||
<meta name="loc:downloadPdf" content="Download PDF">
|
||||
|
||||
<script type="module" src="./../../public/docfx.min.js"></script>
|
||||
|
||||
<script>
|
||||
const theme = localStorage.getItem('theme') || 'auto'
|
||||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
|
||||
<header class="bg-body border-bottom">
|
||||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||||
<div class="container-xxl flex-nowrap">
|
||||
<a class="navbar-brand" href="../../index.html">
|
||||
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
|
||||
|
||||
</a>
|
||||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<i class="bi bi-three-dots"></i>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navpanel">
|
||||
<div id="navbar">
|
||||
<form class="search" role="search" id="search">
|
||||
<i class="bi bi-search"></i>
|
||||
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="container-xxl">
|
||||
<div class="toc-offcanvas">
|
||||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<nav class="toc" id="toc"></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="actionbar">
|
||||
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
|
||||
<nav id="breadcrumb"></nav>
|
||||
</div>
|
||||
|
||||
<article data-uid="Anatomy-MainPanel">
|
||||
<h1 id="main-panel">Main Panel</h1>
|
||||
|
||||
<p>The Main Panel is the primary window of the HiNC application, providing navigation and access to all major features.</p>
|
||||
<h2 id="key-models">Key Models</h2>
|
||||
<ul>
|
||||
<li>Project Service
|
||||
<ul>
|
||||
<li><strong>WPF Single-User Desktop Application</strong>: Uses self-hosted <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a></li>
|
||||
<li><strong>Web Service Application</strong>: injects <a class="xref" href="../../api/Hi.MachiningProcs.ProxyProjectService.html">ProxyProjectService</a>, the <a class="xref" href="../../api/Hi.MachiningProcs.IProjectService.html">IProjectService</a> implementation that reaches the session's project across the connection</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>User Service</strong>: <code>UserService</code></li>
|
||||
</ul>
|
||||
<h2 id="layout-structure">Layout Structure</h2>
|
||||
<ul>
|
||||
<li>Top <code>Navigation Menu</code>
|
||||
<ul>
|
||||
<li><p>Brand logo, and in the web application the HiAPI version as an outlined badge beside it. The
|
||||
badge carries the HiNc assembly version reported by the anonymous authentication-status probe
|
||||
the router runs before the first route resolves, so it needs neither a loaded project nor a
|
||||
signed-in session; it is omitted only while that probe has reported no version.</p>
|
||||
</li>
|
||||
<li><p><code>Project Menu Dropdown</code></p>
|
||||
<ul>
|
||||
<li><code>Project Path Text Field</code> — readonly; reads “No Project Loaded” until a project is loaded</li>
|
||||
<li><code>New MenuItem</code></li>
|
||||
<li><code>Load MenuItem</code></li>
|
||||
<li><code>ReLoad MenuItem</code> (web application only)</li>
|
||||
<li><code>Save MenuItem</code></li>
|
||||
<li><code>Save As MenuItem</code></li>
|
||||
<li><code>Close Project MenuItem</code> (web application only, below a separator)</li>
|
||||
</ul>
|
||||
<p>In the web application ReLoad, Save, Save As and Close Project are disabled until a project is loaded, and New, Load and Save As open the shared file-picker dialog with a <code>.hincproj</code> filter. The picker is allowed the Admin and Project roots and is denied the Resource root, which holds read-only templates the project endpoints cannot save through; it asks for the Admin root by name, so that is where it opens, and it seeds its path box with the directory holding the loaded project, or with the admin root itself when there is none. The Project root is one of the two only while a project is loaded: the roots endpoint lists a root only when its directory resolves, and the project directory resolves to nothing until a project is open, so with no project the picker offers Admin alone. The WPF client's dropdown stops at Save As.</p>
|
||||
</li>
|
||||
<li><p><code>Environment Menu Dropdown</code> (WPF application only — the web application has no such dropdown; see below)</p>
|
||||
<ul>
|
||||
<li>Machine Tool MenuItem
|
||||
Open <a class="xref" href="../general-setup/machine-tool.html">Machine Tool Page</a>
|
||||
Sole window in WPF app.
|
||||
The page manages <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_MachiningEquipment">MachiningEquipment</a>.<a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.MachiningEquipment.html#Hi_Machining_MachiningEquipmentUtils_MachiningEquipment_MachiningChain">MachiningChain</a>.</li>
|
||||
<li>Controller MenuItem
|
||||
Open <a class="xref" href="../legacy-controller.html">Legacy Controller Page</a></li>
|
||||
<li>Tool House MenuItem</li>
|
||||
<li>Fixture MenuItem
|
||||
Open <a class="xref" href="../general-setup/fixture.html">Fixture Page</a></li>
|
||||
<li>Workpiece MenuItem
|
||||
Open <a class="xref" href="../general-setup/workpiece.html">Workpiece Page</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p>Mission MenuItem
|
||||
Open <a class="xref" href="../execution/mission/mission-root-panel.html">Mission Page</a>
|
||||
In the web application the Mission editor is a branch of the Execution page's Control Tree; <code>/mission</code> redirects there.</p>
|
||||
</li>
|
||||
<li><p><code>Page Menu Dropdown</code> (web application only) — the three workflow pages in setup order (fill the tool house, set up the equipment, run), then the utilities.</p>
|
||||
<ul>
|
||||
<li>Tool House MenuItem
|
||||
Open <a class="xref" href="../tool-house/index.html">Tool House Page</a></li>
|
||||
<li>General Setup MenuItem
|
||||
The equipment Control Tree — Machine Tool, Spindle Capability, Background, Coolant, Fixture, Workpiece, Controller, in that order — plus the shared equipment canvas. Two further controller branches, CSV Controller and CL Controller, are <a class="xref" href="../general-setup/hidden-controllers.html">hidden by default</a> and are switched on from the Preference dropdown.</li>
|
||||
<li>Execution MenuItem
|
||||
Open <a class="xref" href="../execution/index.html">Execution Page</a></li>
|
||||
<li>File Explorer MenuItem (below a separator). See <a href="../util/index.html">Util Pages</a>.</li>
|
||||
<li>Mechanism Builder MenuItem
|
||||
Open <a class="xref" href="../util/mech-builder.html">Mechanism Builder Page</a></li>
|
||||
<li>Legacy-Controller MenuItem (below a separator)
|
||||
Open <a class="xref" href="../legacy-controller.html">Legacy Controller Page</a></li>
|
||||
</ul>
|
||||
<p>The dropdown is not every route the application has. The Machine Tool page stays reachable by URL for its chain-only canvas preview, the Log Viewer is reached by the <code>Show Log</code> button, and the Fixture, Workpiece, Spindle Capability, Mission and Background / Coolant paths resolve as redirects into the two tree pages.</p>
|
||||
</li>
|
||||
<li><p><a class="xref" href="preference-menu.html">Preference Menu Dropdown</a></p>
|
||||
</li>
|
||||
<li><p><code>Debug Menu Dropdown</code> (WPF application only) — Transformers and Geometry Management, visible only while the client runs in debug mode</p>
|
||||
</li>
|
||||
<li><p>Help MenuItem</p>
|
||||
<ul>
|
||||
<li>HiAPI Version label
|
||||
A label to show the HiNc library version.
|
||||
The web application shows this as a version badge next to the brand logo, with no Help dropdown.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><code>Show Log</code> Button — a button on both clients, not a menu item. In the web application it sits on the menu bar's right side and routes to the Log Viewer page; in the WPF client it sits at the right end of the bottom message bar.
|
||||
The Log Viewer presents the server's application log for the current day, with a manual refresh, a selectable auto-refresh interval, copy to the clipboard, and download of the day's log file for offline analysis.</li>
|
||||
<li>Central <code>Page Panel</code> — one router outlet wrapped in a keep-alive cache keyed on a project epoch: an
|
||||
integer the layout owns, raised by two watchers and read by nothing else. The first watches the project
|
||||
store's path, which New, Load and Save As each assign from the response they get back, which Close Project
|
||||
clears, and which a store-level watcher on the shared execution-status hub adopts from every broadcast — so a
|
||||
project change made in another tab, from another browser, or outside the browser altogether bumps the epoch
|
||||
here as well, and so does the boot status fetch, once, on a service that already has a project open. The
|
||||
second watches a counter the store raises in exactly one place, ReLoad, which is what makes a re-read of the
|
||||
same path remount at all: the backend raises its project-changed event with the path it already had, so the
|
||||
broadcast cannot be told apart from a no-op. Assigning the path it already holds moves neither watcher, so
|
||||
Save on the current path does not remount and neither does a Save As written back onto the path already open.
|
||||
A bump discards every cached page and rebuilds it, so each page initializes on its own mount hook rather than
|
||||
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>In the WPF application the run tool bars belong to the menu shell and appear only while the central panel is the player. The web application does not carry them on the menu bar 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>
|
||||
<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>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Operation</th>
|
||||
<th>Description</th>
|
||||
<th>Example</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>New</td>
|
||||
<td>Creates a new project</td>
|
||||
<td>See <code>DemoBuildGeomOnlyMachiningProject</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Load</td>
|
||||
<td>Opens an existing project</td>
|
||||
<td>See <code>DemoUseMachiningProject</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ReLoad</td>
|
||||
<td>Re-reads the current project from disk, same path</td>
|
||||
<td>—</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Save</td>
|
||||
<td>Saves the current project</td>
|
||||
<td>See <code>DemoBuildGeomOnlyMachiningProject</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Save As</td>
|
||||
<td>Saves the project to a new location</td>
|
||||
<td>See <code>DemoBuildGeomOnlyMachiningProject</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Close</td>
|
||||
<td>Closes the current project and clears the shell</td>
|
||||
<td>—</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>In the web application every Project action reports through two channels: a background progress line on the footer while it runs, then a toast when it lands — positive on success, a “busy” warning when a concurrent action has already claimed the service (HTTP 409), negative otherwise. In the WPF client the operations log through <code>ILogger</code> and, after a load, set the player panel's DispEngine to the isometric view. What a project change drives in the web shell is the layout's keep-alive epoch, not a canvas view: every cached page is discarded and rebuilt.</p>
|
||||
<div class="NOTE">
|
||||
<h5>Note</h5>
|
||||
<p>The web implementation reports through the toast helper and the routine-progress footer store; the WPF client reports through <code>ILogger</code>. Neither routes project messages through MessageUtil. Project I/O is asynchronous on both clients, so the shell stays responsive during file I/O.</p>
|
||||
</div>
|
||||
<h2 id="platform-specific-differences">Platform-Specific Differences</h2>
|
||||
<h3 id="wpf-application">WPF Application</h3>
|
||||
<ul>
|
||||
<li>Only a single instance of each sub-window (Mission, Workpiece, Fixture) can exist at a time</li>
|
||||
<li>There is no menu entry for the run cockpit: the Main Panel itself is the player</li>
|
||||
</ul>
|
||||
<h3 id="web-application">Web Application</h3>
|
||||
<ul>
|
||||
<li>The <a class="xref" href="../execution/index.html">Execution Page</a> is the landing route — <code>/</code> redirects to <code>/execution</code></li>
|
||||
<li>The page URL and panel state are synchronized (bi-directional navigation)</li>
|
||||
<li>There is no Environment dropdown. Machine Tool, Fixture, Workpiece, Controller, Background / Coolant and Spindle Capability are branches of the General Setup page's Control Tree, and Tool House and Execution are pages of their own; the remaining paths resolve as redirects into those pages. The menu bar is therefore <code>Project ▾ | Page ▾ | Preference ▾</code>, and the Controller page is reached from <code>Page ▾</code> as <code>Legacy-Controller</code>.</li>
|
||||
</ul>
|
||||
<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-1">Web Application</h3>
|
||||
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
|
||||
<ul>
|
||||
<li><code>Environments/PreferenceController.cs</code> — the endpoints behind the Preference dropdown.</li>
|
||||
<li><code>Environments/ProjectController.cs</code> — the project endpoints: status, new, load, save, reload, saveas and close, plus the log endpoints.</li>
|
||||
<li><code>Environments/UserService.cs</code> — the shell's user model.</li>
|
||||
<li><code>wwwroot-src/src/components/AppMenuBar.vue</code> — the whole navigation menu.</li>
|
||||
<li><code>wwwroot-src/src/components/AppFooter.vue</code> — the routine-progress footer the layout docks.</li>
|
||||
<li><code>wwwroot-src/src/layouts/MainLayout.vue</code> — the shell that hosts the menu bar, the keep-alive page panel and the footer.</li>
|
||||
<li><code>wwwroot-src/src/router/routes.ts</code> — the routes the Page dropdown targets and the redirect-only legacy paths.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/menu.ts</code> — the menu bar's English labels.</li>
|
||||
<li><code>wwwroot-src/src/stores/project.ts</code> — the six Project actions and the busy error a 409 becomes.</li>
|
||||
<li><code>wwwroot-src/src/stores/routineProgress.ts</code> — the foreground-message and background-progress store the Project handlers share with the footer.</li>
|
||||
<li><code>wwwroot-src/src/composables/useToast.ts</code> — the toasts every Project action ends in.</li>
|
||||
<li><code>wwwroot-src/src/composables/useViewPrefs.ts</code> — the device-local per-page column visibility and the CSV / CL controller switches.</li>
|
||||
<li><code>wwwroot-src/src/composables/useConnectionsHealth.ts</code> — the aggregate state behind the Execution connection badge.</li>
|
||||
<li><code>wwwroot-src/src/components/widgets/FileExplorerDialog.vue</code> — the shared picker New, Load and Save As open.</li>
|
||||
<li><code>wwwroot-src/src/components/widgets/ColumnToggleIcon.vue</code> — the glyph each column quick-toggle draws.</li>
|
||||
<li><code>wwwroot-src/src/pages/LogViewerPage.vue</code> — the Log Viewer the <code>Show Log</code> button opens.</li>
|
||||
</ul>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a class="xref" href="../execution/index.html">Execution Page</a> — the landing page the shell routes to</li>
|
||||
<li><a class="xref" href="preference-menu.html">Preference Menu Dropdown</a> — the third menu on the bar</li>
|
||||
<li><a class="xref" href="bottom-message-bar.html">Bottom Message Bar</a> — the notification bar the shell docks along the bottom</li>
|
||||
<li><a class="xref" href="../general-setup/index.html">General Setup Page</a> — the equipment page the Page menu reaches</li>
|
||||
<li><a class="xref" href="../platform/tree-ids-and-routes.html">Tree Ids and Routes</a> — the route table this bar navigates, and how a <code>?tree=</code> id lands on the page that owns it</li>
|
||||
<li><a class="xref" href="../platform/session-state.html">Session State</a> — the keep-alive this shell wraps the router view in, and what a project change destroys</li>
|
||||
<li><a class="xref" href="../platform/login-and-auth.html">Login and Authentication</a> — the gate in front of this shell, and the sign-out entry on this bar</li>
|
||||
<li><a class="xref" href="../platform/log-viewer.html">Log Viewer Page</a> — the screen the Show Log button opens</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||
<div class="contribution d-print-none">
|
||||
</div>
|
||||
|
||||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="affix">
|
||||
<nav id="affix"></nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="container-xxl search-results" id="search-results"></div>
|
||||
|
||||
<footer class="border-top text-secondary">
|
||||
<div class="container-xxl">
|
||||
<div class="flex-fill">
|
||||
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,194 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Preference Menu Dropdown | HiAPI-C# 2025 </title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="title" content="Preference Menu Dropdown | HiAPI-C# 2025 ">
|
||||
|
||||
|
||||
<link rel="icon" href="../../img/HiAPI.favicon.ico">
|
||||
<link rel="stylesheet" href="../../public/docfx.min.css">
|
||||
<link rel="stylesheet" href="../../public/main.css">
|
||||
<meta name="docfx:navrel" content="../../toc.html">
|
||||
<meta name="docfx:tocrel" content="toc.html">
|
||||
|
||||
<meta name="docfx:rel" content="../../">
|
||||
|
||||
|
||||
|
||||
<meta name="loc:inThisArticle" content="In this article">
|
||||
<meta name="loc:searchResultsCount" content="{count} results for "{query}"">
|
||||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||||
<meta name="loc:tocFilter" content="Filter by title">
|
||||
<meta name="loc:nextArticle" content="Next">
|
||||
<meta name="loc:prevArticle" content="Previous">
|
||||
<meta name="loc:themeLight" content="Light">
|
||||
<meta name="loc:themeDark" content="Dark">
|
||||
<meta name="loc:themeAuto" content="Auto">
|
||||
<meta name="loc:changeTheme" content="Change theme">
|
||||
<meta name="loc:copy" content="Copy">
|
||||
<meta name="loc:downloadPdf" content="Download PDF">
|
||||
|
||||
<script type="module" src="./../../public/docfx.min.js"></script>
|
||||
|
||||
<script>
|
||||
const theme = localStorage.getItem('theme') || 'auto'
|
||||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
|
||||
<header class="bg-body border-bottom">
|
||||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||||
<div class="container-xxl flex-nowrap">
|
||||
<a class="navbar-brand" href="../../index.html">
|
||||
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
|
||||
|
||||
</a>
|
||||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<i class="bi bi-three-dots"></i>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navpanel">
|
||||
<div id="navbar">
|
||||
<form class="search" role="search" id="search">
|
||||
<i class="bi bi-search"></i>
|
||||
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="container-xxl">
|
||||
<div class="toc-offcanvas">
|
||||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<nav class="toc" id="toc"></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="actionbar">
|
||||
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
|
||||
<nav id="breadcrumb"></nav>
|
||||
</div>
|
||||
|
||||
<article data-uid="Anatomy-PreferenceMenu">
|
||||
<h1 id="preference-menu-dropdown">Preference Menu Dropdown</h1>
|
||||
|
||||
<p>The Preference dropdown holds the application's display settings, and it is on the <a class="xref" href="main-panel.html">Main Panel</a>. The server-backed ones are service-wide rather than per-account: one <code>UserService</code> singleton holds one <code>UserConfig</code>, saved to a single <code>UserConfig.xml</code> resolved against the process working directory, so every browser signed in to that service reads and writes the same values. The sign-in cookie carries a user-name claim that nothing outside the authentication endpoints reads, and no preference endpoint is keyed on an account.</p>
|
||||
<p>In the WPF application the menu binds <code>UserService</code>, whose <code>UserConfig</code> holds the persisted values. In the web application the dropdown has two models: Language and Show Physics Options bind the <code>appState</code> store, hydrated from and written back through <code>/api/preference/*</code>, where the server keeps them on <code>UserConfig</code>; the CSV / CL Controller checkboxes bind the device-local <code>useViewPrefs</code> singleton, persisted in the browser's <code>localStorage</code> and never sent to the server.</p>
|
||||
<h2 id="layout">Layout</h2>
|
||||
<ul>
|
||||
<li>Preference Menu Dropdown
|
||||
<ul>
|
||||
<li><a class="xref" href="../execution/step-present-dialog.html">Step Present Preference</a> Button
|
||||
<ul>
|
||||
<li>WPF application: the first entry of the menu, opening the Step Present window.</li>
|
||||
<li>Web application: the editor belongs to the Execution page's Step Info column, where a small icon button in the Step Properties panel header opens it as a modal next to the list it configures.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="xref" href="../execution/graphic-cache-menu.html">Graphic-Cache Dropdown</a>
|
||||
<ul>
|
||||
<li>WPF application: a nested menu of cache fields inside the dropdown.</li>
|
||||
<li>Web application: an entry of the Execution page's <a class="xref" href="../execution/execution-extended-renderingcanvas-tool-bar.html">extended tool bar</a>, under <code>Meshed Geom ▾</code>, which gathers the workpiece rendering-cache settings.</li>
|
||||
<li>Its write is the one preference write that does not persist. <code>POST /api/preference/graphic-cache</code> clamps the requested size between the stored limits, assigns the three fields on the live <code>UserConfig</code> and returns, without calling <code>UserService.SaveUserConfig()</code>. The new value is service-wide and takes effect at once, but it reaches the file only when some later preference save writes the config out.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="xref" href="language-selection-submenu.html">Language Selection SubMenu</a>
|
||||
<ul>
|
||||
<li>The persisted value is <code>UserConfig.LanguageCode</code>; the web application reaches it through <code>GET/POST /api/preference/language</code>, whose response also names the language codes the server supports.</li>
|
||||
<li>In the web application the parent row captions the current language and the sub-menu marks the active code. A successful switch flips the interface text at once, so the confirmation toast already reads in the just-picked language.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>CSV Controller CheckBox
|
||||
<ul>
|
||||
<li>Web application only. The model is <code>useViewPrefs().showCsvController</code> — device-local, stored in the browser's <code>localStorage</code>, not in <code>UserConfig</code>. It is off by default.</li>
|
||||
<li>Checking it adds the <code>CSV Controller</code> node to the General Setup page's Control Tree; unchecking removes it, moving the selection away first when that node is the selected one.</li>
|
||||
<li>The caption under the box says whether the loaded project plays CSV — <code>This project plays CSV</code>, or <code>Not used by this project</code> — read from the <code>referenced</code> flag of <code>GET /api/mech/csv-runner</code>. Opening the dropdown fetches both runner snapshots in parallel, but the fetch is guarded on a loaded project: with none, neither request is made and both captions are cleared to blank. A snapshot that fails to arrive leaves its caption blank as well, so a blank caption states nothing about the project. The guard reaches the captions only — neither checkbox is disabled by it.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>CL Controller CheckBox
|
||||
<ul>
|
||||
<li>The same, for <code>useViewPrefs().showClController</code>, the <code>CL Controller</code> Control Tree node and <code>GET /api/mech/cl-runner</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Show Physics Options CheckBox
|
||||
<ul>
|
||||
<li>The model is <code>UserConfig.ShowPhysicsOptions</code>, reached in the web application through <code>GET/POST /api/preference/show-physics-options</code>.</li>
|
||||
<li>The checkbox is disabled and unchecked if <code>UserService.IsPhysicsLicensed</code> is false: the GET returns the flag ANDed with the licence and the POST forces <code>false</code> without it.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Show Log Button
|
||||
<ul>
|
||||
<li>See <a class="xref" href="bottom-message-bar.html">Message Section</a>.</li>
|
||||
<li>It is not a Preference-dropdown entry on either platform: the WPF application puts it on the bottom message bar, and the web application puts it on the menu bar's right side as an always-visible button that opens the Log Viewer page.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>So the web application's Preference dropdown carries the Language submenu, the CSV Controller and CL Controller visibility checkboxes, and the Show Physics Options checkbox.</p>
|
||||
<p>A server write that fails raises a negative toast and rolls the item back in <code>appState</code>, so the dropdown never shows a language or a physics flag the server did not take.</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>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/components/AppMenuBar.vue</code> — the <code>Preference ▾</code> dropdown itself and the menu bar's <code>Show Log</code> button.</li>
|
||||
<li><code>wwwroot-src/src/stores/appState.ts</code> — the model of the two server-backed items, with the boot-time hydration and the write-back actions.</li>
|
||||
<li><code>wwwroot-src/src/composables/useViewPrefs.ts</code> — the device-local <code>localStorage</code> singleton behind the two controller checkboxes.</li>
|
||||
<li><code>wwwroot-src/src/api/preference.ts</code> — typed wrapper over <code>/api/preference/language</code> and <code>/api/preference/show-physics-options</code>.</li>
|
||||
<li><code>wwwroot-src/src/api/csvRunner.ts</code>, <code>wwwroot-src/src/api/clRunner.ts</code> — the <code>referenced</code> flag each controller caption reports.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — builds or omits the two controller nodes and rebuilds the tree when either checkbox flips.</li>
|
||||
<li><code>wwwroot-src/src/i18n/en/menu.ts</code> — the dropdown's labels and captions.</li>
|
||||
<li><code>wwwroot-src/src/pages/LogViewerPage.vue</code> — the page the <code>Show Log</code> button routes to.</li>
|
||||
<li><code>Environments/PreferenceController.cs</code> — the endpoints. The step-present, show-physics-options, language and execution-layout writes persist through <code>UserService.SaveUserConfig()</code>; the graphic-cache write is the exception, and returns without one.</li>
|
||||
<li><code>Environments/UserConfig.cs</code> — the persisted <code>LanguageCode</code> and <code>ShowPhysicsOptions</code> properties.</li>
|
||||
<li><code>Environments/UserService.cs</code> — owns the single <code>UserConfig</code> the service holds, writes it to <code>UserConfigPath</code>, and answers the physics licence check.</li>
|
||||
<li><code>Program.cs</code> — the one <code>UserService</code> registration behind every server-backed item here, and the configuration path it resolves against the process working directory.</li>
|
||||
</ul>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a class="xref" href="main-panel.html">Main Panel</a> — the menu bar this dropdown sits on</li>
|
||||
<li><a class="xref" href="language-selection-submenu.html">Language Selection SubMenu</a> — the only sub-menu this dropdown nests</li>
|
||||
<li><a class="xref" href="../execution/graphic-cache-menu.html">Graphic-Cache SubMenu</a> — one of the two entries the web client hosts elsewhere</li>
|
||||
<li><a class="xref" href="../execution/step-present-dialog.html">Step Present Preference Page</a> — the other entry the web client hosts elsewhere</li>
|
||||
<li><a class="xref" href="../platform/log-viewer.html">Log Viewer Page</a> — the log screen this menu's namesake route serves</li>
|
||||
<li><a class="xref" href="../general-setup/hidden-controllers.html">Hidden Controller Branches</a> — the two equipment nodes the CSV and CL entries reveal, and what a link to one does while its box is off</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||
<div class="contribution d-print-none">
|
||||
</div>
|
||||
|
||||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="affix">
|
||||
<nav id="affix"></nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="container-xxl search-results" id="search-results"></div>
|
||||
|
||||
<footer class="border-top text-secondary">
|
||||
<div class="container-xxl">
|
||||
<div class="flex-fill">
|
||||
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,220 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Session Message Panel | HiAPI-C# 2025 </title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="title" content="Session Message Panel | HiAPI-C# 2025 ">
|
||||
|
||||
|
||||
<link rel="icon" href="../../img/HiAPI.favicon.ico">
|
||||
<link rel="stylesheet" href="../../public/docfx.min.css">
|
||||
<link rel="stylesheet" href="../../public/main.css">
|
||||
<meta name="docfx:navrel" content="../../toc.html">
|
||||
<meta name="docfx:tocrel" content="toc.html">
|
||||
|
||||
<meta name="docfx:rel" content="../../">
|
||||
|
||||
|
||||
|
||||
<meta name="loc:inThisArticle" content="In this article">
|
||||
<meta name="loc:searchResultsCount" content="{count} results for "{query}"">
|
||||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||||
<meta name="loc:tocFilter" content="Filter by title">
|
||||
<meta name="loc:nextArticle" content="Next">
|
||||
<meta name="loc:prevArticle" content="Previous">
|
||||
<meta name="loc:themeLight" content="Light">
|
||||
<meta name="loc:themeDark" content="Dark">
|
||||
<meta name="loc:themeAuto" content="Auto">
|
||||
<meta name="loc:changeTheme" content="Change theme">
|
||||
<meta name="loc:copy" content="Copy">
|
||||
<meta name="loc:downloadPdf" content="Download PDF">
|
||||
|
||||
<script type="module" src="./../../public/docfx.min.js"></script>
|
||||
|
||||
<script>
|
||||
const theme = localStorage.getItem('theme') || 'auto'
|
||||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
|
||||
<header class="bg-body border-bottom">
|
||||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||||
<div class="container-xxl flex-nowrap">
|
||||
<a class="navbar-brand" href="../../index.html">
|
||||
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
|
||||
|
||||
</a>
|
||||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<i class="bi bi-three-dots"></i>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navpanel">
|
||||
<div id="navbar">
|
||||
<form class="search" role="search" id="search">
|
||||
<i class="bi bi-search"></i>
|
||||
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="container-xxl">
|
||||
<div class="toc-offcanvas">
|
||||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<nav class="toc" id="toc"></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="actionbar">
|
||||
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
|
||||
<nav id="breadcrumb"></nav>
|
||||
</div>
|
||||
|
||||
<article data-uid="Anatomy-SessionMessagePanel">
|
||||
<h1 id="session-message-panel">Session Message Panel</h1>
|
||||
|
||||
<p>Session messages are partitioned by kind into four sinks on <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> (obtained via dependency injection):</p>
|
||||
<ul>
|
||||
<li><a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_ShellProgress">ShellProgress</a> — session-level routine / lifecycle messages (<a class="xref" href="../../api/Hi.MachiningProcs.ShellProgress.html">ShellProgress</a>). Session-scoped: the property is null outside <code>BeginSession</code>/<code>EndSession</code>.</li>
|
||||
<li><a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_NcDiagnosticProgress">NcDiagnosticProgress</a> — play-time NC-pipeline diagnostics (<a class="xref" href="../../api/Hi.NcParsers.NcDiagnosticProgress.html">NcDiagnosticProgress</a>), anchored to the NC source block that raised them wherever the diagnostic has one.</li>
|
||||
<li><a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_StepDiagnosticProgress">StepDiagnosticProgress</a> — diagnostics anchored to a motion step (<a class="xref" href="../../api/Hi.MachiningProcs.StepDiagnosticProgress.html">StepDiagnosticProgress</a>).</li>
|
||||
<li><a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_NcManipulationDiagnosticProgress">NcManipulationDiagnosticProgress</a> — NC-manipulation diagnostics: a second <a class="xref" href="../../api/Hi.NcParsers.NcDiagnosticProgress.html">NcDiagnosticProgress</a>, written by <a class="xref" href="../../api/Hi.MachiningProcs.MachiningSession.html#Hi_MachiningProcs_MachiningSession_ConvertClToNcFiles_">ConvertClToNcFiles</a> and <a class="xref" href="../../api/Hi.MachiningProcs.MachiningSession.html#Hi_MachiningProcs_MachiningSession_OptimizeNcFiles_">OptimizeNcFiles</a>, held apart from the play-time sink so writeback findings never mix into the play pipeline's.</li>
|
||||
</ul>
|
||||
<p>The panel surfaces each sink in its own tab, so one tab holds one message kind. <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_ResetRuntime_">ResetRuntime</a> — which a project change runs — empties the first three, so each of them holds the current project only; the manipulation sink is outside that sweep, cleared only at the start of the conversion or optimization run that fills it, and its rows therefore survive a project change.</p>
|
||||
<h2 id="layout">Layout</h2>
|
||||
<ul>
|
||||
<li>Tab Bar (each tab carries a floating count badge, drawn only while its sink holds messages)
|
||||
<ul>
|
||||
<li>Shell Tab</li>
|
||||
<li>NC Diagnostics Tab</li>
|
||||
<li>Step Diagnostics Tab</li>
|
||||
<li>NC Manipulation Tab</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Per-Tab Content
|
||||
<ul>
|
||||
<li>Filter Toolbar
|
||||
<ul>
|
||||
<li><code>Severity</code> Filter Dropdown</li>
|
||||
<li><code>Category</code> Filter Dropdown</li>
|
||||
<li>Message Text Filter Input</li>
|
||||
<li><code>Reset</code> Button (this tab's three filters, nothing else)</li>
|
||||
<li><code>Export</code> Button</li>
|
||||
<li>Matched / Total Badge (also the tab's hub connection indicator)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Message Table</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="message-table-per-tab">Message Table (per tab)</h2>
|
||||
<p>Each tab renders its sink's message list — <a class="xref" href="../../api/Hi.MachiningProcs.ShellProgress.html#Hi_MachiningProcs_ShellProgress_Messages">Messages</a>, <a class="xref" href="../../api/Hi.MachiningProcs.StepDiagnosticProgress.html#Hi_MachiningProcs_StepDiagnosticProgress_Messages">Messages</a>, or <a class="xref" href="../../api/Hi.NcParsers.NcDiagnosticProgress.html#Hi_NcParsers_NcDiagnosticProgress_Diagnostics">Diagnostics</a> for the two NC-diagnostic sinks — as rows of:</p>
|
||||
<ul>
|
||||
<li><code>Severity</code> (colour-coded via <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html#Hi_Common_Messages_IMessage_GetSeverity">GetSeverity()</a>)</li>
|
||||
<li><code>Anchor</code> — the kind-specific position: none for shell messages, the NC sentence ordinal (<code>Sn <n></code>) for both the play-time and the manipulation NC diagnostics, and the motion step with its sentence ordinal (<code>S<step> · Sn <n></code>) for step diagnostics; an NC diagnostic raised at pipeline level rather than at a source block carries none</li>
|
||||
<li><code>Message</code> — <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html#Hi_Common_Messages_IMessage_GetCategory">GetCategory()</a>, <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html#Hi_Common_Messages_IMessage_GetId">GetId()</a> and <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html#Hi_Common_Messages_IMessage_GetNotification">GetNotification()</a></li>
|
||||
</ul>
|
||||
<p>Only take the last filtered elements (e.g. 500–1000) for user experience. Find the usage example in the code:</p>
|
||||
<pre><code class="lang-csharp" name="Demo_UseSessionMessageHost">internal static void DemoUseSessionMessageHost(LocalProjectService localProjectService)
|
||||
{
|
||||
// Session messages are partitioned by kind into three sinks on LocalProjectService:
|
||||
// - ShellProgress: session-level routine / lifecycle messages
|
||||
// (session-scoped: null outside BeginSession/EndSession).
|
||||
// - NcDiagnosticProgress: NC-pipeline diagnostics, anchored to the NC source sentence.
|
||||
// - StepDiagnosticProgress: diagnostics anchored to a motion step.
|
||||
|
||||
ShellProgress shellProgress = localProjectService.ShellProgress;
|
||||
List<IMessage> shellMessages = shellProgress == null
|
||||
? new List<IMessage>() : shellProgress.Messages.ToList();
|
||||
foreach (IMessage message in shellMessages)
|
||||
Console.WriteLine(
|
||||
$"Shell [{message.GetSeverity()}] {message.GetId()}: {message.GetNotification()}");
|
||||
|
||||
foreach (NcDiagnostic diagnostic in
|
||||
localProjectService.NcDiagnosticProgress.Diagnostics.ToList())
|
||||
{
|
||||
var ncLine = diagnostic.SentenceCarrier?.GetSentence()?.FirstIndexedFileLine;
|
||||
Console.WriteLine(
|
||||
$"NC [{diagnostic.GetSeverity()}] {diagnostic.GetId()}: {diagnostic.GetNotification()}; " +
|
||||
$"File: {ncLine?.FilePath}; LineNo: {ncLine?.GetLineNo()}; NC: {ncLine?.Line}");
|
||||
}
|
||||
|
||||
foreach (StepDiagnostic diagnostic in
|
||||
localProjectService.StepDiagnosticProgress.Messages.ToList())
|
||||
Console.WriteLine(
|
||||
$"Step {diagnostic.StepIndex} [{diagnostic.GetSeverity()}] " +
|
||||
$"{diagnostic.GetId()}: {diagnostic.GetNotification()}");
|
||||
|
||||
File.WriteAllLines("output-session-messages.txt",
|
||||
shellMessages.Select(m =>
|
||||
$"[{m.GetSeverity()}] {m.GetId()}: {m.GetNotification()}"));
|
||||
}
|
||||
</code></pre>
|
||||
<p>Add the update-table event per sink: <a class="xref" href="../../api/Hi.MachiningProcs.StepDiagnosticProgress.html#Hi_MachiningProcs_StepDiagnosticProgress_MessageAdded">MessageAdded</a> / <a class="xref" href="../../api/Hi.NcParsers.NcDiagnosticProgress.html#Hi_NcParsers_NcDiagnosticProgress_MessageAdded">MessageAdded</a>, and for the session-scoped shell sink the app-lifetime bridge <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_OnShellMessageAdded">OnShellMessageAdded</a> (with the matching <code>Cleared</code> events). The updating process has to be called by <a class="xref" href="../conventions/index.html">Loose Manner</a> for user experience.</p>
|
||||
<div class="TIP">
|
||||
<h5>Tip</h5>
|
||||
<p>On window desktop application (WPF), consider use textarea instead of datagrid to MessageTable for better performance. Use padding to show the different columns. And use the font in the textarea that with consistent width.</p>
|
||||
</div>
|
||||
<div class="NOTE">
|
||||
<h5>Note</h5>
|
||||
<p>The message display should be real-time.</p>
|
||||
</div>
|
||||
<h2 id="behavior-of-export-button">Behavior of Export Button</h2>
|
||||
<p>Every tab has its own <code>Export</code>, and it carries that tab's sink alone. It writes the rows the tab is holding — the recent window pulled from that sink, narrowed by that tab's severity, category and text filters — as a CSV of <code>Index,Count,Severity,Category,Id,Anchor,Notification,Detail</code>, named after the sink it came from. It is disabled while the filters match nothing.</p>
|
||||
<h2 id="signalr-implementation-webapi-only">SignalR Implementation (Webapi Only)</h2>
|
||||
<p>One hub per sink — <code>/shellMessageHub</code>, <code>/ncDiagnosticHub</code>, <code>/stepDiagnosticHub</code>, <code>/ncManipulationDiagnosticHub</code> — each with a <code>GetMessages(int limit)</code> pull returning <code>MessagesUpdate { messages, totalCount }</code>. A per-sink broadcast service subscribes its sink's <code>MessageAdded</code>/<code>Cleared</code> and raises a coalesced <code>MessagesChanged</code> notification via <a class="xref" href="../../api/Hi.Common.LooseRunner.html">LooseRunner</a>; the client re-pulls the recent window on each notification (loss-free regardless of how many appends coalesced). The client components connect to the hubs they display to receive real-time updates.</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>
|
||||
<ul>
|
||||
<li>wwwroot-src/src/components/execution/SessionMessagePanel.vue (tabbed panel)</li>
|
||||
<li>wwwroot-src/src/components/execution/SessionMessageTab.vue + MessageRow.vue (per-tab list)</li>
|
||||
<li>wwwroot-src/src/composables/useSessionSinkHub.ts (the four hub composables)</li>
|
||||
<li>Execution/SessionSinkHub.cs (the SignalR hub base; one hub per sink)</li>
|
||||
<li>Execution/SessionSinkBroadcastService.cs + ShellMessageBroadcastService.cs, NcDiagnosticBroadcastService.cs, StepDiagnosticBroadcastService.cs, NcManipulationDiagnosticBroadcastService.cs (subscribe-and-rebroadcast)</li>
|
||||
<li>Execution/SessionSinkDtos.cs (typed DTOs)</li>
|
||||
</ul>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a class="xref" href="../execution/index.html">Execution Page</a> — the page whose main column hosts this panel</li>
|
||||
<li><a class="xref" href="bottom-message-bar.html">Bottom Message Bar</a> — the app-level notification bar, as distinct from these session sinks</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||
<div class="contribution d-print-none">
|
||||
</div>
|
||||
|
||||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="affix">
|
||||
<nav id="affix"></nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="container-xxl search-results" id="search-results"></div>
|
||||
|
||||
<footer class="border-top text-secondary">
|
||||
<div class="container-xxl">
|
||||
<div class="flex-fill">
|
||||
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
<div id="sidetoggle">
|
||||
<div>
|
||||
<div class="sidefilter">
|
||||
<form class="toc-filter">
|
||||
<span class="glyphicon glyphicon-filter filter-icon"></span>
|
||||
<span class="glyphicon glyphicon-remove clear-icon" id="toc_filter_clear"></span>
|
||||
<input type="text" id="toc_filter_input" placeholder="Filter by title" onkeypress="if(event.keyCode==13) {return false;}">
|
||||
</form>
|
||||
</div>
|
||||
<div class="sidetoc">
|
||||
<div class="toc" id="toc">
|
||||
|
||||
<ul class="nav level1">
|
||||
<li>
|
||||
<a href="index.html" name="" title="Overview">Overview</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="main-panel.html" name="" title="Main Panel">Main Panel</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="bottom-message-bar.html" name="" title="Bottom Message Bar">Bottom Message Bar</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="session-message-panel.html" name="" title="Session Message Panel">Session Message Panel</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="preference-menu.html" name="" title="Preference Menu">Preference Menu</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="language-selection-submenu.html" name="" title="Language Selection SubMenu">Language Selection SubMenu</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"Main Panel","href":"main-panel.html","topicHref":"main-panel.html"},{"name":"Bottom Message Bar","href":"bottom-message-bar.html","topicHref":"bottom-message-bar.html"},{"name":"Session Message Panel","href":"session-message-panel.html","topicHref":"session-message-panel.html"},{"name":"Preference Menu","href":"preference-menu.html","topicHref":"preference-menu.html"},{"name":"Language Selection SubMenu","href":"language-selection-submenu.html","topicHref":"language-selection-submenu.html"}]}
|
||||
Reference in New Issue
Block a user