diff --git a/CHANGELOG.md b/CHANGELOG.md index b02a7f16f974227001da0339bfaa2ee9d060f6a3..81b36083373ae9803f7cd273677be840590fa09b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ - 更新向导面板语义化埋点 - 更新搜索栏语义化埋点 - 更新搜索表单语义化埋点 +- 更新数据看板、门户部件语义化埋点 ## [0.7.41-alpha.47] - 2026-05-29 diff --git a/src/control/dashboard/dashboard.scss b/src/control/dashboard/dashboard.scss index 63d285db11ee8c9bb614ca3133d713dc64346c0f..8584df17b99e6b3aad3bf40029e6d51e537c5f7e 100644 --- a/src/control/dashboard/dashboard.scss +++ b/src/control/dashboard/dashboard.scss @@ -1,21 +1,20 @@ -$control-dashboard: ( - // 边距 - spacing-sidebar-topleft-top: calc(#{getCssVar(view-page-caption, line-height)} + 2 * #{getCssVar(spacing, tight)}), - spacing-sidebar-topleft-left: rem(0px), - spacing-sidebar-topright-top: calc(#{getCssVar(view-page-caption, line-height)} + 2 * #{getCssVar(spacing, tight)}), - spacing-sidebar-topright-right: rem(0px), - spacing-sidebar-bottomleft-bottom: rem(0px), - spacing-sidebar-bottomleft-left: rem(0px), - spacing-sidebar-bottomright-bottom: rem(0px), - spacing-sidebar-bottomright-right: rem(0px), - spacing-sidebar-middleleft-top: 50%, - spacing-sidebar-middleleft-left: rem(0px), - spacing-sidebar-middleright-top: 50%, - spacing-sidebar-middleright-right: rem(0px), +$control-dashboard-anchor: ( + topleft-top: calc(#{getCssVar(view-page-caption, line-height)} + 2 * #{getCssVar(spacing, tight)}), + topleft-left: rem(0px), + topright-top: calc(#{getCssVar(view-page-caption, line-height)} + 2 * #{getCssVar(spacing, tight)}), + topright-right: rem(0px), + bottomleft-bottom: rem(0px), + bottomleft-left: rem(0px), + bottomright-bottom: rem(0px), + bottomright-right: rem(0px), + middleleft-top: 50%, + middleleft-left: rem(0px), + middleright-top: 50%, + middleright-right: rem(0px), ); @include b(control-dashboard) { - @include set-component-css-var('control-dashboard', $control-dashboard); + @include set-component-css-var('control-dashboard-anchor', $control-dashboard-anchor); height: 100%; overflow-y: auto; @@ -24,24 +23,24 @@ $control-dashboard: ( @include e(nav-bar) { @include m(topleft) { .van-index-bar__sidebar { - top: getCssVar('control-dashboard', 'spacing-sidebar-topleft-top'); + top: getCssVar('control-dashboard-anchor', 'topleft-top'); right: auto; - left: getCssVar('control-dashboard', 'spacing-sidebar-topleft-left'); + left: getCssVar('control-dashboard-anchor', 'topleft-left'); transform: none; } } @include m(topright) { .van-index-bar__sidebar { - top: getCssVar('control-dashboard', 'spacing-sidebar-topright-top'); - right: getCssVar('control-dashboard', 'spacing-sidebar-topright-right'); + top: getCssVar('control-dashboard-anchor', 'topright-top'); + right: getCssVar('control-dashboard-anchor', 'topright-right'); transform: none; } } @include m(bottomleft) { .van-index-bar__sidebar { - inset: auto auto getCssVar('control-dashboard', 'spacing-sidebar-bottomleft-bottom') getCssVar('control-dashboard', 'spacing-sidebar-bottomleft-left'); + inset: auto auto getCssVar('control-dashboard-anchor', 'bottomleft-bottom') getCssVar('control-dashboard-anchor', 'bottomleft-left'); transform: none; } } @@ -49,33 +48,29 @@ $control-dashboard: ( @include m(bottomright) { .van-index-bar__sidebar { top: auto; - right: getCssVar('control-dashboard', 'spacing-sidebar-bottomright-right'); - bottom: getCssVar('control-dashboard', 'spacing-sidebar-bottomright-bottom'); + right: getCssVar('control-dashboard-anchor', 'bottomright-right'); + bottom: getCssVar('control-dashboard-anchor', 'bottomright-bottom'); transform: none; } } @include m(middleleft) { .van-index-bar__sidebar { - top: getCssVar('control-dashboard', 'spacing-sidebar-middleleft-top'); + top: getCssVar('control-dashboard-anchor', 'middleleft-top'); right: auto; - left: getCssVar('control-dashboard', 'spacing-sidebar-middleleft-left'); + left: getCssVar('control-dashboard-anchor', 'middleleft-left'); } } @include m(middleright) { .van-index-bar__sidebar { - top: getCssVar('control-dashboard', 'spacing-sidebar-middleright-top'); - right: getCssVar('control-dashboard', 'spacing-sidebar-middleright-right'); + top: getCssVar('control-dashboard-anchor', 'middleright-top'); + right: getCssVar('control-dashboard-anchor', 'middleright-right'); } } } - @include b(control-dashboard-row) { - gap: getCssVar('control-dashboard', 'dashboard-margin'); - } - &.#{bem(control)} { width: auto; } diff --git a/src/control/dashboard/dashboard.tsx b/src/control/dashboard/dashboard.tsx index ec225d35db062cdc4933832b9fda8947d1697015..75c39e5a3268aea4e063e309f9a32c024a4fcab3 100644 --- a/src/control/dashboard/dashboard.tsx +++ b/src/control/dashboard/dashboard.tsx @@ -1,4 +1,8 @@ -import { useControlController, useNamespace } from '@ibiz-template/vue3-util'; +import { + useControlController, + useNamespace, + useSemanticNode, +} from '@ibiz-template/vue3-util'; import { ConcreteComponent, defineComponent, @@ -111,6 +115,31 @@ export const DashboardControl = defineComponent({ (...args) => new DashboardController(...args), ); const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`); + const { semanticClass, semanticStyle } = useSemanticNode(c); + + // 子类类名透传 + const childClass = [ + { + class: semanticClass('anchor'), + selector: '.van-index-bar__sidebar', + }, + { + class: semanticClass('anchor.item'), + selector: '.van-index-bar__index', + }, + ]; + + // 子类样式透传 + const childStyle = [ + { + style: semanticStyle('anchor'), + selector: '.van-index-bar__sidebar', + }, + { + style: semanticStyle('anchor.item'), + selector: '.van-index-bar__index', + }, + ]; c.evt.on('onInitPortlets', () => { // 数据看板成员state响应式 @@ -168,6 +197,10 @@ export const DashboardControl = defineComponent({ ns, initialized, isShowFloatingButton, + semanticClass, + semanticStyle, + childClass, + childStyle, handleFloatingButtonClick, }; }, @@ -176,7 +209,11 @@ export const DashboardControl = defineComponent({ const { state, model } = this.c; let content = ( - + {model.controls?.map((child: IDBPortletPart) => { return ( {content} @@ -214,11 +253,17 @@ export const DashboardControl = defineComponent({ } return ( - + {state.isCreated && this.initialized && content} {state.isCreated && this.initialized && this.isShowFloatingButton && ( )} diff --git a/src/control/dashboard/portlet/actionbar-portlet/actionbar-portlet.tsx b/src/control/dashboard/portlet/actionbar-portlet/actionbar-portlet.tsx index 74bca87cf2a7283312af3ceb280e521be87bb517..885324658b942bab62e57b1b3f67fd3a022afd7e 100644 --- a/src/control/dashboard/portlet/actionbar-portlet/actionbar-portlet.tsx +++ b/src/control/dashboard/portlet/actionbar-portlet/actionbar-portlet.tsx @@ -1,4 +1,4 @@ -import { useNamespace } from '@ibiz-template/vue3-util'; +import { useNamespace, useSemanticNode } from '@ibiz-template/vue3-util'; import { defineComponent, PropType } from 'vue'; import { IDBToolbarPortlet, IUIActionGroupDetail } from '@ibiz/model-core'; import { ActionBarPortletController } from '@ibiz-template/runtime'; @@ -19,6 +19,9 @@ export const ActionBarPortlet = defineComponent({ const ns = useNamespace( `portlet-${props.modelData.portletType?.toLowerCase()}`, ); + const { semanticClass, semanticStyle } = useSemanticNode( + props.controller.dashboard, + ); const zIndex = props.controller.dashboard.state.zIndex; @@ -30,7 +33,7 @@ export const ActionBarPortlet = defineComponent({ await props.controller.onActionClick(detail, event); }; - return { ns, zIndex, onActionClick }; + return { ns, zIndex, onActionClick, semanticClass, semanticStyle }; }, render() { @@ -45,6 +48,12 @@ export const ActionBarPortlet = defineComponent({ {this.modelData.uiactionGroup && ( { return item.controlType === ControlType.CHART; @@ -46,7 +49,7 @@ export const ChartPortlet = defineComponent({ clearInterval(timerTag); }); - return { ns, chart }; + return { ns, chart, semanticClass, semanticStyle }; }, render() { @@ -62,6 +65,12 @@ export const ChartPortlet = defineComponent({ context, params, modelData: this.chart, + class: this.semanticClass('portlet.chart', { + chart: this.controller, + }), + style: this.semanticStyle('portlet.chart', { + chart: this.controller, + }), })} ); diff --git a/src/control/dashboard/portlet/container-portlet/container-portlet.tsx b/src/control/dashboard/portlet/container-portlet/container-portlet.tsx index b44d7cf24701dd972d06130423f444befa261a07..1f0a25a4c023a6efcd4c2afdf05efb072873873b 100644 --- a/src/control/dashboard/portlet/container-portlet/container-portlet.tsx +++ b/src/control/dashboard/portlet/container-portlet/container-portlet.tsx @@ -1,4 +1,4 @@ -import { useNamespace } from '@ibiz-template/vue3-util'; +import { useNamespace, useSemanticNode } from '@ibiz-template/vue3-util'; import { defineComponent, PropType, VNode } from 'vue'; import { IDBContainerPortletPart } from '@ibiz/model-core'; import { ContainerPortletController } from '@ibiz-template/runtime'; @@ -19,12 +19,23 @@ export const ContainerPortlet = defineComponent({ const ns = useNamespace( `portlet-${props.modelData.portletType?.toLowerCase()}`, ); - return { ns }; + const { semanticClass, semanticStyle } = useSemanticNode( + props.controller.dashboard, + ); + return { ns, semanticClass, semanticStyle }; }, render() { const defaultSlots: VNode[] = this.$slots.default?.() || []; const content = ( - + {defaultSlots.map(slot => { const props = slot.props as IData; if (!props || !props.controller) { diff --git a/src/control/dashboard/portlet/html-portlet/html-portlet.tsx b/src/control/dashboard/portlet/html-portlet/html-portlet.tsx index c7766fa5566bde7395bb0077f9d046faf5de743f..834c4ac4129435ddbd260201adff011b4e6f4b90 100644 --- a/src/control/dashboard/portlet/html-portlet/html-portlet.tsx +++ b/src/control/dashboard/portlet/html-portlet/html-portlet.tsx @@ -1,4 +1,4 @@ -import { useNamespace } from '@ibiz-template/vue3-util'; +import { useNamespace, useSemanticNode } from '@ibiz-template/vue3-util'; import { defineComponent, PropType } from 'vue'; import { IDBHtmlPortletPart } from '@ibiz/model-core'; import { HtmlPortletController } from '@ibiz-template/runtime'; @@ -20,8 +20,11 @@ export const HtmlPortlet = defineComponent({ const ns = useNamespace( `portlet-${props.modelData.portletType?.toLowerCase()}`, ); + const { semanticClass, semanticStyle } = useSemanticNode( + props.controller.dashboard, + ); - return { ns }; + return { ns, semanticClass, semanticStyle }; }, render() { @@ -32,7 +35,11 @@ export const HtmlPortlet = defineComponent({ ]; return ( - + ); }, diff --git a/src/control/dashboard/portlet/list-portlet/list-portlet.tsx b/src/control/dashboard/portlet/list-portlet/list-portlet.tsx index 6fd1fdc6f1530b976a2549f6081f8dab007f24b5..37f373fb183780f8184e57220ba1695ead477e43 100644 --- a/src/control/dashboard/portlet/list-portlet/list-portlet.tsx +++ b/src/control/dashboard/portlet/list-portlet/list-portlet.tsx @@ -1,4 +1,4 @@ -import { useNamespace } from '@ibiz-template/vue3-util'; +import { useNamespace, useSemanticNode } from '@ibiz-template/vue3-util'; import { defineComponent, PropType, @@ -26,6 +26,9 @@ export const ListPortlet = defineComponent({ const ns = useNamespace( `portlet-${props.modelData.portletType?.toLowerCase()}`, ); + const { semanticClass, semanticStyle } = useSemanticNode( + props.controller.dashboard, + ); const list = props.modelData.controls?.find(item => { return item.controlType === ControlType.LIST; @@ -46,7 +49,7 @@ export const ListPortlet = defineComponent({ clearInterval(timerTag); }); - return { ns, list }; + return { ns, list, semanticClass, semanticStyle }; }, render() { @@ -59,6 +62,8 @@ export const ListPortlet = defineComponent({ return ( {h(resolveComponent('IBizControlShell'), { + class: this.semanticClass('portlet.list', { list: this.controller }), + style: this.semanticStyle('portlet.list', { list: this.controller }), context, params, modelData: this.list, diff --git a/src/control/dashboard/portlet/menu-portlet/menu-portlet.tsx b/src/control/dashboard/portlet/menu-portlet/menu-portlet.tsx index 4e4a9d3f046ffd62fd4d3c1892dc2454133bbed0..813441f41cad775b87425c76345d5d00a70342ba 100644 --- a/src/control/dashboard/portlet/menu-portlet/menu-portlet.tsx +++ b/src/control/dashboard/portlet/menu-portlet/menu-portlet.tsx @@ -1,4 +1,4 @@ -import { useNamespace } from '@ibiz-template/vue3-util'; +import { useNamespace, useSemanticNode } from '@ibiz-template/vue3-util'; import { defineComponent, PropType } from 'vue'; import { IAppMenu, IDBAppMenuPortletPart } from '@ibiz/model-core'; import { MenuPortletController } from '@ibiz-template/runtime'; @@ -19,10 +19,13 @@ export const MenuPortlet = defineComponent({ const ns = useNamespace( `portlet-${props.modelData.portletType?.toLowerCase()}`, ); + const { semanticClass, semanticStyle } = useSemanticNode( + props.controller.dashboard, + ); const menu: IAppMenu | undefined = props.modelData.controls?.find(item => { return item.controlType === 'APPMENU'; }); - return { ns, menu }; + return { ns, menu, semanticClass, semanticStyle }; }, render() { @@ -35,6 +38,12 @@ export const MenuPortlet = defineComponent({ {this.menu && ( { if (c.model.portletType === 'RAWITEM') { @@ -95,6 +96,8 @@ export const PortletLayout = defineComponent({ headerAction, renderContent, onActionClick, + semanticClass, + semanticStyle, }; }, render() { @@ -111,7 +114,16 @@ export const PortletLayout = defineComponent({ headerRender = (
{this.renderContent(this.header)}
@@ -120,7 +132,16 @@ export const PortletLayout = defineComponent({ headerRender = (
{this.headerBg && (
@@ -132,7 +153,17 @@ export const PortletLayout = defineComponent({ (this.headerCaption ? ( this.renderContent(this.headerCaption) ) : ( -
+
+
{headerRender} -
+
{this.$slots.default?.()}
diff --git a/src/control/dashboard/portlet/rawitem-portlet/rawitem-portlet.scss b/src/control/dashboard/portlet/rawitem-portlet/rawitem-portlet.scss index 3c78d9906de366a4f0ca0b35a8907322e9e67df8..509b2816b9c7fc59da62846194ea1d05cf3f7350 100644 --- a/src/control/dashboard/portlet/rawitem-portlet/rawitem-portlet.scss +++ b/src/control/dashboard/portlet/rawitem-portlet/rawitem-portlet.scss @@ -1,6 +1,6 @@ @include b('portlet-rawitem') { >.#{bem('portlet-layout-content')} { - padding: getCssVar(portlet-layout, spacing-content-padding) !important; - margin: getCssVar(portlet-layout, spacing-content-margin) !important; + padding: getCssVar(portlet-layout-content, padding) !important; + margin: getCssVar(portlet-layout-content, margin) !important; } } \ No newline at end of file diff --git a/src/control/dashboard/portlet/rawitem-portlet/rawitem-portlet.tsx b/src/control/dashboard/portlet/rawitem-portlet/rawitem-portlet.tsx index 80133f5fd9d13e6fcfbce52a04786b3a0fc45414..b13e47b5a11758c39dfd15e3534bcc07e661c415 100644 --- a/src/control/dashboard/portlet/rawitem-portlet/rawitem-portlet.tsx +++ b/src/control/dashboard/portlet/rawitem-portlet/rawitem-portlet.tsx @@ -1,4 +1,4 @@ -import { useNamespace } from '@ibiz-template/vue3-util'; +import { useNamespace, useSemanticNode } from '@ibiz-template/vue3-util'; import { defineComponent, PropType, resolveComponent, h } from 'vue'; import { IDBRawItemPortletPart } from '@ibiz/model-core'; import { RawItemPortletController } from '@ibiz-template/runtime'; @@ -20,10 +20,13 @@ export const RawItemPortlet = defineComponent({ const ns = useNamespace( `portlet-${props.modelData.portletType?.toLowerCase()}`, ); + const { semanticClass, semanticStyle } = useSemanticNode( + props.controller.dashboard, + ); const rawItem = props.modelData; - return { ns, rawItem }; + return { ns, rawItem, semanticClass, semanticStyle }; }, render() { @@ -35,6 +38,12 @@ export const RawItemPortlet = defineComponent({ return ( {h(resolveComponent('iBizRawItem'), { + class: this.semanticClass('portlet.rawitem', { + rawitem: this.controller, + }), + style: this.semanticStyle('portlet.rawitem', { + rawitem: this.controller, + }), rawItem: this.rawItem, })} diff --git a/src/control/dashboard/portlet/view-portlet/view-portlet.tsx b/src/control/dashboard/portlet/view-portlet/view-portlet.tsx index 68db4b578e1e132bc600f87b1b0bd1a6668a7677..3839bf14ce6a9a64f19534fc1ff36d2d2561215b 100644 --- a/src/control/dashboard/portlet/view-portlet/view-portlet.tsx +++ b/src/control/dashboard/portlet/view-portlet/view-portlet.tsx @@ -1,4 +1,4 @@ -import { useNamespace } from '@ibiz-template/vue3-util'; +import { useNamespace, useSemanticNode } from '@ibiz-template/vue3-util'; import { defineComponent, h, PropType, resolveComponent } from 'vue'; import { IDBAppViewPortletPart } from '@ibiz/model-core'; import { ViewPortletController } from '@ibiz-template/runtime'; @@ -19,8 +19,11 @@ export const ViewPortlet = defineComponent({ const ns = useNamespace( `portlet-${props.modelData.portletType?.toLowerCase()}`, ); + const { semanticClass, semanticStyle } = useSemanticNode( + props.controller.dashboard, + ); const view = props.modelData.portletAppView; - return { ns, view }; + return { ns, view, semanticClass, semanticStyle }; }, render() { @@ -33,6 +36,8 @@ export const ViewPortlet = defineComponent({ return ( {h(resolveComponent('IBizViewShell'), { + class: this.semanticClass('portlet.view', { view: this.controller }), + style: this.semanticStyle('portlet.view', { view: this.controller }), context, params, modelData: this.view,