JIRA Forge开发:如何在问题状态改为Done时打开ModalDialog
实现方案说明
你当前编写的是Jira Forge的产品事件处理函数,这类函数运行在Atlassian的服务端,无法直接操作前端页面的DOM或唤起UI组件,所以不能在这个函数里直接调用ModalDialog。
可行实现思路
我们采用「前端页面埋点监听状态变更 + 前端唤起模态框」的方案,同时可以保留你的后端逻辑做数据校验或业务处理,具体步骤如下:
第一步:调整应用清单(manifest.yml)配置
你需要注册两个前端模块,分别覆盖问题详情页和看板页的场景,同时声明必要的权限:
modules: jira:issueView: - key: done-status-modal-issue-view resource: main title: 完成状态模态框 jira:boardView: - key: done-status-modal-board-view resource: main title: 看板完成状态模态框 resources: - key: main path: src/frontend/index.jsx permissions: scopes: - read:jira-work - write:jira-work app: id: 你的应用ID
第二步:前端实现状态监听与模态框唤起
以UI Kit 2 + React为例,前端代码逻辑如下:
import React, { useState, useEffect } from 'react'; import { ModalDialog, Button } from '@forge/react'; import { view } from '@forge/jira-bridge'; const DONE = 'Done'; const App = () => { const [isModalOpen, setIsModalOpen] = useState(false); const [issueSummary, setIssueSummary] = useState(''); useEffect(() => { // 监听问题详情页的状态变更事件 const unsubscribe = view.addEventListener('jira:issue:updated', async (event) => { const { issue } = event.data; const newStatus = issue.fields.status.name; // 匹配你原来的状态判断逻辑 if (newStatus === DONE) { setIssueSummary(issue.fields.summary); setIsModalOpen(true); } }); // 监听看板页拖拽变更问题状态的事件 const boardUnsubscribe = view.addEventListener('jira:board:issue:updated', async (event) => { const { issue, newStatus } = event.data; if (newStatus.name === DONE) { setIssueSummary(issue.fields.summary); setIsModalOpen(true); } }); return () => { unsubscribe(); boardUnsubscribe(); }; }, []); return ( <> {isModalOpen && ( <ModalDialog header="问题已完成" onClose={() => setIsModalOpen(false)}> <p>问题 {issueSummary} 已被标记为完成</p> <Button onClick={() => setIsModalOpen(false)}>确认</Button> </ModalDialog> )} </> ); }; export default App;
第三步:原有后端逻辑的复用
如果你原来的run函数中还有其他业务逻辑(比如数据统计、关联其他系统操作),可以将其改造为Forge Resolver,前端在唤起模态框前调用Resolver执行逻辑即可:
// 后端resolver代码 import Resolver from '@forge/resolver'; const resolver = new Resolver(); const DONE = 'Done'; resolver.define('checkIssueStatus', async ({ payload }) => { const { issue } = payload; // 此处可复用你原来的业务逻辑 return { shouldOpenModal: issue.fields.status.name === DONE, description: issue.fields.summary }; }); export const run = resolver.getDefinitions();
前端调用Resolver的逻辑:
import { invoke } from '@forge/bridge'; // 在状态变更的监听回调里调用 const result = await invoke('checkIssueStatus', { issue: event.data.issue }); if (result.shouldOpenModal) { setIssueSummary(result.description); setIsModalOpen(true); }
注意事项
- 该方案可以同时覆盖「问题详情页修改状态」和「看板页拖拽修改状态」两种场景
- 如果你的模态框需要展示更复杂的内容,可以直接在ModalDialog组件内扩展即可
- 如果需要限制仅特定角色/项目触发弹窗,可以在状态判断逻辑里加对应的权限校验
内容的提问来源于stack exchange,提问作者Joaquín L. Robles
相关产品推荐
相关产品推荐

