Preference Menu Dropdown
The Preference dropdown holds the application's display settings, and it is on the Main Panel. The server-backed ones are service-wide rather than per-account: one UserService singleton holds one UserConfig, saved to a single UserConfig.xml 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.
The dropdown has two models, and its layout follows them: Language and Show Physics Options, at the top, bind the appState store, hydrated from and written back through /api/preference/*, where the server keeps them on UserConfig; the five checkboxes of the Optional Nodes & Charts submenu below them — the CSV / CL Controller checkboxes, the two sensor-chart checkboxes and the Block Info panel's raw JSON checkbox — bind the device-local useViewPrefs singleton, persisted in the browser's localStorage and never sent to the server.
Layout
- Preference Menu Dropdown
- Step Present Preference Button
- 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.
- Graphic-Cache Dropdown
- Web application: the
Graphic Cachebutton on the Execution page's extended tool bar, which opens this panel directly. - Its write is the one preference write that does not persist.
POST /api/preference/graphic-cacheclamps the requested size between the stored limits, assigns the three fields on the liveUserConfigand returns, without callingUserService.SaveUserConfig(). 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.
- Web application: the
- Language Selection SubMenu
- The persisted value is
UserConfig.LanguageCode; the web application reaches it throughGET/POST /api/preference/language, whose response also names the language codes the server supports. - 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.
- The persisted value is
- Show Physics Options CheckBox
- The model is
UserConfig.ShowPhysicsOptions, reached in the web application throughGET/POST /api/preference/show-physics-options. - The checkbox is disabled and unchecked if
UserService.IsPhysicsLicensedis false: the GET returns the flag ANDed with the licence and the POST forcesfalsewithout it.
- The model is
- Optional Nodes & Charts SubMenu
- Web application only, below a separator: a row that opens a nested menu to its right, built like the Language row, holding the five device-local checkboxes grouped under the page each one adds to. The group headers are
menu.preference.pageGroupfilled with the page switches' own labels, so they readEquipment PageandExecution Page. - The row carries a caption only while the loaded project plays a kind whose box is clear —
This project plays CSV,This project plays CL, orThis project plays CSV / CL— and none otherwise. It is computed from the same tworeferencedflags as the controller captions below and from the two boxes, so ticking the box it names takes that kind off the caption at once. - Equipment Page Head Label
- CSV Controller CheckBox
- The model is
useViewPrefs().showCsvController— device-local, stored in the browser'slocalStorage, not inUserConfig. It is off by default. - Checking it adds the
CSV Controllernode to the Equipment page's Control Tree; unchecking removes it, moving the selection away first when that node is the selected one. - The caption under the box says whether the loaded project plays CSV —
This project plays CSV, orNot used by this project— read from thereferencedflag ofGET /api/mech/csv-runner. 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 flags are cleared, so the two captions go blank and the submenu row carries none. A snapshot that fails to arrive leaves its flag cleared as well, so a blank caption states nothing about the project. A project change clears both flags — and asks again at once while the dropdown is open — and an answer that lands after a newer question, or after the project it answers for has gone, is dropped; a snapshot taken while the service has no project open leaves its flag cleared too. The menu keeps the flags rather than the sentences, so after a language switch the captions read in the new language as soon as the dropdown next opens, before its snapshots arrive again. The guard reaches the captions only — neither checkbox is disabled by it.
- The model is
- CL Controller CheckBox
- The same, for
useViewPrefs().showClController, theCL ControllerControl Tree node andGET /api/mech/cl-runner.
- The same, for
- CSV Controller CheckBox
- Execution Page Head Label — below a separator
- Sensor Cutting Force Cycle CheckBox
- The model is
useViewPrefs().showSensorForceCycle— device-local like the two controller checkboxes, and off by default. Its label is the chart's own title, from thecharts.titlesstrings rather than a menu string. - Checking it renders the
Sensor Cutting Force Cyclepanel in the Execution page's Step Info column (Cycle-Line Charts); unchecking removes the panel outright. Whether that panel is expanded or collapsed is a separate, server-held flag the checkbox leaves alone, so checking it again brings the panel back as it was left. Both sensor charts plot shot data measured on a physical rig — an external dynamometer, a spindle moment sensor — which is why they start hidden.
- The model is
- Sensor Spindle Moment Cycle CheckBox
- The same, for
useViewPrefs().showSensorSpindleMomentCycleand theSensor Spindle Moment Cyclepanel.
- The same, for
- Block Info · Raw JSON CheckBox
- The model is
useViewPrefs().syntaxDevView— device-local like the boxes above it, and off by default;data-testidmenu-preference-block-raw-json. Its label is built from the panel's own strings,execution.syntax.title+' · '+execution.syntax.view.json, so it follows the panel's name; its caption ismenu.preference.blockRawJsonNote, For development and support: adds a view switch and a Copy JSON button to the panel’s title bar. - Checking it adds the
CNC view/Raw JSONswitch to the title bar of the Step Info column's Block Info panel, and, in the raw JSON view, the Copy JSON button, absent while the block's record could not be read. The switch's position isuseViewPrefs().syntaxView('cnc'by default, so the first tick still shows the CNC view), and the raw JSON shows only while both hold, so unchecking drops the panel back to the CNC view at once, with no reload, and checking it again brings back the view last picked. Both live in the singleton rather than in the panel, because a collapsed panel is unmounted. The CNC view is the same whether the box is checked or not (Inspecting a Step).
- The model is
- Sensor Cutting Force Cycle CheckBox
- Web application only, below a separator: a row that opens a nested menu to its right, built like the Language row, holding the five device-local checkboxes grouped under the page each one adds to. The group headers are
- Log Viewer Entry
- See Log Viewer Page.
- It is not a Preference-dropdown entry, although the route path
/preference/logis named after this menu: it is an entry of the menu bar's Help dropdown, below a separator, and opens the Log Viewer page in place; when the web service runs on its own, it is that dropdown's last entry.
- Step Present Preference Button
So the web application's Preference dropdown carries, top to bottom, the Language submenu, the Show Physics Options checkbox and, below a separator, the Optional Nodes & Charts submenu, which holds the CSV Controller and CL Controller visibility checkboxes under its Equipment Page header and the Sensor Cutting Force Cycle, Sensor Spindle Moment Cycle and Block Info · Raw JSON checkboxes under its Execution Page header.
No checkbox carries a close directive, so ticking or clearing one leaves the dropdown open, and the submenu with it when the box is in one; Esc closes the innermost open menu first. Every open menu closes on a route change, and a box can cause one: when the physics switch withdraws the selected node, or either controller box flips while the Equipment page's selection is a controller node whose box is off — the one just cleared, or one a link revealed — the selection moves, and while that tree's page is shown the URL follows it (Control Tree, Hidden Controller Branches). A Language row is the one entry that closes on purpose, and it takes the dropdown with it (Language Selection SubMenu).
A language write that fails raises a negative toast and rolls the item back in appState. When the newest physics-flag write fails, appState waits for the older writes of a double click, 5 s at most, and reads the preference back: the checkbox then shows what the server holds — the value the server last answered with when that read fails too — and the toast is raised unless the read-back shows the value asked for. Either way the dropdown never shows a language or a physics flag the server did not take.
Source Code Path
See HiNC App Anatomy for git repository links.
wwwroot-src/src/components/AppMenuBar.vue— thePreference ▾dropdown itself with its two nested submenus, the snapshot fetch it runs as it opens and the captions computed from the tworeferencedflags, and the Help dropdown'sLog Viewerentry.wwwroot-src/src/stores/appState.ts— the model of the two server-backed items, with the boot-time hydration and the write-back actions.wwwroot-src/src/composables/useViewPrefs.ts— the device-locallocalStoragesingleton behind the two controller checkboxes, the two sensor-chart checkboxes and the raw JSON checkbox, with the Block Info view that last one unlocks.wwwroot-src/src/api/preference.ts— typed wrapper over/api/preference/language,/api/preference/show-physics-optionsand/api/preference/license-caps— the last a read of the two caps a licence may carry in this process,{ resolutionCapRatio, stepCap, stepsTaken, hasResolutionCap, hasStepCap }(0 = no cap;stepsTakenis process-wide; the response'sleaseStepsLeftis left out), which no dropdown item shows; what a cap means for the current workpiece isGET /api/Workpiece/resolution-cap, see Workpiece.wwwroot-src/src/api/csvRunner.ts,wwwroot-src/src/api/clRunner.ts— thereferencedflag each controller caption reports.wwwroot-src/src/components/controlTree/useControlTreeHost.ts— builds or omits the two controller nodes and rebuilds the tree when either checkbox flips.wwwroot-src/src/i18n/en/menu.ts— the dropdown's own labels and captions,menu.preference.optionalNodesCharts,menu.preference.pageGroupandmenu.preference.blockRawJsonNoteamong them, and themenu.page.*switch labels the submenu's group headers reuse.wwwroot-src/src/i18n/en/charts.ts— the two chart titles the sensor-chart checkboxes take as their labels.wwwroot-src/src/i18n/en/execution.ts—execution.syntax.titleandexecution.syntax.view.json, the two panel strings the raw JSON checkbox's label is built from.wwwroot-src/src/pages/ExecutionPage.vue— renders each sensor cycle chart panel only while its checkbox is checked.wwwroot-src/src/components/execution/SyntaxPiecePanel.vue— the Block Info panel whose title bar the raw JSON checkbox adds the view switch and the Copy JSON button to.wwwroot-src/src/pages/LogViewerPage.vue— the page the Help dropdown'sLog Viewerentry routes to.Environments/PreferenceController.cs— the endpoints. The step-present, show-physics-options, language and execution-layout writes persist throughUserService.SaveUserConfig(); the graphic-cache write is the exception, and returns without one.license-capsis a read with nothing to persist —{ success, resolutionCapRatio, stepCap, stepsTaken, hasResolutionCap, hasStepCap, leaseStepsLeft },Okwithsuccessfalse and amessageon error, as the other preference reads answer — and read-only by design: no endpoint sets a cap.leaseStepsLeftis what is left of the steps the licence server reserved for this process's cloud lease,-1when there is no such limit (the Sentinel licence, a paid plan); the installed HiNC's licence dialog adds it to the account's balance for its Step quota row (Signing In with a Cloud Account).Environments/UserConfig.cs— the persistedLanguageCodeandShowPhysicsOptionsproperties.Environments/UserService.cs— owns the singleUserConfigthe service holds, writes it toUserConfigPath, and answers the physics licence check.Program.cs— the oneUserServiceregistration behind every server-backed item here, and the configuration path it resolves against the process working directory.
See Also
- Main Panel — the menu bar this dropdown sits on
- Language Selection SubMenu — the language picker, the first of the two submenus this dropdown nests
- Graphic-Cache SubMenu — one of the two entries the web client hosts elsewhere
- Step Present Preference Page — the other entry the web client hosts elsewhere
- Log Viewer Page — the log screen this menu's namesake route serves
- Hidden Controller Branches — the two equipment nodes the CSV and CL entries reveal, and what a link to one does while its box is off
- Block Info Panel — the panel whose title bar the raw JSON checkbox adds the view switch and the Copy JSON button to