Table of Contents

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 Cache button 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-cache clamps the requested size between the stored limits, assigns the three fields on the live UserConfig and returns, without calling UserService.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.
    • Language Selection SubMenu
      • The persisted value is UserConfig.LanguageCode; the web application reaches it through GET/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.
    • Show Physics Options CheckBox
      • The model is UserConfig.ShowPhysicsOptions, reached in the web application through GET/POST /api/preference/show-physics-options.
      • The checkbox is disabled and unchecked if UserService.IsPhysicsLicensed is false: the GET returns the flag ANDed with the licence and the POST forces false without it.
    • 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.pageGroup filled with the page switches' own labels, so they read Equipment Page and Execution 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, or This project plays CSV / CL — and none otherwise. It is computed from the same two referenced flags 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's localStorage, not in UserConfig. It is off by default.
          • Checking it adds the CSV Controller node 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, or Not used by this project — read from the referenced flag of GET /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.
        • CL Controller CheckBox
          • The same, for useViewPrefs().showClController, the CL Controller Control Tree node and GET /api/mech/cl-runner.
      • 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 the charts.titles strings rather than a menu string.
          • Checking it renders the Sensor Cutting Force Cycle panel 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.
        • Sensor Spindle Moment Cycle CheckBox
          • The same, for useViewPrefs().showSensorSpindleMomentCycle and the Sensor Spindle Moment Cycle panel.
        • Block Info · Raw JSON CheckBox
          • The model is useViewPrefs().syntaxDevView — device-local like the boxes above it, and off by default; data-testid menu-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 is menu.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 JSON switch 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 is useViewPrefs().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).
    • Log Viewer Entry
      • See Log Viewer Page.
      • It is not a Preference-dropdown entry, although the route path /preference/log is 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.

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 — the Preference ▾ dropdown itself with its two nested submenus, the snapshot fetch it runs as it opens and the captions computed from the two referenced flags, and the Help dropdown's Log Viewer entry.
  • 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-local localStorage singleton 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-options and /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; stepsTaken is process-wide; the response's leaseStepsLeft is left out), which no dropdown item shows; what a cap means for the current workpiece is GET /api/Workpiece/resolution-cap, see Workpiece.
  • wwwroot-src/src/api/csvRunner.ts, wwwroot-src/src/api/clRunner.ts — the referenced flag 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.pageGroup and menu.preference.blockRawJsonNote among them, and the menu.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.title and execution.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's Log Viewer entry routes to.
  • Environments/PreferenceController.cs — the endpoints. The step-present, show-physics-options, language and execution-layout writes persist through UserService.SaveUserConfig(); the graphic-cache write is the exception, and returns without one. license-caps is a read with nothing to persist — { success, resolutionCapRatio, stepCap, stepsTaken, hasResolutionCap, hasStepCap, leaseStepsLeft }, Ok with success false and a message on error, as the other preference reads answer — and read-only by design: no endpoint sets a cap. leaseStepsLeft is what is left of the steps the licence server reserved for this process's cloud lease, -1 when 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 persisted LanguageCode and ShowPhysicsOptions properties.
  • Environments/UserService.cs — owns the single UserConfig the service holds, writes it to UserConfigPath, and answers the physics licence check.
  • Program.cs — the one UserService registration behind every server-backed item here, and the configuration path it resolves against the process working directory.

See Also