diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d80d92871825023bee9a14f3b95518512057e17..ecc9275a9a8dd8cb2b2a52f5cdcd0561bc26862a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,8 @@ - 新增浮动按钮通用组件 - 新增图标菜单、列表菜单识别模型配置(支持自定义) - 新增树部件加载时显示loadding +- 新增树导航视图的视图刷新能力 +- 新增树面包屑绘制模式(头部样式),当配置树控件动态参数crumbshowmode=HEADERSTYLE或处于树导航栏视图时,将绘制该样式 ### Change @@ -102,6 +104,8 @@ - 多数据选择模式支持分割线 - 模态消息弹框样式与主题保持一致 - 优化树部件组件样式,不直接用基础css变量,定义组件专属变量 +- 移动端数据关系栏、数据关系分页打开导航视图时路由跳转改用replace,防止路由后退后还在当前页 +- 优化树导航栏组件样式,遵循主题调整原则 ### Fixed diff --git a/src/control/drbar/drbar.controller.ts b/src/control/drbar/drbar.controller.ts index a9a94b9abeec1c54f3a3b1ab2023f30125d6a6c5..c17686756d9372bd3f67125817a8918e8a2422df 100644 --- a/src/control/drbar/drbar.controller.ts +++ b/src/control/drbar/drbar.controller.ts @@ -332,7 +332,6 @@ export class DRBarController if (this.isCreate) { this.state.defaultItem = this.model.uniqueTag!; - return; } } @@ -567,6 +566,9 @@ export class DRBarController params, viewId: drBarItem.appViewId, isRoutePushed, + modalOptions: { + replace: true, + }, }); } diff --git a/src/control/drtab/drtab.controller.ts b/src/control/drtab/drtab.controller.ts index 03ed2135ba7d7cc5542dcf89981fd32aa3fd8def..ebf65d80e3a61afae9e7dbdee7d509c6ac217730 100644 --- a/src/control/drtab/drtab.controller.ts +++ b/src/control/drtab/drtab.controller.ts @@ -445,6 +445,9 @@ export class DRTabController params, viewId: drTabPages.appViewId, isRoutePushed, + modalOptions: { + replace: true, + }, }); } diff --git a/src/control/tree-exp-bar/tree-exp-bar.scss b/src/control/tree-exp-bar/tree-exp-bar.scss index 13085e2ad1349ccc46cfc4f4f98ddbd300304dbe..7973bd31642fe3a3e0acaa2f5e2797db3415cd6d 100644 --- a/src/control/tree-exp-bar/tree-exp-bar.scss +++ b/src/control/tree-exp-bar/tree-exp-bar.scss @@ -1,6 +1,7 @@ $control-treeexpbar: ( - caption-padding: getCssVar(spacing, base), - toolbar-padding: getCssVar(spacing, base), + // Spacing + spacing-caption-padding: getCssVar(spacing, base), + spacing-toolbar-padding: getCssVar(spacing, base), ); @include b('control-treeexpbar') { @@ -13,12 +14,12 @@ $control-treeexpbar: ( white-space: nowrap; } @include b('control-treeexpbar-caption') { - padding: getCssVar(control-treeexpbar, caption-padding); + padding: getCssVar(control-treeexpbar, spacing-caption-padding); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .#{bem(panel-ctrl-pos--treeexpbar_toolbar)}{ - padding: getCssVar(control-treeexpbar, toolbar-padding); + padding: getCssVar(control-treeexpbar, spacing-toolbar-padding); } } diff --git a/src/control/tree/tree.scss b/src/control/tree/tree.scss index ea8ba97da0e388d209d7bad5276addfadb8bd3e1..1bbd9522495df63fc54121d29bd0aefa715a36c8 100644 --- a/src/control/tree/tree.scss +++ b/src/control/tree/tree.scss @@ -8,6 +8,7 @@ $control-treeview: ( // Width/Height 'height-node': getCssVar(height, control, large), 'height-crumb': getCssVar('height-control', 'large'), + 'width-crumb-back-btn': rem(24px), // Spacing 'spacing-padding': 0 0 getCssVar(spacing, base) 0, 'spacing-node-padding': 0 getCssVar(spacing, base), @@ -52,13 +53,26 @@ $control-treeview: ( padding: getCssVar('control-treeview', 'spacing-node-padding'); height: getCssVar('control-treeview', 'height-node'); - &.selected { + // 修复节点点击后背景色改变 + &:hover { + background-color: unset; + } + + &.selected, + &.selected:hover { background-color: getCssVar('control-treeview', 'color-node-active'); } .vs-tree-inner { display: flex; align-items: center; + flex: 1; + overflow: hidden; + } + + .vs-tree-text { + text-overflow: ellipsis; + overflow: hidden; } .vs-icon-parent, @@ -160,6 +174,50 @@ $control-treeview: ( & > span:not(:last-child) { color: getCssVar('control-treeview', 'color-crumb-history-nav-text'); } + + // 导航内的(即树导航里的树)样式 + @include when(header-style) { + & > span:not(:last-child) { + display: none; + } + & > span:last-child { + display: flex; + width: 100%; + + // 返回按钮样式 + .#{bem(control-treeview-header, crumb, back-btn)} { + display: inline-block; + width: getCssVar('control-treeview', 'width-crumb-back-btn'); + color: getCssVar('control-treeview', 'color-crumb-history-nav-text'); + } + + // 面包屑文本与图标样式 + .vs-breadcrumb-link { + flex: 1; + overflow: hidden; + } + .#{bem(control-treeview-header, crumb)} { + display: flex; + align-items: center; + & > span:first-child { + // 图标样式 + display: flex; + align-items: center; + &::after { + display: none; + } + .#{bem(icon)} { + position: unset; + } + } + & > span:last-child { + text-overflow: ellipsis; + overflow: hidden; + flex: 1; + } + } + } + } } @include b(control-treeview-container) { diff --git a/src/control/tree/tree.tsx b/src/control/tree/tree.tsx index 3156ff5f14ea1137666dea55517933333e164766..7ffca2addd0bfb0bd4bcd3bfd9de4560f8d36014 100644 --- a/src/control/tree/tree.tsx +++ b/src/control/tree/tree.tsx @@ -95,6 +95,9 @@ export const TreeControl = defineComponent({ // 隐藏显示面包屑 const hiddenBreadcrumb = ref(false); + const isHeaderStyle = + c.crumbShowMode === 'HEADERSTYLE' || c.state.navigational; + // 创建图标节点 const createIconNode = (customProps: IData) => { const iop = h(IBizIcon, customProps); @@ -253,6 +256,22 @@ export const TreeControl = defineComponent({ c.state.mobExpandedKey = data._uuid || ''; }; + // 面包屑回退按钮点击事件 + const handleCrumbBack = (_e: MouseEvent, crumbItem?: IData) => { + _e.preventDefault(); + _e.stopPropagation(); + + const breads = crumbItem?.parent.list; + const prevIndex = breads.length - 2; + const prevNode = breads[prevIndex]; + if (!prevNode) return; + const store = prevNode.store; + const _data = prevNode.store?.data; + breads.splice(prevIndex + 1); + store.update(); + handleExpandedLastKey(_data); + }; + // 搜索 const debounceSearch = debounce(async () => { if (treeRef.value) { @@ -408,7 +427,7 @@ export const TreeControl = defineComponent({ renderNode, renderContent, customNodeClick, - }; + } as IParams; if (breadcrumb.value) { Object.assign(options, { @@ -438,6 +457,22 @@ export const TreeControl = defineComponent({ separator: '>', }, }); + + if (isHeaderStyle) { + Object.assign(options.breadcrumb, { + icon: (...args: IParams[]) => { + const crumbItem = args[2]; + const content = document.createElement('span'); + const iconDom = document.createElement('i'); + iconDom.className = 'van-icon van-icon-arrow-left'; + content.className = `${ns.bem('header', 'crumb', 'back-btn')}`; + content.appendChild(iconDom); + content.onclick = (_e: MouseEvent) => + handleCrumbBack.bind(this)(_e, crumbItem); + return content; + }, + }); + } } /** @@ -494,6 +529,7 @@ export const TreeControl = defineComponent({ checkedKeys, treeRefreshKey, hiddenBreadcrumb, + isHeaderStyle, onInput, loadData, onScroll, @@ -533,6 +569,7 @@ export const TreeControl = defineComponent({ class={[ this.ns.b('header'), this.ns.is('no-root', !this.treeData.length), + this.ns.is('header-style', this.isHeaderStyle), ]} > diff --git a/src/view-engine/mob-tree-exp-view.engine.ts b/src/view-engine/mob-tree-exp-view.engine.ts index 4e3b55e1523b5cba8941435ac6199d24e16801c5..87f44369e78b3f17b4d35a315e58d1ec4bdfed35 100644 --- a/src/view-engine/mob-tree-exp-view.engine.ts +++ b/src/view-engine/mob-tree-exp-view.engine.ts @@ -8,6 +8,8 @@ import { ViewEngineBase, IExpBarControlController, calcDeCodeNameById, + SysUIActionTag, + IApiMDViewCall, } from '@ibiz-template/runtime'; import { IAppDataEntity, IAppDETreeExplorerView } from '@ibiz/model-core'; @@ -15,7 +17,7 @@ export class MobTreeExpViewEngine extends ViewEngineBase { /** * 树导航视图控制器 */ - protected declare view: ViewController< + declare protected view: ViewController< IAppDETreeExplorerView, ITreeExpViewState, ITreeExpViewEvent @@ -81,6 +83,32 @@ export class MobTreeExpViewEngine extends ViewEngineBase { await this.loadEntityData(); } + async call( + key: keyof IApiMDViewCall, + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types + _args: any, + ): Promise { + if (key === SysUIActionTag.REFRESH) { + await this.refresh(); + return null; + } + } + + /** + * 视图刷新 + * + * @protected + * @return {*} {Promise} + * @memberof MobTreeExpViewEngine + */ + protected async refresh(): Promise { + // 重置当前展开节点,适配树控制load逻辑 + this.tree.state.mobExpandedKey = ''; + // 刷新后导航栏默认选中第一条并导航 + this.expBar.state.srfnav = ''; + await this.tree.refresh(); + } + /** * @description 检测实体数据变更 * @protected