import * as React from "react" ; import { AbstractWidgetProps , BackstageItem , BackstageItemUtilities , BadgeType , CommonStatusBarItem , CommonToolbarItem , ConditionalBooleanValue , IconSpecUtilities , StagePanelLocation , StagePanelSection , StageUsage , StatusBarSection , ToolbarItemUtilities , ToolbarOrientation , ToolbarUsage , UiItemsManager , UiItemsProvider , WidgetState , } from "@itwin/appui-abstract" ; import { CustomToolbarItem } from "@itwin/components-react" ; import { Indicator , StateManager , StatusBarItemUtilities , SyncUiEventDispatcher } from "@itwin/appui-react" ; import { IModelApp , NotifyMessageDetails , OutputMessagePriority , OutputMessageType } from "@itwin/core-frontend" ; import { PresentationPropertyGridWidget , PresentationPropertyGridWidgetControl } from "../widgets/PresentationPropertyGridWidget" ; import { OpenTraceDialogTool } from "../../tools/OpenTraceDialogTool" ; import { NetworkTracingFrontstage } from "../frontstages/NetworkTracing" ; import { getTestProviderState , setIsTraceAvailable } from "../../store" ; import { UiItemsProvidersTest } from "../../ui-items-providers-test" ; import { SelectedElementDataWidgetComponent } from "../widgets/SelectedElementDataWidget" ; import { VisibilityTreeComponent } from "../widgets/VisibilityWidget" ; import { ViewAttributesWidgetComponent } from "../widgets/ViewAttributesWidget" ; /** the following will import svgs into DOM and generate SymbolId that is used to locate the svg image. This
 * processing is done via the 'magic' webpack plugin and requires the use or the Bentley build scripts. */ import upstreamIcon from "../icons/upstream-query.svg?sprite" ; import downstreamIcon from "../icons/downstream-query.svg?sprite" ; import traceIcon from "../icons/query-multi.svg?sprite" ; /**
 * Test UiItemsProvider that provide buttons, widgets, and backstage item to NetworkTracing stage.
 */ export class NetworkTracingUiProvider implements UiItemsProvider { public static providerId = "ui-item-provider-test:NetworkTracingUiProvider" ; public readonly id = NetworkTracingUiProvider . providerId ; public static syncEventIdTraceAvailable = "ui-test:trace-available-changed" ; public static register ( ) { UiItemsManager . register ( new NetworkTracingUiProvider ( ) ) ; } public static unregister ( ) { UiItemsManager . unregister ( NetworkTracingUiProvider . providerId ) ; } /** static method that updates the value in redux store and dispatches a sync event so items are refreshed. */ public static toggleTraceTool ( ) { StateManager . store . dispatch ( setIsTraceAvailable ( ! getTestProviderState ( ) . isTraceAvailable ) ) ; SyncUiEventDispatcher . dispatchImmediateSyncUiEvent ( NetworkTracingUiProvider . syncEventIdTraceAvailable ) ; } public provideToolbarButtonItems ( stageId , _stageUsage , toolbarUsage , toolbarOrientation ) { if ( stageId === NetworkTracingFrontstage . stageId && toolbarUsage === ToolbarUsage . ContentManipulation && toolbarOrientation === ToolbarOrientation . Horizontal ) { /** The following ConditionalBooleanValue is used to determine the display state of some of the buttons
             * provided by this UiItemsProvider.
             */ const isTracingNotAvailableCondition = new ConditionalBooleanValue ( ( ) : boolean => { return ! getTestProviderState ( ) . isTraceAvailable ; } , [ NetworkTracingUiProvider . syncEventIdTraceAvailable ] , ! getTestProviderState ( ) . isTraceAvailable ) ; /** This is an example of where the tool generates the action button definition allowing user to pass item and group
             * priority to control ordering of buttons in toolbox. */ const getConnectedButton = OpenTraceDialogTool . getActionButtonDef ( 10 ) ; /** Sample group entry that hides if isTraceAvailable is set to false  */ const getDownstreamButton = ToolbarItemUtilities . createActionButton ( "trace-tool-downstream" , 15 , IconSpecUtilities . createSvgIconSpec ( downstreamIcon ) , UiItemsProvidersTest . translate ( "trace-tool-downstream" ) , ( ) : void => { IModelApp . notifications . outputMessage ( new NotifyMessageDetails ( OutputMessagePriority . Info , "trace-tool-downstream activated" , undefined , OutputMessageType . Toast ) ) ; } , { isHidden : isTracingNotAvailableCondition , badgeType : BadgeType . TechnicalPreview , } ) ; /** Sample group entry that disables if isTraceAvailable is set to false  */ const getUpstreamButton = ToolbarItemUtilities . createActionButton ( "trace-tool-upstream" , 20 , IconSpecUtilities . createSvgIconSpec ( upstreamIcon ) , UiItemsProvidersTest . translate ( "trace-tool-upstream" ) , ( ) : void => { IModelApp . notifications . outputMessage ( new NotifyMessageDetails ( OutputMessagePriority . Info , "trace-tool-upstream activated" , undefined , OutputMessageType . Toast ) ) ; } , { isDisabled : isTracingNotAvailableCondition , badgeType : BadgeType . TechnicalPreview , } ) ; /** The following defines a group button that contains tree actions buttons. Only the first entry produces a
             * result as it opens a sample dialog. The other two entries are used to show that the display state of
             * group button entries can be maintained by conditional values.
             */ const groupSpec = ToolbarItemUtilities . createGroupButton ( "trace-tool-group" , 230 , IconSpecUtilities . createSvgIconSpec ( traceIcon ) , UiItemsProvidersTest . translate ( "trace-tool-group" ) , [ getConnectedButton , getDownstreamButton , getUpstreamButton ] , { badgeType : BadgeType . TechnicalPreview , } ) ; /** The following test tool toggles the value Redux store and dispatches sync event that triggers tool refresh */ const toggleTracingSpec = ToolbarItemUtilities . createActionButton ( "trace-tool-toggle" , 235 , "icon-activity" , "Toggle isTraceAvailable" , ( ) : void => { NetworkTracingUiProvider . toggleTraceTool ( ) ; } ) ; /** The following test tool hides/shows based on value in Redux store via `isTraceAvailableCondition` */ const getStandaloneButton = ToolbarItemUtilities . createActionButton ( "trace-tool-standalone" , 232 , "icon-symbol" , UiItemsProvidersTest . translate ( "tools.trace-tool-standalone" ) , ( ) : void => { IModelApp . notifications . outputMessage ( new NotifyMessageDetails ( OutputMessagePriority . Info , "trace-tool-standalone activated" , undefined , OutputMessageType . Toast ) ) ; } , { isHidden : isTracingNotAvailableCondition , badgeType : BadgeType . TechnicalPreview , } ) ; const customVisibilityTreeButton = { isCustom : true , id : "test.custom-popup-with-visibility-tree" , itemPriority : 225 , icon : "icon-tree" , label : "Searchable Tree" , panelContentNode : < VisibilityTreeComponent />, keepContentsLoaded : true , groupPriority : 20 , } ; return [ groupSpec , getStandaloneButton , toggleTracingSpec , customVisibilityTreeButton ] ; } return [ ] ; } public provideWidgets ( stageId , _stageUsage , location , section ? ) { const widgets = [ ] ; if ( stageId === NetworkTracingFrontstage . stageId && location === StagePanelLocation . Right && section === StagePanelSection . Start ) { /** This widget when only be displayed when there is an element selected. */ const widget = { id : "ui-item-provider-test:elementDataListWidget" , icon : "icon-annotation-info" , label : "Data" , defaultState : WidgetState . Hidden , isFloatingStateSupported : true , getWidgetContent : ( ) => { return < SelectedElementDataWidgetComponent />; } , } ; widgets . push ( widget ) ; } if ( stageId === NetworkTracingFrontstage . stageId && ( location === StagePanelLocation . Right && section === StagePanelSection . End ) ) { const widget = { id : PresentationPropertyGridWidgetControl . id , label : PresentationPropertyGridWidgetControl . label , icon : PresentationPropertyGridWidgetControl . iconSpec , defaultState : WidgetState . Open , isFloatingStateSupported : true , getWidgetContent : ( ) => { return < PresentationPropertyGridWidget />; } , canPopout : true , } ; widgets . push ( widget ) ; } if ( stageId === NetworkTracingFrontstage . stageId || _stageUsage === StageUsage . General ) { const widget = { id : "ui-item-provider-test:ViewAttributesWidget" , label : "View Attributes" , icon : "icon-window-settings" , defaultState : WidgetState . Floating , isFloatingStateSupported : true , getWidgetContent : ( ) => { return < ViewAttributesWidgetComponent />; } , canPopout : true , } ; widgets . push ( widget ) ; } return widgets ; } public provideBackstageItems ( ) { const label = UiItemsProvidersTest . translate ( "backstage.networkTracingFrontstageLabel" ) ; return [ BackstageItemUtilities . createStageLauncher ( NetworkTracingFrontstage . stageId , 200 , 1 , label , "from provider" , "icon-draw" ) , ] ; } public provideStatusBarItems ( stageId , _stageUsage ) { const statusBarItems = [ ] ; if ( stageId === NetworkTracingFrontstage . stageId ) { statusBarItems . push ( StatusBarItemUtilities . createStatusBarItem ( "Test:Visibility" , StatusBarSection . Center , 50 , < Indicator iconSpec = "icon-tree" isLabelVisible = { false } label = "Searchable Tree" opened = { false } dialog = { < VisibilityTreeComponent / > } />)); } return statusBarItems ; } }