systemlink-cli 2.3.1__tar.gz → 2.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/PKG-INFO +1 -1
  2. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/pyproject.toml +1 -1
  3. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/_version.py +1 -1
  4. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_bootstrap.py +89 -37
  5. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/README.md +41 -2
  6. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/angular.json +7 -1
  7. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/package.json +1 -0
  8. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/app.module.ts +2 -0
  9. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.ts +6 -6
  10. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/app/core/systemlink/systemlink-locale.ts +48 -0
  11. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/app/core/systemlink/webapp-home-data.service.ts +62 -0
  12. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.html +34 -22
  13. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.ts +145 -0
  14. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.html +22 -18
  15. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.ts +177 -0
  16. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.html +28 -7
  17. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.ts +4 -1
  18. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.html +22 -19
  19. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.ts +48 -40
  20. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.html +31 -28
  21. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.ts +56 -18
  22. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.html +175 -0
  23. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.ts +13 -13
  24. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.html +1 -1
  25. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.html +1 -1
  26. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/index.html +1 -1
  27. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/locale/messages.de.json +10 -0
  28. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/locale/messages.en.json +239 -0
  29. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/locale/messages.es.json +10 -0
  30. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/locale/messages.fr.json +10 -0
  31. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/locale/messages.ja.json +10 -0
  32. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/locale/messages.ko.json +10 -0
  33. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/locale/messages.zh.json +10 -0
  34. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/localize.d.ts +1 -0
  35. systemlink_cli-2.4.1/slcli/webapp_templates/angular/blank/src/main.ts +61 -0
  36. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/tsconfig.json +1 -0
  37. systemlink_cli-2.3.1/slcli/webapp_templates/angular/blank/src/app/core/systemlink/webapp-home-data.service.ts +0 -62
  38. systemlink_cli-2.3.1/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.ts +0 -99
  39. systemlink_cli-2.3.1/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.ts +0 -133
  40. systemlink_cli-2.3.1/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.html +0 -175
  41. systemlink_cli-2.3.1/slcli/webapp_templates/angular/blank/src/main.ts +0 -11
  42. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/LICENSE +0 -0
  43. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/dff-editor/editor.js +0 -0
  44. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/dff-editor/index.html +0 -0
  45. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/__init__.py +0 -0
  46. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/__main__.py +0 -0
  47. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/alarm_click.py +0 -0
  48. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/asset_click.py +0 -0
  49. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/cli_formatters.py +0 -0
  50. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/cli_utils.py +0 -0
  51. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/comment_click.py +0 -0
  52. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/completion_click.py +0 -0
  53. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/config.py +0 -0
  54. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/config_click.py +0 -0
  55. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/credentials.py +0 -0
  56. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/dataframe_click.py +0 -0
  57. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/dff_click.py +0 -0
  58. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/dff_decorators.py +0 -0
  59. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/example_click.py +0 -0
  60. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/example_loader.py +0 -0
  61. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/example_provisioner.py +0 -0
  62. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/README.md +0 -0
  63. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/_schema/schema-v1.0.json +0 -0
  64. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/demo-data-1/README.md +0 -0
  65. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/demo-data-1/config.yaml +0 -0
  66. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/demo-data-2/README.md +0 -0
  67. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/demo-data-2/config.yaml +0 -0
  68. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/demo-data-3/config.yaml +0 -0
  69. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/demo-data-3/leakage-current-results.json +0 -0
  70. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/demo-data-3/overvoltage-results.json +0 -0
  71. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/demo-data-3/product-xyz-compliance-report.json +0 -0
  72. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/demo-data-3/product-xyz-specification.csv +0 -0
  73. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/demo-data-3/thermal-response-results.json +0 -0
  74. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/exercise-5-1-parametric-insights/README.md +0 -0
  75. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/exercise-5-1-parametric-insights/config.yaml +0 -0
  76. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/exercise-7-1-test-plans/README.md +0 -0
  77. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/exercise-7-1-test-plans/config.yaml +0 -0
  78. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/spec-compliance-notebooks/README.md +0 -0
  79. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/spec-compliance-notebooks/config.yaml +0 -0
  80. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/spec-compliance-notebooks/notebooks/SpecAnalysis_ComplianceCalculation.ipynb +0 -0
  81. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/spec-compliance-notebooks/notebooks/SpecComplianceCalculation.ipynb +0 -0
  82. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/spec-compliance-notebooks/notebooks/SpecfileExtractionAndIngestion.ipynb +0 -0
  83. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/examples/spec-compliance-notebooks/spec_template.xlsx +0 -0
  84. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/feed_click.py +0 -0
  85. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/file_click.py +0 -0
  86. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/function_click.py +0 -0
  87. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/function_templates.py +0 -0
  88. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/main.py +0 -0
  89. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/managed_client/__init__.py +0 -0
  90. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/managed_client/crypto.py +0 -0
  91. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/managed_client/handlers.py +0 -0
  92. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/managed_client/minion.py +0 -0
  93. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/managed_client/models.py +0 -0
  94. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/managed_client/protocol.py +0 -0
  95. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/managed_client/rest.py +0 -0
  96. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/managed_client/state.py +0 -0
  97. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/managed_client/transport.py +0 -0
  98. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/managed_client_click.py +0 -0
  99. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/mcp_click.py +0 -0
  100. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/mcp_reachability.py +0 -0
  101. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/mcp_server.py +0 -0
  102. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/mcp_skills.py +0 -0
  103. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/notebook_click.py +0 -0
  104. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/pkce.py +0 -0
  105. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/platform.py +0 -0
  106. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/policy_click.py +0 -0
  107. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/policy_utils.py +0 -0
  108. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/profile_credentials.py +0 -0
  109. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/profiles.py +0 -0
  110. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/response_handlers.py +0 -0
  111. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/rich_output.py +0 -0
  112. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/routine_click.py +0 -0
  113. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skill_click.py +0 -0
  114. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/SKILL.md +0 -0
  115. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/evals/COPILOT_BATCH_RUN_PROMPT.md +0 -0
  116. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/evals/README.md +0 -0
  117. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/evals/evals.json +0 -0
  118. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/evals/evals.schema.json +0 -0
  119. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/evals/files/spec-import/battery-specs.csv +0 -0
  120. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/evals/files/webapp-package/icon.svg +0 -0
  121. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/evals/files/webapp-package/nipkg.config.json +0 -0
  122. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/evals/files/webapp-package/webapp-content/index.html +0 -0
  123. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/evals/trigger_evals.json +0 -0
  124. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/analysis-recipes.md +0 -0
  125. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/commands.md +0 -0
  126. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/datasheet-workflow.md +0 -0
  127. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/domain-concepts.md +0 -0
  128. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/example-authoring.md +0 -0
  129. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/filtering.md +0 -0
  130. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/import-specs.min.json +0 -0
  131. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/job-debugging/overview.md +0 -0
  132. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/nipkg/overview.md +0 -0
  133. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/notebook/interfaces.md +0 -0
  134. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/notebook/notebook-patterns.md +0 -0
  135. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/notebook/overview.md +0 -0
  136. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/python-test/overview.md +0 -0
  137. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/routine-examples.md +0 -0
  138. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/troubleshooting.md +0 -0
  139. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/webapp/angular-ui-packages.md +0 -0
  140. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/webapp/deployment.md +0 -0
  141. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/webapp/layout-patterns.md +0 -0
  142. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/webapp/nimble-angular.md +0 -0
  143. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/webapp/overview.md +0 -0
  144. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/webapp/systemlink-services.md +0 -0
  145. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/references/webapp/troubleshooting.md +0 -0
  146. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/scripts/benchmark_iteration.py +0 -0
  147. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/scripts/compare_iteration.py +0 -0
  148. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/scripts/eval_manifest.py +0 -0
  149. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/scripts/grade_eval_response.py +0 -0
  150. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/scripts/grade_iteration.py +0 -0
  151. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/scripts/prepare_eval_prompts.py +0 -0
  152. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/scripts/prepare_eval_workspace.py +0 -0
  153. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/scripts/render_eval_review.py +0 -0
  154. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/skills/slcli/scripts/spec_import_helper.py +0 -0
  155. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/spec_click.py +0 -0
  156. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/ssl_trust.py +0 -0
  157. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/state_click.py +0 -0
  158. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/system_click.py +0 -0
  159. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/system_query_utils.py +0 -0
  160. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/systemlink-logo.svg +0 -0
  161. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/table_utils.py +0 -0
  162. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/tag_click.py +0 -0
  163. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/templates_click.py +0 -0
  164. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/testmonitor_click.py +0 -0
  165. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/universal_handlers.py +0 -0
  166. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/user_click.py +0 -0
  167. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/utils.py +0 -0
  168. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/version_click.py +0 -0
  169. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/web_editor.py +0 -0
  170. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_click.py +0 -0
  171. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/.gitignore +0 -0
  172. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/scripts/filter-sbom.js +0 -0
  173. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/app-routing.module.ts +0 -0
  174. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/app.component.html +0 -0
  175. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/app.component.scss +0 -0
  176. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/app.component.ts +0 -0
  177. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.html +0 -0
  178. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/core/layout/app-shell.component.scss +0 -0
  179. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/core/state/app-view-state.service.ts +0 -0
  180. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/systemlink-context.service.ts +0 -0
  181. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/core/systemlink/theme-sync.service.ts +0 -0
  182. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/assets/assets-page.component.scss +0 -0
  183. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/datasets/datasets-page.component.scss +0 -0
  184. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/home/home-page.component.scss +0 -0
  185. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/master-detail/master-detail-page.component.scss +0 -0
  186. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/operations/operations-page.component.scss +0 -0
  187. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/features/settings/settings-page.component.scss +0 -0
  188. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.scss +0 -0
  189. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/shared/components/empty-state.component.ts +0 -0
  190. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.html +0 -0
  191. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.scss +0 -0
  192. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/shared/components/error-banner.component.ts +0 -0
  193. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.scss +0 -0
  194. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/shared/components/loading-state.component.ts +0 -0
  195. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/app/shared/states/view-state.model.ts +0 -0
  196. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/assets/README.md +0 -0
  197. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/src/styles.scss +0 -0
  198. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/webapp_templates/angular/blank/tsconfig.app.json +0 -0
  199. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/workflow_preview.py +0 -0
  200. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/workflows_click.py +0 -0
  201. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/workitem_click.py +0 -0
  202. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/workspace_click.py +0 -0
  203. {systemlink_cli-2.3.1 → systemlink_cli-2.4.1}/slcli/workspace_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: systemlink-cli
3
- Version: 2.3.1
3
+ Version: 2.4.1
4
4
  Summary: SystemLink Integrator CLI - cross-platform CLI for SystemLink workflows and templates.
5
5
  License-File: LICENSE
6
6
  Author: Fred Visser
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "systemlink-cli"
3
- version = "2.3.1"
3
+ version = "2.4.1"
4
4
  description = "SystemLink Integrator CLI - cross-platform CLI for SystemLink workflows and templates."
5
5
  authors = ["Fred Visser <fred.visser@emerson.com>"]
6
6
  packages = [{ include = "slcli" }]
@@ -1,4 +1,4 @@
1
1
  """Version information for slcli."""
2
2
 
3
3
  # This file is auto-generated. Do not edit manually.
4
- __version__ = "2.3.1"
4
+ __version__ = "2.4.1"
@@ -357,10 +357,16 @@ def _build_webapp_routing_module(template: str, routing_mode: str) -> str:
357
357
  return "\n".join(lines)
358
358
 
359
359
 
360
+ def _localize_typescript_literal(value: str) -> str:
361
+ """Return a TypeScript `$localize` template literal for a fixed message."""
362
+ escaped = value.replace("\\", "\\\\").replace("`", "\\`").replace("${", "\\${")
363
+ return f"$localize`{escaped}`"
364
+
365
+
360
366
  def _build_webapp_shell_component(template: str) -> str:
361
367
  """Render the app shell tabs for the selected template."""
362
368
  tab_lines = [
363
- f" {{ id: '{tab['id']}', label: '{tab['label']}', route: '{tab['route']}' }},"
369
+ f" {{ id: '{tab['id']}', label: {_localize_typescript_literal(tab['label'])}, route: '{tab['route']}' }},"
364
370
  for tab in _webapp_template_profile(template)["tabs"]
365
371
  ]
366
372
 
@@ -463,6 +469,7 @@ def _build_webapp_app_module(enable_ok_feature: bool) -> str:
463
469
  "import { NimbleChipModule } from '@ni/nimble-angular/chip';",
464
470
  "import { NimbleLabelProviderCoreModule } from '@ni/nimble-angular/label-provider/core';",
465
471
  "import { NimbleTableModule } from '@ni/nimble-angular/table';",
472
+ "import { NimbleTableColumnDateTextModule } from '@ni/nimble-angular/table-column/date-text';",
466
473
  "import { NimbleTableColumnTextModule } from '@ni/nimble-angular/table-column/text';",
467
474
  ]
468
475
  if ok_imports:
@@ -515,6 +522,7 @@ def _build_webapp_app_module(enable_ok_feature: bool) -> str:
515
522
  " NimbleTextAreaModule,",
516
523
  " NimbleTextFieldModule,",
517
524
  " NimbleTableModule,",
525
+ " NimbleTableColumnDateTextModule,",
518
526
  " NimbleTableColumnTextModule,",
519
527
  *ok_modules,
520
528
  " ],",
@@ -533,6 +541,7 @@ def _build_master_detail_page_template(enable_ok_feature: bool) -> str:
533
541
  <ok-fv-master-detail-list
534
542
  class=\"master-detail__list\"
535
543
  placeholder=\"Filter devices...\"
544
+ i18n-placeholder
536
545
  (change)=\"onSelectionChange($event)\"
537
546
  >
538
547
  <ok-fv-master-detail-list-item
@@ -551,6 +560,7 @@ def _build_master_detail_page_template(enable_ok_feature: bool) -> str:
551
560
  <nimble-select
552
561
  class=\"master-detail__list\"
553
562
  aria-label=\"Devices\"
563
+ i18n-aria-label
554
564
  filter-mode=\"standard\"
555
565
  [(ngModel)]=\"selectedDeviceId\"
556
566
  (ngModelChange)=\"onSelectedDeviceIdChange()\"
@@ -564,9 +574,9 @@ def _build_master_detail_page_template(enable_ok_feature: bool) -> str:
564
574
  return (
565
575
  """<section class=\"master-detail sl-page\">
566
576
  <header class=\"sl-page__intro\">
567
- <p class=\"sl-page__eyebrow\">Starter Pattern: Master Detail</p>
568
- <h2>Use this sample layout when selection and lightweight editing need to stay side by side.</h2>
569
- <p>
577
+ <p class=\"sl-page__eyebrow\" i18n>Starter Pattern: Master Detail</p>
578
+ <h2 i18n>Use this sample layout when selection and lightweight editing need to stay side by side.</h2>
579
+ <p i18n>
570
580
  The list items, fields, and helper copy here are starter content. Replace them when the
571
581
  route is connected to the real records your app manages.
572
582
  </p>
@@ -580,7 +590,8 @@ def _build_master_detail_page_template(enable_ok_feature: bool) -> str:
580
590
  (click)=\"isEditing ? saveChanges() : toggleEditMode()\"
581
591
  [disabled]=\"!selectedDevice\"
582
592
  >
583
- {{ isEditing ? 'Save details' : 'Edit details' }}
593
+ <ng-container *ngIf=\"isEditing\" i18n>Save details</ng-container>
594
+ <ng-container *ngIf=\"!isEditing\" i18n>Edit details</ng-container>
584
595
  </nimble-button>
585
596
  </div>
586
597
  </div>
@@ -591,9 +602,10 @@ def _build_master_detail_page_template(enable_ok_feature: bool) -> str:
591
602
  class=\"master-detail__filter\"
592
603
  [(ngModel)]=\"filterTerm\"
593
604
  placeholder=\"Search devices\"
605
+ i18n-placeholder
594
606
  (ngModelChange)=\"applyFilter()\"
595
607
  >
596
- Filter devices
608
+ <ng-container i18n>Filter devices</ng-container>
597
609
  </nimble-text-field>
598
610
 
599
611
  """
@@ -612,74 +624,74 @@ def _build_master_detail_page_template(enable_ok_feature: bool) -> str:
612
624
 
613
625
  <div class=\"master-detail__detail-grid\">
614
626
  <div>
615
- <span>Device name</span>
627
+ <span i18n>Device name</span>
616
628
  <strong>{{ device.name }}</strong>
617
629
  </div>
618
630
  <div>
619
- <span>Model</span>
631
+ <span i18n>Model</span>
620
632
  <strong>{{ device.model }}</strong>
621
633
  </div>
622
634
  <div>
623
- <span>IP address</span>
635
+ <span i18n>IP address</span>
624
636
  <strong>{{ device.ipAddress }}</strong>
625
637
  </div>
626
638
  <div>
627
- <span>Firmware version</span>
639
+ <span i18n>Firmware version</span>
628
640
  <strong>{{ device.firmwareVersion }}</strong>
629
641
  </div>
630
642
  </div>
631
643
 
632
644
  <div class=\"master-detail__edit-grid\">
633
645
  <nimble-text-field [(ngModel)]=\"device.location\" [readonly]=\"!isEditing\">
634
- Location
646
+ <ng-container i18n>Location</ng-container>
635
647
  </nimble-text-field>
636
648
  <nimble-text-field [(ngModel)]=\"device.systemId\" [readonly]=\"!isEditing\">
637
- Device ID
649
+ <ng-container i18n>Device ID</ng-container>
638
650
  </nimble-text-field>
639
651
  </div>
640
652
 
641
653
  <nimble-text-area [(ngModel)]=\"device.notes\" [readonly]=\"!isEditing\" resize=\"vertical\">
642
- Notes
654
+ <ng-container i18n>Notes</ng-container>
643
655
  </nimble-text-area>
644
656
 
645
657
  <nimble-switch [(ngModel)]=\"device.monitorEnabled\" [disabled]=\"!isEditing\">
646
- Include in monitor roster
658
+ <ng-container i18n>Include in monitor roster</ng-container>
647
659
  </nimble-switch>
648
660
 
649
- <nimble-banner *ngIf=\"device.statusLabel === 'Pending changes'\" [open]=\"true\" severity=\"warning\">
661
+ <nimble-banner *ngIf=\"device.statusCode === 'pending-changes'\" [open]=\"true\" severity=\"warning\" i18n>
650
662
  Review the pending changes before this device returns to the connected roster.
651
663
  </nimble-banner>
652
664
 
653
665
  <dl class=\"master-detail__facts\">
654
666
  <div>
655
- <dt>Last seen</dt>
656
- <dd>{{ device.lastSeen }}</dd>
667
+ <dt i18n>Last seen</dt>
668
+ <dd>{{ device.lastSeen | date:'medium' }}</dd>
657
669
  </div>
658
670
  <div>
659
- <dt>Calibration due</dt>
660
- <dd>{{ device.calibrationDue }}</dd>
671
+ <dt i18n>Calibration due</dt>
672
+ <dd>{{ device.calibrationDue | date:'mediumDate':'UTC' }}</dd>
661
673
  </div>
662
674
  </dl>
663
675
  </section>
664
676
  </div>
665
677
 
666
678
  <ng-template #emptyState>
667
- <sl-empty-state [message]=\"'Adjust the filter or add a real device query to populate this pattern.'\"></sl-empty-state>
679
+ <sl-empty-state [message]=\"emptyStateMessage\"></sl-empty-state>
668
680
  </ng-template>
669
681
  </section>
670
682
  """
671
683
  )
672
684
 
673
685
 
674
- def _quoted_typescript_list(values: List[str]) -> str:
675
- """Return a comma-separated TypeScript string literal list."""
676
- return ",\n ".join(f"'{value}'" for value in values)
686
+ def _localized_typescript_list(values: List[str]) -> str:
687
+ """Return a comma-separated list of localized TypeScript messages."""
688
+ return ",\n ".join(_localize_typescript_literal(value) for value in values)
677
689
 
678
690
 
679
691
  def _build_webapp_home_data_service(template: str) -> str:
680
692
  """Render the home data service for the selected template."""
681
693
  profile = _webapp_template_profile(template)
682
- patterns = _quoted_typescript_list(profile["patterns"])
694
+ patterns = _localized_typescript_list(profile["patterns"])
683
695
  return "\n".join(
684
696
  [
685
697
  "import { Injectable } from '@angular/core';",
@@ -708,21 +720,21 @@ def _build_webapp_home_data_service(template: str) -> str:
708
720
  " return {",
709
721
  " metrics: [",
710
722
  " {",
711
- " label: 'Hosted origin',",
723
+ " label: $localize`Hosted origin`,",
712
724
  " value: this.context.origin,",
713
- " detail: 'Root future SDK clients and direct fetch calls here.',",
725
+ " detail: $localize`Root future SDK clients and direct fetch calls here.`,",
714
726
  " tone: 'info',",
715
727
  " },",
716
728
  " {",
717
- " label: 'Auth mode',",
729
+ " label: $localize`Auth mode`,",
718
730
  " value: this.context.authMode,",
719
- " detail: 'Swap with --auth when you need API-key-driven development flows.',",
731
+ " detail: $localize`Swap with --auth when you need API-key-driven development flows.`,",
720
732
  " tone: 'warning',",
721
733
  " },",
722
734
  " {",
723
- " label: 'Workspace',",
735
+ " label: $localize`Workspace`,",
724
736
  " value: this.context.workspaceName,",
725
- " detail: 'Publishing help text and starter docs are already aligned to this workspace.',",
737
+ " detail: $localize`Publishing help text and starter docs are already aligned to this workspace.`,",
726
738
  " tone: 'success',",
727
739
  " },",
728
740
  " ],",
@@ -730,11 +742,11 @@ def _build_webapp_home_data_service(template: str) -> str:
730
742
  f" {patterns},",
731
743
  " ],",
732
744
  " nextSteps: [",
733
- " 'Replace one sample page with a real SystemLink query before adding more routes.',",
734
- " 'Use Nimble buttons for actions and Nimble anchors or route tabs for navigation.',",
735
- " 'Preserve hosted query parameters if you later add cross-app breadcrumbs.',",
745
+ " $localize`Replace one sample page with a real SystemLink query before adding more routes.`,",
746
+ " $localize`Use Nimble buttons for actions and Nimble anchors or route tabs for navigation.`,",
747
+ " $localize`Preserve hosted query parameters if you later add cross-app breadcrumbs.`,",
736
748
  " ],",
737
- f" readinessMessage: '{profile['readiness_message']}',",
749
+ f" readinessMessage: {_localize_typescript_literal(profile['readiness_message'])},",
738
750
  " };",
739
751
  " }",
740
752
  "}",
@@ -768,13 +780,18 @@ This app was generated by `slcli webapp new {app_name}` as a hosted Angular 20 s
768
780
  - `nimble-theme-provider` at the application root
769
781
  - `APP_BASE_HREF` provided without a `<base>` tag in `src/index.html`
770
782
  - `useHash: {'true' if routing_mode == 'hash' else 'false'}` routing for hosted navigation
771
- - `@angular/localize/init` configured for the build polyfill path
783
+ - Angular `i18n` and `$localize` support with `en-US` as the source locale
784
+ - `npm run i18n:extract` configured to write the English fallback catalog
785
+ - Runtime localization using the active SystemLink language preference
786
+ - Runtime translation catalogs for German, English, Spanish, French, Japanese, Korean, and Chinese
787
+ - `@angular/localize/init` configured in the build polyfill path
772
788
  - Nimble fonts imported in `src/styles.scss`
773
789
  - modern Angular application builders configured for the hosted scaffold
774
790
  - CycloneDX npm generator for a runtime dependency SBOM
775
791
  - initial bundle warning budget tuned for the included starter shell
776
792
  - shared loading, error, and empty states
777
793
  - SystemLink context and theme sync services under `src/app/core/systemlink/`
794
+ - `nimble-theme-provider` and live SystemLink shell theme synchronization enabled by default
778
795
  - {profile['pattern_summary']}
779
796
 
780
797
  ## Enabled Starter Routes
@@ -797,7 +814,38 @@ or creating the SBOM yet.
797
814
 
798
815
  The generated scaffold intentionally omits a default test runner setup so `npm install`
799
816
  does not pull in the deprecated Karma/Jasmine stack. Add your preferred test tooling when
800
- you start writing app-specific tests.
817
+ you start writing app-specific tests. Include `@angular/localize/init` in the test
818
+ polyfill path when you add that tooling.
819
+
820
+ ## Localization
821
+
822
+ The source locale is `en-US`. Sample UI copy is marked with Angular `i18n` in
823
+ templates and `$localize` in TypeScript. Run `npm run i18n:extract` after adding
824
+ or changing user-facing text to regenerate the complete English fallback
825
+ catalog in `src/locale/messages.en.json`. Add translated message IDs to the
826
+ runtime catalogs in `src/locale/messages.<language>.json`; the selected locale
827
+ catalog overrides matching English entries, while untranslated copy falls
828
+ back to English without runtime warnings. The starter reads the SystemLink
829
+ preference from `localStorage.language` when the iframe loads, with the legacy
830
+ `skyline-api-languages` preference and browser language as fallbacks. It
831
+ supports `de`, `en`, `es`, `fr`, `ja`, `ko`, and `zh`. Angular translations and
832
+ locale data load before app modules are imported through `loadTranslations()`,
833
+ and the resolved language sets `LOCALE_ID` and the iframe document's `lang`.
834
+ The SystemLink shell reloads the iframe when the user changes the profile
835
+ language, so the next bootstrap applies the new translations and date/number
836
+ formats.
837
+ The Home localization preview has translations for all supported non-English
838
+ languages; other starter copy remains in English until you add translations.
839
+
840
+ ## Theming
841
+
842
+ The app is wrapped in a root `nimble-theme-provider`. By default,
843
+ `ThemeSyncService` observes the SystemLink shell theme and updates the app for
844
+ `light`, `dark`, and `color` themes. Use Nimble design tokens for custom styles
845
+ and keep theme aliases on the provider. For standalone previews, the
846
+ `?theme=light`, `?theme=dark`, and `?theme=color` query values can select a
847
+ theme. The `webapp new --theme-sync` option can disable automatic shell
848
+ synchronization when needed.
801
849
 
802
850
  ## Publish To SystemLink
803
851
 
@@ -964,6 +1012,7 @@ def _customize_generated_package_json(
964
1012
  package_json["scripts"] = {
965
1013
  "start": "ng serve --host 0.0.0.0",
966
1014
  "build": "ng build",
1015
+ "i18n:extract": "ng extract-i18n",
967
1016
  "sbom": (
968
1017
  "cyclonedx-npm --omit dev --output-format JSON "
969
1018
  "--output-file sbom.cdx.json --validate --output-reproducible "
@@ -1104,7 +1153,10 @@ def _emit_webapp_new_dry_run(
1104
1153
  + ", ".join(tab["route"].lstrip("/") or "home" for tab in profile["tabs"])
1105
1154
  )
1106
1155
  click.echo(" - APP_BASE_HREF provider with no <base> tag")
1107
- click.echo(" - Angular localize polyfills for build")
1156
+ click.echo(" - Angular localize build polyfill and en-US source locale")
1157
+ click.echo(" - i18n:extract script for the English fallback catalog")
1158
+ click.echo(" - SystemLink runtime language detection and locale-aware bootstrap")
1159
+ click.echo(" - root Nimble theme provider with shell synchronization enabled by default")
1108
1160
  click.echo(" - Nimble fonts in src/styles.scss")
1109
1161
  click.echo(" - @angular/build application builder with inlineCritical disabled")
1110
1162
  click.echo(" - hash routing enabled unless --routing path is requested")
@@ -10,13 +10,18 @@ This app was generated by `slcli webapp new {{APP_NAME}}` as a hosted Angular 20
10
10
  - `nimble-theme-provider` at the application root
11
11
  - `APP_BASE_HREF` provided without a `<base>` tag in `src/index.html`
12
12
  - `useHash: {{ROUTER_USE_HASH}}` routing for hosted navigation
13
- - `@angular/localize/init` configured for the build polyfill path
13
+ - Angular `i18n` and `$localize` support with `en-US` as the source locale
14
+ - `npm run i18n:extract` configured to write the English fallback catalog
15
+ - Runtime localization using the active SystemLink language preference
16
+ - Runtime translation catalogs for German, English, Spanish, French, Japanese, Korean, and Chinese
17
+ - `@angular/localize/init` configured in the build polyfill path
14
18
  - Nimble fonts imported in `src/styles.scss`
15
19
  - modern Angular application builders configured for the hosted scaffold
16
20
  - CycloneDX npm generator for a runtime dependency SBOM
17
21
  - initial bundle warning budget tuned for the included six-route starter shell
18
22
  - shared loading, error, and empty states
19
23
  - SystemLink context and theme sync services under `src/app/core/systemlink/`
24
+ - `nimble-theme-provider` and live SystemLink shell theme synchronization enabled by default
20
25
  - six Nimble-based layout patterns ready to replace with real SystemLink resource calls
21
26
 
22
27
  ## Project Layout
@@ -56,7 +61,41 @@ or creating the SBOM yet.
56
61
 
57
62
  The generated scaffold intentionally omits a default test runner setup so `npm install`
58
63
  does not pull in the deprecated Karma/Jasmine stack. Add your preferred test tooling when
59
- you start writing app-specific tests.
64
+ you start writing app-specific tests. Include `@angular/localize/init` in the test
65
+ polyfill path when you add that tooling.
66
+
67
+ ## Localization
68
+
69
+ The source locale is `en-US`. Sample UI copy is marked with Angular `i18n` in
70
+ templates and `$localize` in TypeScript. The English fallback catalog is a
71
+ union across the `blank`, `dashboard`, `list-detail`, and `admin` profiles and
72
+ the Nimble-only master/detail variant. After adding or changing user-facing
73
+ text, run `npm run i18n:extract` for the affected variant and merge its IDs
74
+ into `src/locale/messages.en.json`; do not replace the union with output from a
75
+ single variant. Add translated message IDs to the
76
+ runtime catalogs in `src/locale/messages.<language>.json`; the selected locale
77
+ catalog overrides matching English entries, while untranslated copy falls
78
+ back to English without runtime warnings. The starter reads the SystemLink
79
+ preference from `localStorage.language` when the iframe loads, with the legacy
80
+ `skyline-api-languages` preference and browser language as fallbacks. It
81
+ supports `de`, `en`, `es`, `fr`, `ja`, `ko`, and `zh`. Angular translations and
82
+ locale data load before app modules are imported through `loadTranslations()`,
83
+ and the resolved language sets `LOCALE_ID` and the iframe document's `lang`.
84
+ The SystemLink shell reloads the iframe when the user changes the profile
85
+ language, so the next bootstrap applies the new translations and date/number
86
+ formats. The Home localization preview has translations for all supported
87
+ non-English languages; other starter copy remains in English until you add
88
+ translations.
89
+
90
+ ## Theming
91
+
92
+ The app is wrapped in a root `nimble-theme-provider`. By default,
93
+ `ThemeSyncService` observes the SystemLink shell theme and updates the app for
94
+ `light`, `dark`, and `color` themes. Use Nimble design tokens for custom styles
95
+ and keep theme aliases on the provider. For standalone previews, the
96
+ `?theme=light`, `?theme=dark`, and `?theme=color` query values can select a
97
+ theme. The `webapp new --theme-sync` option can disable automatic shell
98
+ synchronization when needed.
60
99
 
61
100
  ## Publish To SystemLink
62
101
 
@@ -20,6 +20,9 @@
20
20
  "root": "",
21
21
  "sourceRoot": "src",
22
22
  "prefix": "app",
23
+ "i18n": {
24
+ "sourceLocale": "en-US"
25
+ },
23
26
  "architect": {
24
27
  "build": {
25
28
  "builder": "@angular/build:application",
@@ -82,7 +85,10 @@
82
85
  "extract-i18n": {
83
86
  "builder": "@angular/build:extract-i18n",
84
87
  "options": {
85
- "buildTarget": "{{PROJECT_NAME}}:build"
88
+ "buildTarget": "{{PROJECT_NAME}}:build",
89
+ "format": "json",
90
+ "outFile": "messages.en.json",
91
+ "outputPath": "src/locale"
86
92
  }
87
93
  }
88
94
  }
@@ -6,6 +6,7 @@
6
6
  "scripts": {
7
7
  "start": "ng serve --host 0.0.0.0",
8
8
  "build": "ng build",
9
+ "i18n:extract": "ng extract-i18n",
9
10
  "publish:webapp": "slcli webapp publish dist/{{PROJECT_NAME}}"
10
11
  },
11
12
  "dependencies": {},
@@ -21,6 +21,7 @@ import {
21
21
  import { NimbleChipModule } from '@ni/nimble-angular/chip';
22
22
  import { NimbleLabelProviderCoreModule } from '@ni/nimble-angular/label-provider/core';
23
23
  import { NimbleTableModule } from '@ni/nimble-angular/table';
24
+ import { NimbleTableColumnDateTextModule } from '@ni/nimble-angular/table-column/date-text';
24
25
  import { NimbleTableColumnTextModule } from '@ni/nimble-angular/table-column/text';
25
26
  import { OkFvMasterDetailListItemModule } from '@ni/ok-angular/fv/master-detail-list-item';
26
27
  import { OkFvMasterDetailListModule } from '@ni/ok-angular/fv/master-detail-list';
@@ -69,6 +70,7 @@ import { LoadingStateComponent } from './shared/components/loading-state.compone
69
70
  NimbleTextAreaModule,
70
71
  NimbleTextFieldModule,
71
72
  NimbleTableModule,
73
+ NimbleTableColumnDateTextModule,
72
74
  NimbleTableColumnTextModule,
73
75
  OkFvMasterDetailListModule,
74
76
  OkFvMasterDetailListItemModule,
@@ -25,12 +25,12 @@ interface ShellTab {
25
25
  })
26
26
  export class AppShellComponent {
27
27
  readonly tabs: readonly ShellTab[] = [
28
- { id: 'overview', label: 'Overview', route: '/' },
29
- { id: 'datasets', label: 'Data Table', route: '/datasets' },
30
- { id: 'assets', label: 'Drawer Detail', route: '/assets' },
31
- { id: 'master-detail', label: 'Master Detail', route: '/master-detail' },
32
- { id: 'operations', label: 'Operations', route: '/operations' },
33
- { id: 'settings', label: 'Settings', route: '/settings' },
28
+ { id: 'overview', label: $localize`Overview`, route: '/' },
29
+ { id: 'datasets', label: $localize`Data Table`, route: '/datasets' },
30
+ { id: 'assets', label: $localize`Drawer Detail`, route: '/assets' },
31
+ { id: 'master-detail', label: $localize`Master Detail`, route: '/master-detail' },
32
+ { id: 'operations', label: $localize`Operations`, route: '/operations' },
33
+ { id: 'settings', label: $localize`Settings`, route: '/settings' },
34
34
  ];
35
35
 
36
36
  activeTabId = 'overview';
@@ -0,0 +1,48 @@
1
+ const SYSTEMLINK_LANGUAGES = ['fr', 'de', 'ja', 'zh', 'en', 'ko', 'es'] as const;
2
+ const SYSTEMLINK_LANGUAGE_STORAGE_KEY = 'language';
3
+ const SYSTEMLINK_LEGACY_LANGUAGE_STORAGE_KEY = 'skyline-api-languages';
4
+
5
+ export type SystemLinkLanguage = (typeof SYSTEMLINK_LANGUAGES)[number];
6
+
7
+ function toLanguage(locale: string | null | undefined): string {
8
+ return (locale ?? '').split(/[-_]/)[0].trim().toLowerCase();
9
+ }
10
+
11
+ function isSystemLinkLanguage(language: string): language is SystemLinkLanguage {
12
+ return SYSTEMLINK_LANGUAGES.some((supportedLanguage: string) => supportedLanguage === language);
13
+ }
14
+
15
+ function readLocalStorage(key: string): string | null {
16
+ try {
17
+ return globalThis.localStorage?.getItem(key) ?? null;
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+
23
+ export function getSystemLinkLanguage(): SystemLinkLanguage {
24
+ const storedCandidates = [
25
+ readLocalStorage(SYSTEMLINK_LANGUAGE_STORAGE_KEY),
26
+ readLocalStorage(SYSTEMLINK_LEGACY_LANGUAGE_STORAGE_KEY)?.split(',')[0],
27
+ ];
28
+ for (const candidate of storedCandidates) {
29
+ const language = toLanguage(candidate);
30
+ if (isSystemLinkLanguage(language)) {
31
+ return language;
32
+ }
33
+ }
34
+
35
+ const browserCandidates = [
36
+ ...(globalThis.navigator?.languages ?? []),
37
+ globalThis.navigator?.language,
38
+ Intl.DateTimeFormat().resolvedOptions().locale,
39
+ ];
40
+ for (const candidate of browserCandidates) {
41
+ const language = toLanguage(candidate);
42
+ if (isSystemLinkLanguage(language)) {
43
+ return language;
44
+ }
45
+ }
46
+
47
+ return 'en';
48
+ }
@@ -0,0 +1,62 @@
1
+ import { Injectable } from '@angular/core';
2
+
3
+ import { SystemLinkContextService } from './systemlink-context.service';
4
+
5
+ export interface HomeMetric {
6
+ label: string;
7
+ value: string;
8
+ detail: string;
9
+ tone: 'info' | 'success' | 'warning';
10
+ }
11
+
12
+ export interface HomePageModel {
13
+ metrics: HomeMetric[];
14
+ patterns: string[];
15
+ nextSteps: string[];
16
+ readinessMessage: string;
17
+ }
18
+
19
+ @Injectable({ providedIn: 'root' })
20
+ export class WebappHomeDataService {
21
+ constructor(private readonly context: SystemLinkContextService) {}
22
+
23
+ async load(): Promise<HomePageModel> {
24
+ return {
25
+ metrics: [
26
+ {
27
+ label: $localize`Hosted origin`,
28
+ value: this.context.origin,
29
+ detail: $localize`Root future SDK clients and direct fetch calls here.`,
30
+ tone: 'info',
31
+ },
32
+ {
33
+ label: $localize`Auth mode`,
34
+ value: this.context.authMode,
35
+ detail: $localize`Swap with --auth when you need API-key-driven development flows.`,
36
+ tone: 'warning',
37
+ },
38
+ {
39
+ label: $localize`Workspace`,
40
+ value: this.context.workspaceName,
41
+ detail: $localize`Publishing help text and starter docs are already aligned to this workspace.`,
42
+ tone: 'success',
43
+ },
44
+ ],
45
+ patterns: [
46
+ $localize`Route-level navigation with Nimble anchor tabs`,
47
+ $localize`Search-first Nimble table toolbar with concise Search <items> copy`,
48
+ $localize`Drawer-based detail inspection from a primary dataset`,
49
+ $localize`Master/detail split pane with read-only detail fields until edit mode`,
50
+ $localize`Split operations workspace with manual refresh and a confirm dialog`,
51
+ $localize`Grouped settings form with theme-aware sections and readonly hosted facts`,
52
+ ],
53
+ nextSteps: [
54
+ $localize`Replace one sample page with a real SystemLink query before adding more routes.`,
55
+ $localize`Use Nimble buttons for actions and Nimble anchors or route tabs for navigation.`,
56
+ $localize`Preserve hosted query parameters if you later add cross-app breadcrumbs.`,
57
+ ],
58
+ readinessMessage:
59
+ $localize`This starter keeps hosted routing, Nimble tokens, and sample control text aligned to current Stratus guidance.`,
60
+ };
61
+ }
62
+ }