
最近我們發布了Jmix 的最新1.5 正式版本。本文中,我們將介紹1.5 版本中引入的主要新功能和改進。
如需了解更新的詳細信息以及如何升級,請參考Jmix 文檔中的 最近更新 部分。
Studio UI/UX 改進
首先我們看一下在更新了Studio 後你可能發現的一些UI 層面的變化。
我們通過對不熟悉Jmix 的開發者進行幾輪的測試後發現,當前的UI 可視化設計器有些過於復雜了。對於第一次使用Studio 的用戶來說,三個工具窗口和多個XML 編輯和界面預覽面板容易使人感到不知所錯。另外,我們發現用戶更偏向使用當前編輯器窗口頂部的操作面板,並且更習慣通過點擊鼠標右鍵查找可用的功能。
因此,我們決定移除靜態的組件工具箱面板,而改為通過幾種不同的方式打開工具箱彈窗的交互模式。這幾種不同的方式包括:從頂部操作面板打開,從組件層級結構的右鍵菜單打開,以及從源程式碼編輯器中的 「Generate」 菜單打開。新的工具箱彈窗支持搜索可用組件,也支持將組件拖放至UI 層級結構或者源碼中:
▲ Studio 添加組件
UI 組件層級結構和組件屬性面板現在合併成了單一的工具窗口,稱為Jmix UI,默認位於IDE 的右側。因此,UI 可視化設計器最後僅保留一個工具窗口,而組件工具箱可以通過不同的方式打開。
Studio 界面中的另一個不太好用的功能是 「Code Snippets」 工具箱。儘管對於沒有Jmix 開發經驗的人來說,這個功能非常有用,但是卻很難被注意到。所以,我們也修改了這個面板的展示方式:現在,在編輯Spring bean 或者UI 控制器時,可以通過頂部操作面板的按鈕或者 「Generate」 菜單打開,並且程式碼段的窗口也是以彈窗的方式展示。
▲ Studio 程式碼片段
Flow UI 改進
我們一直在持續改進Flow UI 的功能,使其更接近作為Jmix 中主要的UI 技術這一目標。
在這個版本中,我們將Flow UI 的核心升級到Vaadin 23.3 並且集成了幾個新的組件。
TabSheet
當需要將大量UI 組件放入單個視圖時,TabSheet 是必不可少的。使用Jmix 最常見的場景就是開發類似ERP 這樣的後台系統,而這種系統中,TabSheet 是一個典型需求。
在以前的版本中,Jmix 只提供了Tabs 組件,該組件並不是容器,需要在不同的佈局之間進行編程切換。而Vaadin 23.3 提供了功能齊全的TabSheet,這樣我們可以完全用聲明式的方式集成:
<tabSheet width="100%">
<tab id="mainTab" label="Main">
<formLayout id="form" dataContainer="userDc">...</formLayout>
</tab>
<tab id="additionalTab" label="Onboarding steps">
<vbox>
<hbox>...</hbox>
<dataGrid width="100%" dataContainer="stepsDc">...</dataGrid>
</vbox>
</tab>
</tabSheet>
▲ Flow UI TabSheet
MultiSelectComboBox
在最新的Vaadin 中也提供了多選下拉框組件,使用該組件用戶可以在下拉列表中選擇多個值,並且在字段中很好地顯示選擇的內容。我們已經在Jmix 集成該組件,並添加了數據綁定,因此可用於展示或修改實體的集合屬性。下面的示例中,我們用這個組件管理產品和標籤的多對多關係:
<instance id="productDc"
class="com.company.demo.entity.Product">
<fetchPlan extends="_base">
<property name="tags" fetchPlan="_base"/>
</fetchPlan>
<loader/>
</instance>
<collection class="com.company.demo.entity.Tag" id="allTagsDc">
<fetchPlan extends="_base"/>
<loader id="allTagsDl">
<query>
<![CDATA[select e from Tag e]]>
</query>
</loader>
</collection>
<!-- ... -->
<formLayout id="form" dataContainer="productDc">
<textField id="nameField" property="name"/>
<multiSelectComboBox property="tags" itemsContainer="allTagsDc"/>
</formLayout>
▲ Flow UI MultiSelectComboBox
上傳控件
基於Vaadin 的Upload 組件,我們開發了兩個Flow UI 的組件:FileStorageUploadField
和 FileUploadField
。前一個用來將档案上傳至档案存儲,返回 FileRef
對象,可以保存在實體屬性中。後一個返回字節數組,這個字節數組是直接保存在一個實體中的。
這兩個組件的聲明式用法非常簡單:只需要設置一個帶有實體實例的數據容器,然後配置 FileRef
或字節數組類型的實體屬性名稱即可:
<fileStorageUploadField id="uploadField"
dataContainer="userDc" property="picture"/>
圖片
圖片組件現在也支持Jmix 的數據綁定,可以綁定至 FileRef
或字節數組類型的實體屬性:
<image id="image"
dataContainer="userDc" property="picture"
height="280px" width="200px" classNames="user-picture"/>
如果需要配置圖片的放置方式,可以用CSS 樣式。例如,需要在縮放圖像同時保持其寬高比,可以創建下面這個CSS 類,並在組件的 classNames
屬性中指定:
.user-picture {
object-fit: contain;
}
Tooltip
Tooltip(提示窗)可以在UI 組件旁邊的小彈窗中展示組件的附加信息。鼠標懸停或者鍵盤聚焦都可以維持它的展示狀態。
對於支持提示窗的組件,Studio UI 設計器會在組件屬性面板展示 Add 按鈕:
▲ Flow UI 添加提示窗
在XML 中則是通過組件內部的元素定義:
<textField id="nameField" property="name">
<tooltip text="Product name" position="BOTTOM_START"/>
</textField>
▲ Flow UI 提示窗
通用過濾器
過濾器是經典UI 中最受歡迎的組件之一,支持用戶根據不同的條件篩選數據,包括實體屬性、引用、JPQL 查詢和條件運算符。打個形象的比喻,過濾器就像是一把用於結構化數據搜索的瑞士軍刀,開發人員只需在界面中放置過濾器,用戶就可以自定義並按需使用。
在Jmix 1.5,我們在Flow UI 中添加了具有基本功能的通用過濾器:用戶可以基於整個實體關係圖創建任意數量的屬性條件。與Flow UI 中的其他組件一樣,過濾器也是響應式的:
▲ Flow UI 響應式過濾器
而且,對於響應式的breakpoints,過濾器還支持在其內部XML 元素 responsiveSteps
進行配置:
<genericFilter id="filter" dataLoader="usersDl"
summaryText="My filter">
<responsiveSteps>
<responsiveStep minWidth="0" columns="1"/>
<responsiveStep minWidth="800px" columns="2"/>
<responsiveStep minWidth="1200px" columns="3"/>
</responsiveSteps>
</genericFilter>
顯然,過濾器是有狀態的,而且在不同的視圖之間導航或刷新網頁時應保持其狀態。否則,用戶設置過的篩選條件將會丟失,例如,在詳情頁編輯數據後返回列表頁的情況。 Jmix 提供了 queryParameters
facet,用於保存當前URL 和篩選條件的映射,這樣可以確保在不同的視圖間導航時過濾器能保持正確的過濾狀態,並且能提供包括篩選條件在內的頁面深度鏈接(Deep link)。 Facet 的最簡單配置就是直接設置它所控制的過濾器組件:
<facets>
<queryParameters>
<genericFilter component="filter"/>
</queryParameters>
</facets>
通用過濾器的研發還在繼續,我們計劃在2023 年6 月的版本中讓Flow UI 的過濾器具有通用UI 過濾器的所有功能。
帶有Flow UI 的擴展組件
在1.5 中,我們為下列開源組件提供了Flow UI:
-
多租戶
-
Quartz 定時任務
-
應用程式設置
-
表格導出操作
在使用Flow UI 的項目中可以直接通過Studio 的擴展組件市場安裝。
Flow UI 菜單
Flow UI 中的主菜單結構與經典UI 不同:每個擴展組件都有自己的根節點菜單、有預定義的順序,而且沒有通用的“管理” 菜單。對於試驗和原型系統來說,這種默認的菜單結構已經夠用,但對於實際的應用來說,往往還是需要一個自定義的菜單結構。因此,可以從“Composite” 模式切換到“Single” 模式並定義自己的菜單結構。
以前,許多開發人員盡可能避免使用“Single” 模式,因為在項目中添加新擴展組件時,這種模式會有問題:新擴展組件的菜單項沒有出現在主菜單中,並且不清楚要怎麼添加。
現在,這個問題已經在Flow UI 的菜單設計器中得到解決。一旦切換到“Single” 模式,設計器就會在左側顯示一個包含擴展組件所有菜單項的面板,這些菜單也可以在主菜單使用。這樣一來,在添加了新的擴展組件之後,只需要將擴展組件的菜單拖放到主菜單中合適的位置即可。
▲ Flow UI 菜單設計器
Excel 導出
Jmix 應用程式中最常用的功能之一是能夠一鍵將UI 表格中展示的數據導出到Excel。這個功能在最初設計時是用來精確導出用戶當前能看到的所有數據,即通過過濾器選擇的當前頁面的數據。但是很多時候用戶希望能導出過濾器篩選的所有數據,而不僅僅是當前頁面。
在1.5 中,我們改進了表格導出操作擴展組件提供的 excelExport
操作。現在,如果用戶在導出對話框中選擇“所有行”,則會導出所有數據。考慮到性能和服務器內存使用情況,數據加載會分批次執行。
該功能同時支持經典UI 和Flow UI。
悲觀鎖UI
Jmix 現在提供了一個用於管理悲觀鎖的默認UI。位於經典UI 的“管理” 菜單和Flow UI 的“系統” 菜單中。
系統管理員可以查看當前鎖的列表,並在需要時進行手動刪除。
Liquibase changelog
Jmix 的一個優勢是能幫助開發人員創建和運行用於數據庫版本控制的Liquibase changelog。 Studio 會針對數據模型和數據庫結構之間的差異生成changelog,並在啟動應用程式時運行這些更改腳本。因此,當在測試或生產環境中啟動一個新版本的應用時,會自動在連接的數據庫上運行那些新添加的changelog。
但是,這個簡單的流程並不能滿足所有的需求,有時候需要在沒有Studio 或應用程式的情況下運行Liquibase,比如,在一個CI 服務器上通過Liquibase CLI 或Gradle 插件運行changelog。
在以前的版本中,這是不可能實現的,因為項目的root changelog 档案沒有定義擴展組件提供的數據庫變更。但是changelog 能正確運行是因為,Jmix 會從項目配置中獲取使用的擴展組件信息,並在運行Liquibase 之前在內存中動態創建正確的changelog。
從Jmix 1.5 開始,我們修改了這個機制,項目的root changelog 档案始終是完整的,可以通過Liquibase CLI 或Gradle 插件執行。每當添加或刪除擴展組件時,Studio 都會自動更新changelog 包含新的內容。此外,當啟動應用程式時,Studio 會檢查root changelog 中包含的內容與項目的擴展組件是否匹配。如果發現不匹配,Studio 會顯示通知對話框,並建議添加或刪除對擴展組件changelog 的引入。
Jmix 工具窗口中,通過雙擊數據存儲下的Liquibase 節點即可打開root changelog:
▲ Flow UI root changelog
下一步?
下一個Jmix 的功能版本將在2023 年6 月發布,在這個版本中,我們將更新框架底層技術棧的版本,包括Spring、Spring Boot、Eclipselink 以及Vaadin。這次更新後,將會要求最低使用Java 17 作為開發和運行Jmix 程式的基線版本。
另一個重要的里程碑是為報表和BPM 擴展組件實現Flow UI 的界面模塊。
未來版本的詳細路線圖請訪問 GitHub 項目。 1.5 的後續補丁版本會按照大約每個月一次的頻率發布,提供常規更新和升級。
歡迎通過我們的 論壇 提供反饋和問題。謝謝大家對Jmix 的支持和建議!