Kanban 组件
kanban
UI 组件表示一个看板。其中看板列表示项目的不同阶段,项目的任务以卡片的形式展示。
基本用法
使用 Jmix Studio 可以创建组件的 kanban
XML 元素并与 数据容器 绑定。
<kanban:kanban id="kanban"
height="100%"
width="100%"/>
如果不使用 Studio 的视图设计器,则可以在 XML 中手动声明 kanban
命名空间:
<view xmlns="http://jmix.io/schema/flowui/view"
xmlns:kanban="http://jmix.io/schema/kanban/ui"
title="msg://kanbanView.title">
下一步,指定需要展示的数据和列:
-
配置列需要添加带
columnsEnum
属性的 columns 元素。 -
配置实体字段映射需要添加 propertiesMapping 元素。
下面的示例创建了一个基本的 kanban
:
<data>
<collection id="kanbanTasksDc"
class="com.company.onboarding.entity.KanbanTask">
<loader id="kanbanTasksDl" readOnly="true">
<query>
<![CDATA[select e from KanbanTask e]]>
</query>
</loader>
<fetchPlan extends="_base"/>
</collection>
</data>
<layout>
<kanban:kanban id="kanban" dataContainer="kanbanTasksDc"
width="100%" height="100%">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label"/>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
</kanban:kanban>
</layout>
数据绑定
键值对容器
kanban
也可以与 键值对数据容器 绑定。示例:
<data>
<keyValueCollection id="keyValueKanbanTasksDc">
<properties idProperty="id">
<property name="id" datatype="uuid"/>
<property name="status" datatype="string"/>
<property name="text" datatype="string"/>
</properties>
<loader>
<query>
<![CDATA[select t.id, t.status, t.text from KanbanTask t]]>
</query>
</loader>
</keyValueCollection>
</data>
<layout>
<kanban:kanban id="kanbanKeyValue"
dataContainer="keyValueKanbanTasksDc"
width="100%" height="100%">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label"/>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
</kanban:kanban>
</layout>
编程式绑定
如需以编程的方式定义一个数据容器,则需要删除 dataContainer 属性:
<kanban:kanban id="programmaticallyKanban"
width="100%" height="100%">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label"/>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
</kanban:kanban>
然后在视图控制器中,用 ContainerKanbanItems
类将看板与数据容器关联:
@ViewComponent
private Kanban<KanbanTask> programmaticallyKanban;
@ViewComponent
private CollectionContainer<KanbanTask> kanbanTasksDc;
@Autowired
private DataManager dataManager;
@Subscribe
public void onInit(InitEvent event) {
programmaticallyKanban.setItems(new ContainerKanbanItems<>(kanbanTasksDc, UUID.class));
}
属性映射
通过属性映射可以定义实体中的数据如何在看板的卡片中展示。
-
Jmix 实体:一个 Jmix 实体(例如,
KanbanTask
)用于表示应用程序中的任务。该实体有多个属性,如title
、status
、dueDate
等。 -
看板卡片:需要在应用程序中通过看板卡片展示任务的属性。
-
映射:Jmix 的
Kanban
组件提供一个机制,可以将实体属性关联至看板卡片的特定字段。
propertiesMapping
元素定义一组实体属性与任务卡片字段的映射。看板中显示的任务卡片有一组预定义的字段:
id |
任务的唯一 ID。必需字段。 |
---|---|
status |
任务的状态。必须对应列或子列的 dataField。必需字段。 |
text |
任务的描述。必需字段。 |
color |
任务卡片的颜色。 |
dueDate |
任务的到期时间。 |
priority |
任务的优先级。 |
progress |
任务的进度。可以是从 0 到 100 之间的一个数字。 |
swimlane |
任务的泳道。必须对应泳道定义中泳道的 dataField 属性,如果存在泳道的话。 |
tags |
逗号分隔的标签。 |
userAvatar |
分配该任务的用户头像。 |
username |
分配该任务的用户名。 |
声明式映射
通常,kanban
实体属性的映射可以用 XML 的 propertiesMapping 元素定义。
请注意这里属性值的设置方式。既可以是根实体的直接属性(text = "text"
)或子实体的属性(username = "assignee.username"
)。
下面的示例中,一个 kanban
与任务实体的一些字段做了映射:
<kanban:kanban id="declarativePropertiesMappingKanban" dataContainer="kanbanTasksDc"
width="100%" height="100%"
taskUserAvatarVisible="true">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label"/>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
<kanban:propertiesMapping id="id" status="status" text="text"
username="assignee.username"
userAvatar="assignee.picture"/>
</kanban:kanban>
编程式映射
propertiesMapping
也可以编程式定义,此时不需要在 XML 中添加该元素,而是在视图控制器中,通过 setPropertiesMapping(JmixKanban.PropertiesMapping)
方法设置。
<kanban:kanban id="programmaticPropertiesMappingKanban" dataContainer="kanbanTasksDc"
width="100%" height="100%"
taskUserAvatarVisible="true">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label"/>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
</kanban:kanban>
@ViewComponent
private Kanban<KanbanTask> programmaticPropertiesMappingKanban;
@Subscribe
public void onInit(InitEvent event) {
JmixKanban.PropertiesMapping propertiesMapping = new JmixKanban.PropertiesMapping("id", "status", "text");
propertiesMapping.setUserAvatar("assignee.picture");
propertiesMapping.setUsername("assignee.username");
programmaticPropertiesMappingKanban.setPropertiesMapping(propertiesMapping);
}
数据保存代理
通过 kanban
组件修改数据有三种方法:
包括 kanban
在内的可视化组件会在数据容器中暂存修改后的数据,直到触发一个确认操作才会提交数据至数据库。
如需在用户编辑任务后自动提交,可以创建一个 saveDelegate,并使用 DataManager 保存更改:
<data>
<collection id="kanbanTasksDc"
class="com.company.onboarding.entity.KanbanTask">
<loader id="kanbanTasksDl" readOnly="true">
<query>
<![CDATA[select e from KanbanTask e]]>
</query>
</loader>
<fetchPlan extends="_base"/>
</collection>
</data>
<layout>
<kanban:kanban id="saveDelegateKanban" dataContainer="kanbanTasksDc"
width="100%" height="100%">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label"/>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
</kanban:kanban>
</layout>
@Install(to = "saveDelegateKanban", subject = "saveDelegate")
private void kanbanSaveDelegate(final KanbanTask kanbanTask) {
dataManager.save(kanbanTask);
}
如需自动保存 |
操作
kanban
组件实现了 HasActions
接口,可以包含标准的 列表操作 和自定义操作。通过点击特定的按钮来调用操作。
以下示例演示了如何向组件添加操作:
<hbox id="buttonsPanel" classNames="buttons-panel"> (1)
<button id="createBtn" action="kanbanActions.create"/>
<button id="editBtn" action="kanbanActions.edit"/>
<button id="removeBtn" action="kanbanActions.remove"/>
<button id="infoBtn" action="kanbanActions.getInfo"/>
</hbox>
<kanban:kanban id="kanbanActions" dataContainer="kanbanTasksDc"
width="100%" height="100%">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label"/>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
<kanban:actions>
<kanban:action id="create" type="list_create"/> (2)
<kanban:action id="edit" type="list_edit"/>
<kanban:action id="remove" type="list_remove"/>
<kanban:action id="getInfo" text="Get Info" icon="INFO_CIRCLE"/> (3)
</kanban:actions>
</kanban:kanban>
1 | 定义一个 hbox 容器,在组件上方显示操作按钮。 |
2 | 定义 list_create 标准操作。用于创建新条目。 |
3 | 定义 getInfo 自定义操作。text 属性的值将作为按钮的文本。 |
如需通过 Jmix Studio 添加 |
状态列层级结构
kanban
组件支持具有层级结构的看板列。子列与父列具有相同的属性。
子列无法与 swimlanes 或 columnsEnum 同时使用。 |
下面的示例展示了带子列的 kanban
:
显示代码
<kanban:kanban id="hierarchicalKanban" dataContainer="kanbanTasksDc"
width="100%" height="100%">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label">
<kanban:columns>
<kanban:column dataField="started"
label="msg://kanban.column.started.label"/>
<kanban:column dataField="almost-finished"
label="msg://kanban.column.almost_finished.label"/>
</kanban:columns>
</kanban:column>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
</kanban:kanban>
层级模式
层级列的展示有两种模式:
-
COLUMNS
- 子列以内部列的形式展示。 -
TABS
- 子列以文本标签页(tab)的形式展示。此时,设置子列的 selected 属性可以配置默认的选择列。
示例:
显示代码
<kanban:kanban id="hierarchyModeKanban" dataContainer="kanbanTasksDc"
width="100%" height="100%"
hierarchyMode="TABS">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label">
<kanban:columns>
<kanban:column dataField="started" selected="true"
label="msg://kanban.column.started.label"/>
<kanban:column dataField="almost-finished"
label="msg://kanban.column.almost_finished.label"/>
</kanban:columns>
</kanban:column>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
</kanban:kanban>
任务位置
层级列可以只显示在叶子节点。任务的显示位置有两个选项:
-
ALL
- 任务可以显示在所有列层级中。 -
LEAF
- 任务仅能显示在列结构的叶子节点中。
示例:
显示代码
<kanban:kanban id="taskPositionKanban" dataContainer="kanbanTasksDc"
width="100%" height="100%"
taskPosition="LEAF">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label">
<kanban:columns>
<kanban:column dataField="started" selected="true"
label="msg://kanban.column.started.label"/>
<kanban:column dataField="almost-finished"
label="msg://kanban.column.almost_finished.label"/>
</kanban:columns>
</kanban:column>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
</kanban:kanban>
渲染器
kanban
组件支持对卡片的展示进行自定义。使用渲染器(Renderer)可以自定义列表头、脚注以及看板任务卡片的文字。
任务渲染器
任务渲染器可以自定义任务的外观,通过一个回调函数定义。回调函数带 2 个参数:任务的 HTML 元素以及任务的数据。
示例:
显示代码
<kanban:kanban id="taskRendererKanban" dataContainer="kanbanTasksDc"
width="100%" height="100%">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label"/>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
<kanban:taskRendererFunction>
<![CDATA[
(task, data) => {
task.style.color = data.text.includes("Create") ? '#0B88DF' : '#182739'
}
]]>
</kanban:taskRendererFunction>
</kanban:kanban>
列表头渲染器
列表头渲染器可以自定义看板列表头的外观,通过一个回调函数定义。回调函数带 3 个参数:列表头的 HTML 元素、列数据以及列的 dataField。
示例:
显示代码
<kanban:kanban id="headerRendererKanban" dataContainer="kanbanTasksDc"
width="100%" height="100%">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label"/>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
<kanban:columnHeaderRendererFunction>
<![CDATA[
(header, data, dataField) => {
let color = '';
switch (data.label) {
case 'Todo': {
color = '#0B88DA';
break;
}
case 'In progress': {
color = '#30C1E3'
break;
}
case 'Verification': {
color = '#3634C8'
break;
}
case 'Done': {
color = '#34C8BA';
break;
}
}
header.style.background = color;
header.style.color = '#FFF';
}
]]>
</kanban:columnHeaderRendererFunction>
</kanban:kanban>
列脚注渲染器
列脚注渲染器可以自定义看板列脚注的外观,通过一个回调函数定义。回调函数带 3 个参数:列脚注的 HTML 元素、列数据以及列的 dataField。
示例:
显示代码
<kanban:kanban id="footerRendererKanban" dataContainer="kanbanTasksDc"
width="100%" height="100%"
columnSummaryEnabled="true"
columnFooterVisible="true">
<kanban:columns>
<kanban:column dataField="todo"
label="msg://kanban.column.todo.label"/>
<kanban:column dataField="in-progress"
label="msg://kanban.column.in_progress.label"/>
<kanban:column dataField="verification"
label="msg://kanban.column.verification.label"/>
<kanban:column dataField="done"
label="msg://kanban.column.done.label"/>
</kanban:columns>
<kanban:columnFooterRendererFunction>
<![CDATA[
(footer, data, dataField) => {
footer.style.color = data.label === 'In progress' ? '#0B88DA' : '#3634C8';
}
]]>
</kanban:columnFooterRendererFunction>
</kanban:kanban>
XML 属性
在 Jmix 中,所有组件都有一些作用一致的 通用属性。下面是 kanban
的特殊属性:
可以通过 Jmix Studio 的组件属性面板查看和编辑组件的属性。 |
名称 |
描述 |
默认值 |
---|---|---|
|
||
如果为 |
|
|
如果为 |
|
|
如果为 |
|
|
如果为 |
|
|
如果为 |
|
|
如果为 |
|
|
如果为 |
|
|
如果为 |
|
|
如果为 |
|
|
设置所有列的宽度,单位为像素。 |
|
|
如果为 |
|
|
如果为 |
|
|
如果为 |
|
|
配置内部子列的层级模式。选项: |
|
|
设置泳道的起始列的索引位置。参阅 泳道。 |
|
|
设置泳道的结束列的索引位置。 |
- |
|
如果为 |
|
|
如果为 |
|
|
设置任务在列中的位置。选项: |
|
|
如果为 |
|
|
如果为 |
|
|
如果为 |
|
|
如果为 |
|
事件和处理器
在 Jmix 中,所有组件都有一些 通用事件和处理器,可以按相同的方法设置。下面是 kanban
的特殊事件和处理器:
在 Jmix Studio 生成处理器桩代码时,可以使用 Jmix UI 组件面板的 Handlers 标签页或者视图类顶部面板的 Generate Handler 添加,也可以通过 Code → Generate 菜单(Alt+Insert / Cmd+N)生成。 |
名称 |
描述 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
添加一个数据保存的代理函数,在使用看板更新数据时通过该函数保存。在通过拖放改变任务卡片状态或点击对应图标修改任务优先级时调用。参阅 保存代理。 |
XML 内部元素
kanban
内的 XML 元素提供了更多的选项控制列的外观、行为和功能。
如需通过 Studio 为选择的组件添加内部元素,可以点击组件属性面板的 Add 按钮。 |
Columns
columns
可以定义一组需要展示的列,可以显式设置值或者使用枚举设置。
XML 元素 |
|
---|---|
属性 |
|
XML 内部元素 |
名称 |
描述 |
默认值 |
---|---|---|
设置列需要使用的枚举类的全限定名称(FQN)。枚举值作为列的 dataField,值的本地化信息作为列的 label。使用这种方式定义列时,不支持定义内部的子列。参考 在线示例。 |
- |
Column
column
元素定义单独的一列。
XML 元素 |
|
---|---|
Java 类 |
|
XML 属性 |
dataField - collapsed - collapsible - color - label - orientation - reorder - selected - visible - width |
XML 内部元素 |
名称 |
描述 |
默认值 |
---|---|---|
设置该列需要映射的标识符。
|
- |
|
如果为 |
|
|
如果为 |
|
|
设置列的颜色属性,值需要是 CSS 的颜色格式。颜色应用在列的表头标题上,也可以应用到该列内部的卡片上。 |
- |
|
设置列表头的文字。该属性的值可以是一个纯文本,或 消息包 中的一个键值。如果是键值,需要以 |
- |
|
设置列内部任务卡片的摆放方向,选项: |
|
|
如果为 |
|
|
如果为 |
- |
|
如果为 |
|
|
设置列的宽度,单位为像素。 |
- |
Swimlanes
该功能在预览阶段。其外观以及实现细节在将来的版本中可能发生重大变化。 |
swimlaes
元素可用于定义泳道,可以显式设置值或者使用枚举设置。泳道是将任务水平划分的横向条纹(责任区域),使用泳道时无法使用子列。
XML 元素 |
|
---|---|
XML 属性 |
|
XML 内部元素 |
名称 |
描述 |
默认值 |
---|---|---|
设置泳道需要使用的枚举类的全限定名称(FQN)。枚举值作为泳道的 dataField,值的本地化信息作为泳道的 label。 |
- |
Swimlane
swimlane
元素定义单一泳道。
XML 元素 |
|
---|---|
Java 类 |
|
XML 属性 |
名称 |
描述 |
默认值 |
---|---|---|
设置该泳道需要映射的标识符。
|
- |
|
设置泳道的颜色。颜色应用于泳道的水平条纹。 |
- |
|
设置泳道的表头文本。该属性的值可以是一个纯文本,或 消息包 中的一个键值。如果是键值,需要以 |
- |
PropertiesMapping
看板任务卡片可以展示看板任务实体的特定字段。使用 propertiesMapping
元素设置实体属性与看板字段的映射关系。参考 示例。
XML 元素 |
|
---|---|
Java 类 |
|
XML 属性 |
id - status - test - color - dueDate - priority - progress - swimlane - tags - userAvatar - username - |
名称 |
描述 |
默认值 |
---|---|---|
设置实体属性的名称,该属性映射至卡片的 |
|
|
设置实体属性的名称,该属性映射至卡片的 |
|
|
设置实体属性的名称,该属性映射至卡片的 |
|
|
设置实体属性的名称,该属性映射至卡片的 |
- |
|
设置实体属性的名称,该属性映射至卡片的 |
- |
|
设置实体属性的名称,该属性映射至卡片的 |
- |
|
设置实体属性的名称,该属性映射至卡片的 |
- |
|
设置实体属性的名称,该属性映射至卡片的 |
- |
|
设置实体属性的名称,该属性映射至卡片的 |
- |
|
设置实体属性的名称,该属性映射至卡片的 |
- |
|
设置实体属性的名称,该属性映射至卡片的 |
- |