跳到主要内容

表单自定义控件

要求

适用环境

  • 私有部署
  • SAAS

ONES 系统版本

v6.90.0+

ONES CLI 版本

v1.70.1+

npm install -g @ones/cli --registry=https://npm.partner.ones.cn/registry/
ones --version
1.70.1

能力概述

本文档主要介绍如何通过功能扩展在工作项详情表单,新建表单,步骤表单中添加自定义表单控件。

功能扩展配置

配置

config/plugin.yaml中添加如下配置

oauth:
type:
- user
scope:
- read:project:issueField
extension:
- formControlExtension:
provider: smsprov2
slots:
- name: ones:form:control:content
entryUrl: modules/ones-form-control-content-nLtK/index.html
- name: ones:form:control:settings
entryUrl: modules/ones-form-control-settings-71OJ/index.html
config:
name: 自定义控件name
fieldUUIDs:
- 9ax9ExKt
- M3Fgzu3F
- EGx9jsaH
- LS5aqwaW
supportForms:
- detail
- create
- transition
controlTips: 控件描述

注:oauth 相关的配置主要跟 Open API 有关,插件可以按需配置。具体参考文档:Open API

插槽说明

插件名称说明
ones:form:control:content表单自定义控件在表单中渲染的内容插槽。
ones:form:control:settings表单自定义控件在表单配置器中实现自定义配置的设置插槽。如果表单自定义控件不需要自定义配置,可以不实现这个插槽。

config 字段说明

字段类型说明
namestring表单自定义控件名称
fieldUUIDsstring[]表单自定义控件包含的属性列表
supportForms"detail" | "create" | "transition"表单自定义控件支持的表单,目前只有三种(detail,create,transition)。目前 create 必须跟 detail 一起使用。
controlTipsstring控件描述,在表单配置器中展示,可以不配置。

示例

前端实现

表单自定义控件内容插槽

  1. 创建插槽内容渲染的入口文件 web/src/modules/ones-form-control-content-nLtK/index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import { ConfigProvider } from '@ones-design/core'
import { lifecycle, OPProvider } from '@ones-op/bridge'
import './index.css'
import { ControlContentExtension } from './control_content_extension'


ReactDOM.render(
<ConfigProvider>
<OPProvider>
<ControlContentExtension/>
</OPProvider>
</ConfigProvider>,
document.getElementById('ones-mf-root'),
)

lifecycle.onDestroy(() => {
ReactDOM.unmountComponentAtNode(document.getElementById('ones-mf-root') as HTMLElement)
})

  1. 实现ControlContentExtension组件。
import React, { useEffect } from 'react'
import type { FC } from 'react'
import { useExtensionContext, useExtensionConfig } from '@ones-op/sdk'

export const ControlContentExtension: FC = () => {
// 在插件内部调用useExtensionContext获取到标品传递给插件的上下文参数。调用useExtensionConfig获取到插件配置。
const extensionContext = useExtensionContext()
const extensionConfig = useExtensionConfig()

const {
fields,
fieldsConfig,
ctx,
values,
onSubmit,
onPermissionDenied,
type,
inEditor,
onChange,
settings,
} = extensionContext

return <div>your business logic</div>
}

  1. extensionContext 参数说明
字段类型说明详情表单新建表单步骤表单
namestring表单自定义控件名称
inEditorboolean是否在表单配置器中
type"detail" | "create" | "transition"当前表单类型
fieldsIField[] 属性基本信息
fieldsConfigRecord<string, FieldConfig>属性在表单中的配置,包括:visible,required,placeholder,hasPermission
valuesRecord<string, any>属性在表单中的值
settingsRecord<string, any>自定义控件在表单上的配置
ctxControlContentExtensionContext上下文信息
onPermissionDenied(fieldUUID: string) => void没有权限的情况下根据 fieldUUID 弹出对应的toast 文案,具体逻辑标品来处理
onSubmit(values: Record<string, { value: unknown; submitType?: SubmitTypeEnum }> ) => Promise<void>提交数据的回调
onChange(value: Record<string, any>) => void;新建表单/步骤表单内数据发生变化后的回调

ControlContentExtensionContext类型

export interface ControlContentExtensionContext {
taskUUID?: string // 工作项 UUID,仅详情表单,步骤表单会传递,
projectUUID?: string // 项目 UUID
issueTypeUUID?: string // 工作项类型 UUID
taskDetailViewMode?: TaskDetailViewMode // 工作项详情布局,仅详情表单会传递
taskStatus?: TaskStatus // 工作项状态,仅详情表单
transitionUUID?: string // 步骤流UUID,仅步骤表单才会有
formValues?: Record<string, any> // 表单的值,仅新建表单和步骤表单有
}

export enum TaskDetailViewMode {
Wide = 'wide', // 宽详情布局
Narrow = 'narrow', // 窄详情布局
}
export interface TaskStatus {
uuid: string
category: string
name: string
}
  1. 流程说明:

    详情表单:调用 onSubmit 传入表单自定义控件内部编辑好的数据,标品监听到 onSubmit 事件后会将接收到的参数调用 update 接口更新工作项属性的值。

    新建表单和步骤表单:调用 onChange 传入表单自定义控件内部编辑好的数据,标品监听到 onChange 事件后,会将接收到的值保存到表单内部,最后在点击确定按钮的时候统一提交数据。

表单自定义控件配置插槽

  1. 创建插槽自定义配置的入口文件 web/src/modules/ones-form-control-settings-71OJ/index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import { ConfigProvider } from '@ones-design/core'
import { lifecycle, OPProvider } from '@ones-op/bridge'
import { ControlSettingsExtension } from './control_settings_extension'
import './index.css'

ReactDOM.render(
<ConfigProvider>
<OPProvider>
<ControlSettingsExtension />
</OPProvider>
</ConfigProvider>,
document.getElementById('ones-mf-root'),
)

lifecycle.onDestroy(() => {
ReactDOM.unmountComponentAtNode(document.getElementById('ones-mf-root') as HTMLElement)
})

  1. 实现ControlSettingsExtension组件。
import React, { useEffect } from 'react'
import type { FC } from 'react'
import { useExtensionContext, useExtensionConfig } from '@ones-op/sdk'

export const ControlSettingsExtension: FC = () => {
// 在插件内部调用useExtensionContext获取到标品传递给插件的上下文参数。调用useExtensionConfig获取到插件配置。
const extensionContext = useExtensionContext()
const extensionConfig = useExtensionConfig()
return <div>your business logic</div>
}
  1. extensionContext 参数说明
名称类型描述
namestring插件的名称
type'detail' | 'create' | 'transition'表单类型
fieldsIField[]属性基本信息
valueRecord<string, any>控件历史保存的配置
ctxControlSettingsExtensionContext上下文信息
onChange(value: Record<string, any>) => Promise<void>控件配置发生改变后的回调

ControlSettingsExtensionContext类型

export interface ControlSettingsExtensionContext {
projectUUID?: string // 项目 UUID
issueTypeUUID?: string // 工作项类型 UUID
transitionUUID?: string // 步骤流UUID,仅步骤表单才会有
}
  1. 流程说明:

插件内部将编辑好的数据,通过onChange回调给标品,标品监听到 onChange 事件后会将接收到的参数保存到表单配置中。在渲染的时候会将配置读取出来,用 settings 字段传递给插件。