
Open MCT User Indicator 插件指南顶部状态栏用户信息、角色切换与 Mission Status 配置【免费下载链接】openmctA web based mission control framework.项目地址: https://gitcode.com/GitHub_Trending/ope/openmct导读User Indicator 是 Open MCTA web based mission control framework内置插件之一用于在应用顶部的状态栏status bar中展示当前登录用户的信息包括用户名与当前激活角色role在用户拥有多个角色时还允许用户直接在状态栏切换角色。除此之外该插件还承载了 Mission Status任务状态能力具备权限的用户可以点击用户指示器或其旁的 Mission Status 按钮在弹出的对话框中为一项或多项 Mission Action任务动作如 Drive、Imagery、Commanding设置 Go / No Go 之类的状态。读完本文你将掌握该插件的安装方式、依赖的 User Provider 接口契约、Mission Status 五要素 Provider 方法的完整配置方法以及如何参照仓库中的示例 Provider 实现自己的用户与任务状态后端。插件概述与前提条件User Indicator 插件本身不存储任何用户信息它只负责呈现。其显示内容完全由User Provider提供。因此官方文档明确指出A User Provider must be registered as a prerequisite for this plugin.从插件实现 src/plugins/userIndicator/plugin.js 可以看到插件在安装时会检查openmct.user.hasProvider()export default function UserIndicatorPlugin() { function addIndicator(openmct) { openmct.indicators.add({ key: user-indicator, vueComponent: UserIndicator, priority: openmct.priority.HIGH }); } return function install(openmct) { if (openmct.user.hasProvider()) { addIndicator(openmct); } else { // back up if user provider added after indicator installed openmct.user.on(providerAdded, () { addIndicator(openmct); }); } }; }这带来两个关键事实没有 User Provider指示器不会出现。对应的单元测试 src/plugins/userIndicator/pluginSpec.js 中第一个用例 will not show, if there is no user provider 验证了这一行为。安装顺序是宽松的。即使插件在 Provider 之前安装插件也会监听providerAdded事件在 Provider 被openmct.user.setProvider()注册后自动补挂指示器。因此只要在应用启动前两者都安装即可。User Provider 在src/api/user/UserAPI.js中通过setProvider()注册同一时刻只允许一个 Provider重复注册会触发MULTIPLE_PROVIDER_ERROR。快速开始两步安装官方 README 给出的用法是先注册一个 User Provider可以是你自己的实现也可以直接安装仓库自带的示例 Provider再安装 User Indicator 插件openmct.install(openmct.plugins.example.ExampleUser());openmct.install(openmct.plugins.UserIndicator());这两个插件均已在 src/plugins/plugins.js 中注册到全局命名空间plugins.example.ExampleUser ExampleUser;plugins.UserIndicator UserIndicator;所以它们可以通过openmct.plugins.example.ExampleUser()与openmct.plugins.UserIndicator()直接调用。示例 User Provider 插件定义在 example/exampleUser/plugin.js它支持三个可选参数参数默认值说明autoLoginUsermct-user跳过登录表单自动以该用户名登录用于测试/演示环境statusRoles[flight, driver]可以被轮询/提供状态的角色列表roles[observer]新建用户被赋予的角色列表示例插件在install阶段创建ExampleUserProvider并调用openmct.user.setProvider(userProvider)从而触发前文提到的providerAdded事件。用户信息展示与角色切换指示器 UI 结构指示器的 Vue 组件为 src/plugins/userIndicator/components/UserIndicator.vue。其模板逻辑为默认显示用户名若当前存在激活角色则显示用户名: 角色role ? \${userName}: ${role} : userName若当前用户拥有多于一个可用角色availableRoles?.length 1则显示一个Change Role按钮若当前用户有权限设置任务状态canSetMissionStatus为 true则显示Mission Status按钮且整个指示器变为clickable可点击状态。组件通过inject: [openmct]获取 Open MCT 实例并在created钩子中异步拉取用户信息async getUserInfo() { const user await this.openmct.user.getCurrentUser(); this.canSetMissionStatus await this.openmct.user.status.canSetMissionStatus(); this.userName user.getName(); this.role this.openmct.user.getActiveRole(); this.loggedIn this.openmct.user.isLoggedIn(); }角色切换的完整链路角色切换涉及三层机制从源码可以还原出完整的调用链角色来源openmct.user.getPossibleRoles()从 Provider 获取当前用户可用的全部角色对应UserProvider.getPossibleRoles()。激活角色持久化openmct.user.getActiveRole()/setActiveRole()内部使用StoragePersistencesessionStorage读写激活角色见 src/api/user/UserAPI.js 与 src/api/user/StoragePersistence.js。多标签页同步切换角色后通过 src/api/user/ActiveRoleSynchronizer.js 使用BroadcastChannel频道名定义于 src/api/user/constants.js广播新角色使同一浏览器中其他标签页的 Open MCT 实例同步切换角色。UI 侧的流程为点击 Change Role → 若只有一个角色则直接updateRole()若有多个角色则调用openmct.overlays.selection(...)弹出 Select Role 对话框确认后执行updateRole(role) { this.setRoleSelection(role); this.openmct.user.setActiveRole(role); // update other tabs through broadcast channel this.roleChannel.broadcastNewRole(role); }此外组件在openmct.on(start)时执行fetchOrPromptForRole若管理员从 Provider 中移除了当前角色会主动清空激活角色并重新提示选择若用户只有一个可用角色则自动选中若存在多个角色则通过openmct.notifications.info(...)提示当前以某角色登录。User Provider 基础接口任何 User Provider 都应实现 src/api/user/UserProvider.js 中定义的基础契约方法返回说明getCurrentUser()PromiseUser解析为当前登录用户isLoggedIn()boolean当前是否有用户登录hasRole(role)Promiseboolean当前用户是否拥有指定角色Mission Status任务状态面板概念模型官方文档对 Mission Status 的定义如下Mission Status is a feature that is used to indicate the current state of a mission with regards to one or more Mission Actions. A mission action defines a verb that may be, for example, a task for a spacecraft (such as Drive or Imagery), a change in the state of a ground system, or any other event that is relevant to the mission. Example states for a mission action might include Go or No Go, indicating whether a particular action is currently cleared for execution.简言之Mission Action是任务的动名词航天器任务如 Drive、Imagery地面系统状态变更等Mission Status表示每个 Mission Action 当前是否获准执行典型取值即 Go放行与 No Go不放行。有权限的用户可以点击用户指示器本身或指示器旁的Mission Status按钮打开对话框为每个 Mission Action 设置状态。Provider 配置五个必需方法要启用 Mission Status 功能注册的 User Provider 必须实现以下五个方法这是原文档的核心清单缺一不可方法返回类型说明canSetMissionStatus()boolean当前用户是否有权设置任务状态getPossibleMissionActions()Array用户可设置状态的 Mission Action 列表每个 action 应包含key与name属性getPossibleMissionActionStatuses()ArrayMissionStatusOption每个 Mission Action 可选的候选状态集合getStatusForMissionAction(action)MissionStatusOption返回指定 Mission Action 的当前状态setStatusForMissionAction(action, status)boolean为指定 Mission Action 设置新状态返回是否成功MissionStatusOption的数据结构在 src/api/user/StatusAPI.js 末尾的 JSDoc 中有明确定义/** * The MissionStatusOption type, extends Status. * typedef {Object} MissionStatusOption * property {string} key - A unique identifier for this status. * property {string} label - A human-readable label for this status. * property {number} timestamp - The time that the status was set. * property {string} color - A color to be used when displaying the mission status. */即每个状态对象至少包含key唯一标识与label人类可读标签可选timestamp与color。底层 API 转发机制这些方法并不是 UI 直接调用 Provider 的而是经由openmct.user.status即StatusAPI见 src/api/user/StatusAPI.js统一转发。StatusAPI对每个方法都做了能力探测若 Provider 未实现对应方法则给出user provider does not support ...之类的错误提示canSetMissionStatus()在 Provider 未实现时安全地返回Promise.resolve(false)使无权限用户不会看到任务状态入口。StatusAPI还会监听 Provider 上的missionActionStatusChange事件并重新广播为openmct.user.status上的同名事件见listenToStatusEvents/onMissionActionStatusChange供 UI 实时刷新。面板交互源码级解析任务状态弹出面板由 src/plugins/userIndicator/components/MissionStatusPopup.vue 实现挂在用户指示器的 Teleport 弹层中。其加载与交互逻辑如下并发加载通过Promise.all同时获取getPossibleMissionActions()与getPossibleMissionActionStatuses()批量拉取当前状态对每个 action 调用getStatusForMissionAction(action)用Promise.all并发执行然后 reduce 成action → status.key的映射表missionActionStatusMap实时监听注册missionActionStatusChange事件监听任何外部如其他标签页修改都会自动更新该 action 的当前状态修改状态用户在下拉框select切换选项后调用onChangeStatus(action)内部先再次校验canSetMissionStatus()不满足时弹出Selected user role is ineligible to set mission status错误提示再执行setStatusForMissionAction(action, statusObject)根据返回布尔值弹出 Successfully set mission status 或 Unable to set mission status 通知视觉反馈getMissionActionStatusClass会根据状态 label 是否为NO GO/GO为状态徽标追加--is-no-go/--is-go样式类实现红/绿语义化显示。弹层的位置计算不超出窗口右缘与底部时贴指示器下方超出则自动上移/左移与点击外部关闭逻辑位于 UserIndicator.vue 的positioncomputed 与handleOutsideClick中。参考实现ExampleUserProvider官方文档明确指出 example/exampleUser/ExampleUserProvider.js 提供了上述五个方法的示例实现是自定义 Provider 的最佳参照模板。状态与动作数据该示例定义了两组核心数据const MISSION_STATUSES [ { key: 0, label: NO GO }, { key: 1, label: GO } ];以及默认的 Mission Action 映射初始全部为NO GOthis.#actionToStatusMap { Imagery: MISSION_STATUSES[0], Commanding: MISSION_STATUSES[0], Driving: MISSION_STATUSES[0] };五要素方法在该类中的实现如下getPossibleMissionActions直接取 map 的键getPossibleMissionActionStatuses返回MISSION_STATUSESgetPossibleMissionActions() { return Promise.resolve(Object.keys(this.#actionToStatusMap)); } getPossibleMissionActionStatuses() { return Promise.resolve(MISSION_STATUSES); } getStatusForMissionAction(action) { return Promise.resolve(this.#actionToStatusMap[action]); } setStatusForMissionAction(action, status) { this.#actionToStatusMap[action] status; this.emit(missionStatusChange, { action, status }); return true; } canSetMissionStatus() { return Promise.resolve(true); }注意setStatusForMissionAction在成功写入后还会emit(missionStatusChange, ...)——这正是StatusAPI.listenToStatusEvents所监听的missionActionStatusChange事件源Provider 端事件名与 API 端重广播事件名的对应关系可从 StatusAPI.js 的onMissionActionStatusChange确认。这也意味着自定义 Provider 若需要实现多用户实时同步可以在此事件中推送变更使 UI 无需刷新即可联动。另外该 Provider 的基类实为StatusUserProvidersrc/api/user/StatusUserProvider.js它在UserProvider基础上扩展了状态轮询poll question、角色状态getStatusForRole/setStatusForRole、任务状态等能力是功能最完整的 Provider 基类如果只需要任务状态实现基础UserProvider接口并补上上述五个方法即可。配套的多角色示例仓库还提供了专门用于测试多角色切换的初始化脚本 e2e/helper/addInitExampleUserMultipleRoles.js可为用户预置多个角色用来验证 Select Role 对话框、角色切换与任务状态权限的完整交互。测试与验证该功能拥有从单元到端到端的多层测试覆盖单元测试src/plugins/userIndicator/pluginSpec.js验证无 Provider 时指示器不注册使用ExampleUserProviderautoLogin后指示器注册成功且状态栏中 User Role 区域包含登录用户名。端到端测试e2e/tests/functional/missionStatus.e2e.spec.js覆盖了任务状态面板的显示/隐藏切换按钮、关闭按钮、点击外部、Imagery / Commanding / Driving 三个 action 的默认状态初始为NO GO与状态设置、以及无权限角色设置状态被拒绝的场景。运行 e2e 测试需要先在 e2e 目录安装依赖并启动 Open MCT 本地服务器参见 e2e/README.md 中的配置说明随后执行 Playwright 用例即可。自定义接入要点小结实现getCurrentUser()/isLoggedIn()/hasRole()基础方法继承UserProvider或StatusUserProvider需要任务状态时按上表补齐五个 Mission Status 方法其中getPossibleMissionActions返回的每一项应含key与name通过openmct.user.setProvider(provider)注册再openmct.install(openmct.plugins.UserIndicator())状态变更通过missionActionStatusChangeProvider 端事件名missionStatusChange广播即可驱动 UI 实时刷新角色切换由ActiveRoleSynchronizerBroadcastChannel在标签页间同步无需额外配置。按照以上步骤你可以在自己的部署中复现顶部状态栏显示用户与角色、多角色切换、Mission Action 的 Go/No Go 管控这套完整的操作员工作流。【免费下载链接】openmctA web based mission control framework.项目地址: https://gitcode.com/GitHub_Trending/ope/openmct创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考