@itwin/tree-widget-react 2.0.0-dev.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/lib/cjs/components/SelectableTree.d.ts +9 -1
  3. package/lib/cjs/components/SelectableTree.js +6 -6
  4. package/lib/cjs/components/SelectableTree.js.map +1 -1
  5. package/lib/cjs/components/SelectableTree.scss +0 -16
  6. package/lib/cjs/components/TreeSelector.d.ts +28 -0
  7. package/lib/cjs/components/TreeSelector.js +27 -0
  8. package/lib/cjs/components/TreeSelector.js.map +1 -0
  9. package/lib/cjs/components/TreeSelector.scss +27 -0
  10. package/lib/cjs/components/TreeWidgetUiItemsProvider.d.ts +9 -1
  11. package/lib/cjs/components/TreeWidgetUiItemsProvider.js +14 -9
  12. package/lib/cjs/components/TreeWidgetUiItemsProvider.js.map +1 -1
  13. package/lib/cjs/components/tree-header/TreeHeader.d.ts +3 -0
  14. package/lib/cjs/components/tree-header/TreeHeader.js +11 -9
  15. package/lib/cjs/components/tree-header/TreeHeader.js.map +1 -1
  16. package/lib/cjs/components/tree-header/TreeHeader.scss +28 -0
  17. package/lib/cjs/components/trees/category-tree/CategoriesTreeComponent.js +13 -8
  18. package/lib/cjs/components/trees/category-tree/CategoriesTreeComponent.js.map +1 -1
  19. package/lib/cjs/components/trees/category-tree/CategoryVisibilityHandler.d.ts +2 -2
  20. package/lib/cjs/components/trees/common/TreeRenderer.scss +32 -0
  21. package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.js +17 -12
  22. package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
  23. package/lib/esm/components/SelectableTree.d.ts +9 -1
  24. package/lib/esm/components/SelectableTree.js +6 -6
  25. package/lib/esm/components/SelectableTree.js.map +1 -1
  26. package/lib/esm/components/SelectableTree.scss +0 -16
  27. package/lib/esm/components/TreeSelector.d.ts +28 -0
  28. package/lib/esm/components/TreeSelector.js +23 -0
  29. package/lib/esm/components/TreeSelector.js.map +1 -0
  30. package/lib/esm/components/TreeSelector.scss +27 -0
  31. package/lib/esm/components/TreeWidgetUiItemsProvider.d.ts +9 -1
  32. package/lib/esm/components/TreeWidgetUiItemsProvider.js +12 -8
  33. package/lib/esm/components/TreeWidgetUiItemsProvider.js.map +1 -1
  34. package/lib/esm/components/tree-header/TreeHeader.d.ts +3 -0
  35. package/lib/esm/components/tree-header/TreeHeader.js +11 -9
  36. package/lib/esm/components/tree-header/TreeHeader.js.map +1 -1
  37. package/lib/esm/components/tree-header/TreeHeader.scss +28 -0
  38. package/lib/esm/components/trees/category-tree/CategoriesTreeComponent.js +10 -8
  39. package/lib/esm/components/trees/category-tree/CategoriesTreeComponent.js.map +1 -1
  40. package/lib/esm/components/trees/category-tree/CategoryVisibilityHandler.d.ts +2 -2
  41. package/lib/esm/components/trees/common/TreeRenderer.scss +32 -0
  42. package/lib/esm/components/trees/models-tree/ModelsTreeComponent.js +14 -12
  43. package/lib/esm/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
  44. package/lib/public/locales/en/TreeWidget.json +1 -0
  45. package/package.json +12 -12
  46. package/lib/cjs/e2e-tests/TreeWidget.test.d.ts +0 -2
  47. package/lib/cjs/e2e-tests/TreeWidget.test.js +0 -104
  48. package/lib/cjs/e2e-tests/TreeWidget.test.js.map +0 -1
  49. package/lib/cjs/e2e-tests/utils.d.ts +0 -10
  50. package/lib/cjs/e2e-tests/utils.js +0 -50
  51. package/lib/cjs/e2e-tests/utils.js.map +0 -1
  52. package/lib/esm/e2e-tests/TreeWidget.test.d.ts +0 -2
  53. package/lib/esm/e2e-tests/TreeWidget.test.js +0 -99
  54. package/lib/esm/e2e-tests/TreeWidget.test.js.map +0 -1
  55. package/lib/esm/e2e-tests/utils.d.ts +0 -10
  56. package/lib/esm/e2e-tests/utils.js +0 -38
  57. package/lib/esm/e2e-tests/utils.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ModelsTreeComponent.js","sourceRoot":"","sources":["../../../../../src/components/trees/models-tree/ModelsTreeComponent.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"../VisibilityTreeBase.scss\";\nimport { Fragment, useEffect, useMemo, useState } from \"react\";\nimport { useActiveIModelConnection, useActiveViewport } from \"@itwin/appui-react\";\nimport { SvgVisibilityHalf, SvgVisibilityHide, SvgVisibilityShow } from \"@itwin/itwinui-icons-react\";\nimport { Button, IconButton } from \"@itwin/itwinui-react\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { TreeHeader } from \"../../tree-header/TreeHeader\";\nimport { useTreeFilteringState } from \"../../TreeFilteringState\";\nimport { AutoSizer } from \"../../utils/AutoSizer\";\nimport { ModelsTree } from \"./ModelsTree\";\nimport { areAllModelsVisible, hideAllModels, invertAllModels, showAllModels, toggleModels } from \"./ModelsVisibilityHandler\";\nimport { queryModelsForHeaderActions } from \"./Utils\";\n\nimport type { IModelConnection, ScreenViewport, Viewport } from \"@itwin/core-frontend\";\nimport type { TreeHeaderButtonProps } from \"../../tree-header/TreeHeader\";\nimport type { ModelsTreeProps } from \"./ModelsTree\";\n/**\n * Information about a single Model.\n * @public\n */\nexport interface ModelInfo {\n id: string;\n isPlanProjection?: boolean;\n}\n\n/**\n * Props that get passed to [[ModelsTreeComponent]] header button renderer.\n * @see ModelTreeComponentProps.headerButtons\n * @public\n */\nexport interface ModelsTreeHeaderButtonProps extends TreeHeaderButtonProps {\n /** A list of models available in the iModel. */\n models: ModelInfo[];\n}\n\n/**\n * Props for [[ModelsTreeComponent]].\n * @public\n */\nexport interface ModelTreeComponentProps extends Omit<ModelsTreeProps, \"iModel\" | \"activeView\" | \"width\" | \"height\" | \"filterInfo\" | \"onFilterApplied\"> {\n /**\n * Renderers of header buttons. Defaults to:\n * ```ts\n * [\n * ModelsTreeComponent.ShowAllButton,\n * ModelsTreeComponent.HideAllButton,\n * ModelsTreeComponent.InvertButton,\n * ModelsTreeComponent.View2DButton,\n * ModelsTreeComponent.View3DButton,\n * ]\n * ```\n */\n headerButtons?: Array<(props: ModelsTreeHeaderButtonProps) => React.ReactNode>;\n}\n\n/**\n * A component that renders [[ModelsTree]] and a header with filtering capabilities\n * and header buttons.\n * @public\n */\nexport const ModelsTreeComponent = (props: ModelTreeComponentProps) => {\n const iModel = useActiveIModelConnection();\n const viewport = useActiveViewport();\n\n if (!iModel || !viewport) {\n return null;\n }\n\n return <ModelsTreeComponentImpl {...props} iModel={iModel} viewport={viewport} />;\n};\n\n/**\n * Renders a \"Show all\" button that enables display of all models.\n * @public\n */\nModelsTreeComponent.ShowAllButton = ShowAllButton;\n\n/**\n * Renders a \"Hide all\" button that disables display of all models.\n * @public\n */\nModelsTreeComponent.HideAllButton = HideAllButton;\n\n/**\n * Renders an \"Invert all\" button that inverts display of all models.\n * @public\n */\nModelsTreeComponent.InvertButton = InvertButton;\n\n/**\n * Renders a \"View 2D\" button that enables display of all plan projection models and disables all others.\n * @public\n */\nModelsTreeComponent.View2DButton = View2DButton;\n\n/**\n * Renders a \"View 3D\" button that enables display of all non-plan projection models and disables all plan projection ones.\n * @public\n */\nModelsTreeComponent.View3DButton = View3DButton;\n\n/**\n * Id of the component. May be used when a creating a [[TreeDefinition]] for [[SelectableTree]].\n * @public\n */\nModelsTreeComponent.id = \"models-tree\";\n\n/**\n * Label of the component. May be used when a creating a [[TreeDefinition]] for [[SelectableTree]].\n * @public\n */\nModelsTreeComponent.getLabel = () => TreeWidget.translate(\"models\");\n\nfunction ModelsTreeComponentImpl(props: ModelTreeComponentProps & { iModel: IModelConnection; viewport: ScreenViewport }) {\n const [availableModels, setAvailableModels] = useState<ModelInfo[]>([]);\n\n const { viewport, iModel } = props;\n\n const { searchOptions, filterString, onFilterApplied } = useTreeFilteringState();\n\n useEffect(() => {\n queryModelsForHeaderActions(iModel)\n .then((modelInfos: ModelInfo[]) => {\n setAvailableModels(modelInfos);\n })\n .catch((_e) => {\n setAvailableModels([]);\n });\n }, [iModel]);\n\n const filterInfo = useMemo(\n () => ({ filter: filterString, activeMatchIndex: searchOptions.activeMatchIndex }),\n [filterString, searchOptions.activeMatchIndex],\n );\n\n return (\n <div className=\"tree-widget-tree-with-header\">\n <TreeHeader\n onFilterClear={searchOptions.onFilterCancel}\n onFilterStart={searchOptions.onFilterStart}\n onSelectedChanged={searchOptions.onResultSelectedChanged}\n resultCount={searchOptions.matchedResultCount}\n selectedIndex={searchOptions.activeMatchIndex}\n >\n {props.headerButtons\n ? props.headerButtons.map((btn, index) => <Fragment key={index}>{btn({ viewport, models: availableModels })}</Fragment>)\n : [\n <ShowAllButton viewport={viewport} models={availableModels} key=\"show-all-btn\" />,\n <HideAllButton viewport={viewport} models={availableModels} key=\"hide-all-btn\" />,\n <InvertButton viewport={viewport} models={availableModels} key=\"invert-all-btn\" />,\n <View2DButton viewport={viewport} models={availableModels} key=\"view-2d-btn\" />,\n <View3DButton viewport={viewport} models={availableModels} key=\"view-3d-btn\" />,\n ]}\n </TreeHeader>\n <div className=\"tree-widget-tree-content\">\n <AutoSizer>\n {({ width, height }) => (\n <ModelsTree\n {...props}\n iModel={iModel}\n activeView={viewport}\n width={width}\n height={height}\n filterInfo={filterInfo}\n onFilterApplied={onFilterApplied}\n />\n )}\n </AutoSizer>\n </div>\n </div>\n );\n}\n\nfunction ShowAllButton(props: ModelsTreeHeaderButtonProps) {\n return (\n <IconButton\n size=\"small\"\n styleType=\"borderless\"\n title={TreeWidget.translate(\"showAll\")}\n onClick={() =>\n void showAllModels(\n props.models.map((model) => model.id),\n props.viewport,\n )\n }\n >\n <SvgVisibilityShow />\n </IconButton>\n );\n}\n\nfunction HideAllButton(props: ModelsTreeHeaderButtonProps) {\n return (\n <IconButton\n size=\"small\"\n styleType=\"borderless\"\n title={TreeWidget.translate(\"hideAll\")}\n onClick={() =>\n void hideAllModels(\n props.models.map((model) => model.id),\n props.viewport,\n )\n }\n >\n <SvgVisibilityHide />\n </IconButton>\n );\n}\n\nfunction InvertButton(props: ModelsTreeHeaderButtonProps) {\n return (\n <IconButton\n size=\"small\"\n styleType=\"borderless\"\n title={TreeWidget.translate(\"invert\")}\n onClick={() =>\n void invertAllModels(\n props.models.map((model) => model.id),\n props.viewport,\n )\n }\n >\n <SvgVisibilityHalf />\n </IconButton>\n );\n}\n\nfunction View2DButton(props: ModelsTreeHeaderButtonProps) {\n const models2d = useMemo(() => {\n return props.models.filter((model) => model.isPlanProjection).map((model) => model.id);\n }, [props.models]);\n\n const [is2dToggleActive, setIs2dToggleActive] = useState(false);\n\n useEffect(() => {\n setIs2dToggleActive(areAllModelsVisible(models2d, props.viewport));\n return props.viewport.onViewedModelsChanged.addListener((vp: Viewport) => setIs2dToggleActive(areAllModelsVisible(models2d, vp)));\n }, [models2d, props.viewport]);\n\n return (\n <Button\n size=\"small\"\n styleType=\"borderless\"\n title={TreeWidget.translate(\"toggle2DViews\")}\n onClick={() => void toggleModels(models2d, is2dToggleActive, props.viewport)}\n disabled={models2d.length === 0}\n endIcon={is2dToggleActive ? <SvgVisibilityShow /> : <SvgVisibilityHide />}\n >\n {TreeWidget.translate(\"label2D\")}\n </Button>\n );\n}\n\nfunction View3DButton(props: ModelsTreeHeaderButtonProps) {\n const models3d = useMemo(() => {\n return props.models.filter((model) => !model.isPlanProjection).map((model) => model.id);\n }, [props.models]);\n\n const [is3dToggleActive, setIs3dToggleActive] = useState(false);\n\n useEffect(() => {\n setIs3dToggleActive(areAllModelsVisible(models3d, props.viewport));\n return props.viewport.onViewedModelsChanged.addListener((vp: Viewport) => setIs3dToggleActive(areAllModelsVisible(models3d, vp)));\n }, [models3d, props.viewport]);\n\n return (\n <Button\n size=\"small\"\n styleType=\"borderless\"\n title={TreeWidget.translate(\"toggle3DViews\")}\n onClick={() => void toggleModels(models3d, is3dToggleActive, props.viewport)}\n disabled={models3d.length === 0}\n endIcon={is3dToggleActive ? <SvgVisibilityShow /> : <SvgVisibilityHide />}\n >\n {TreeWidget.translate(\"label3D\")}\n </Button>\n );\n}\n"]}
1
+ {"version":3,"file":"ModelsTreeComponent.js","sourceRoot":"","sources":["../../../../../src/components/trees/models-tree/ModelsTreeComponent.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"../VisibilityTreeBase.scss\";\nimport { Fragment, useEffect, useMemo, useState } from \"react\";\nimport { useActiveIModelConnection, useActiveViewport } from \"@itwin/appui-react\";\nimport { SvgVisibilityHalf, SvgVisibilityHide, SvgVisibilityShow } from \"@itwin/itwinui-icons-react\";\nimport { Button, IconButton } from \"@itwin/itwinui-react\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { TreeHeader } from \"../../tree-header/TreeHeader\";\nimport { useTreeFilteringState } from \"../../TreeFilteringState\";\nimport { AutoSizer } from \"../../utils/AutoSizer\";\nimport { ModelsTree } from \"./ModelsTree\";\nimport { areAllModelsVisible, hideAllModels, invertAllModels, showAllModels, toggleModels } from \"./ModelsVisibilityHandler\";\nimport { queryModelsForHeaderActions } from \"./Utils\";\n\nimport type { IModelConnection, ScreenViewport, Viewport } from \"@itwin/core-frontend\";\nimport type { TreeHeaderButtonProps } from \"../../tree-header/TreeHeader\";\nimport type { ModelsTreeProps } from \"./ModelsTree\";\nimport classNames from \"classnames\";\n/**\n * Information about a single Model.\n * @public\n */\nexport interface ModelInfo {\n id: string;\n isPlanProjection?: boolean;\n}\n\n/**\n * Props that get passed to [[ModelsTreeComponent]] header button renderer.\n * @see ModelTreeComponentProps.headerButtons\n * @public\n */\nexport interface ModelsTreeHeaderButtonProps extends TreeHeaderButtonProps {\n /** A list of models available in the iModel. */\n models: ModelInfo[];\n}\n\n/**\n * Props for [[ModelsTreeComponent]].\n * @public\n */\nexport interface ModelTreeComponentProps extends Omit<ModelsTreeProps, \"iModel\" | \"activeView\" | \"width\" | \"height\" | \"filterInfo\" | \"onFilterApplied\"> {\n /**\n * Renderers of header buttons. Defaults to:\n * ```ts\n * [\n * ModelsTreeComponent.ShowAllButton,\n * ModelsTreeComponent.HideAllButton,\n * ModelsTreeComponent.InvertButton,\n * ModelsTreeComponent.View2DButton,\n * ModelsTreeComponent.View3DButton,\n * ]\n * ```\n */\n headerButtons?: Array<(props: ModelsTreeHeaderButtonProps) => React.ReactNode>;\n}\n\n/**\n * A component that renders [[ModelsTree]] and a header with filtering capabilities\n * and header buttons.\n * @public\n */\nexport const ModelsTreeComponent = (props: ModelTreeComponentProps) => {\n const iModel = useActiveIModelConnection();\n const viewport = useActiveViewport();\n\n if (!iModel || !viewport) {\n return null;\n }\n\n return <ModelsTreeComponentImpl {...props} iModel={iModel} viewport={viewport} />;\n};\n\n/**\n * Renders a \"Show all\" button that enables display of all models.\n * @public\n */\nModelsTreeComponent.ShowAllButton = ShowAllButton;\n\n/**\n * Renders a \"Hide all\" button that disables display of all models.\n * @public\n */\nModelsTreeComponent.HideAllButton = HideAllButton;\n\n/**\n * Renders an \"Invert all\" button that inverts display of all models.\n * @public\n */\nModelsTreeComponent.InvertButton = InvertButton;\n\n/**\n * Renders a \"View 2D\" button that enables display of all plan projection models and disables all others.\n * @public\n */\nModelsTreeComponent.View2DButton = View2DButton;\n\n/**\n * Renders a \"View 3D\" button that enables display of all non-plan projection models and disables all plan projection ones.\n * @public\n */\nModelsTreeComponent.View3DButton = View3DButton;\n\n/**\n * Id of the component. May be used when a creating a [[TreeDefinition]] for [[SelectableTree]].\n * @public\n */\nModelsTreeComponent.id = \"models-tree\";\n\n/**\n * Label of the component. May be used when a creating a [[TreeDefinition]] for [[SelectableTree]].\n * @public\n */\nModelsTreeComponent.getLabel = () => TreeWidget.translate(\"models\");\n\nfunction ModelsTreeComponentImpl(props: ModelTreeComponentProps & { iModel: IModelConnection; viewport: ScreenViewport }) {\n const [availableModels, setAvailableModels] = useState<ModelInfo[]>([]);\n const { viewport, iModel } = props;\n const { searchOptions, filterString, onFilterApplied } = useTreeFilteringState();\n const contentClassName = classNames(\"tree-widget-tree-content\", props.density === \"enlarged\" && \"enlarge\");\n\n useEffect(() => {\n queryModelsForHeaderActions(iModel)\n .then((modelInfos: ModelInfo[]) => {\n setAvailableModels(modelInfos);\n })\n .catch((_e) => {\n setAvailableModels([]);\n });\n }, [iModel]);\n\n const filterInfo = useMemo(\n () => ({ filter: filterString, activeMatchIndex: searchOptions.activeMatchIndex }),\n [filterString, searchOptions.activeMatchIndex],\n );\n\n return (\n <div className=\"tree-widget-tree-with-header\">\n <TreeHeader\n onFilterClear={searchOptions.onFilterCancel}\n onFilterStart={searchOptions.onFilterStart}\n onSelectedChanged={searchOptions.onResultSelectedChanged}\n resultCount={searchOptions.matchedResultCount}\n selectedIndex={searchOptions.activeMatchIndex}\n density={props.density}\n >\n {props.headerButtons\n ? props.headerButtons.map((btn, index) => <Fragment key={index}>{btn({ viewport, models: availableModels })}</Fragment>)\n : [\n <ShowAllButton viewport={viewport} models={availableModels} key=\"show-all-btn\" density={props.density} />,\n <HideAllButton viewport={viewport} models={availableModels} key=\"hide-all-btn\" density={props.density} />,\n <InvertButton viewport={viewport} models={availableModels} key=\"invert-all-btn\" density={props.density} />,\n <View2DButton viewport={viewport} models={availableModels} key=\"view-2d-btn\" density={props.density} />,\n <View3DButton viewport={viewport} models={availableModels} key=\"view-3d-btn\" density={props.density} />,\n ]}\n </TreeHeader>\n <div className={contentClassName}>\n <AutoSizer>\n {({ width, height }) => (\n <ModelsTree\n {...props}\n iModel={iModel}\n activeView={viewport}\n width={width}\n height={height}\n filterInfo={filterInfo}\n onFilterApplied={onFilterApplied}\n />\n )}\n </AutoSizer>\n </div>\n </div>\n );\n}\n\nfunction ShowAllButton(props: ModelsTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"showAll\")}\n onClick={() =>\n void showAllModels(\n props.models.map((model) => model.id),\n props.viewport,\n )\n }\n >\n <SvgVisibilityShow />\n </IconButton>\n );\n}\n\nfunction HideAllButton(props: ModelsTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"hideAll\")}\n onClick={() =>\n void hideAllModels(\n props.models.map((model) => model.id),\n props.viewport,\n )\n }\n >\n <SvgVisibilityHide />\n </IconButton>\n );\n}\n\nfunction InvertButton(props: ModelsTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"invert\")}\n onClick={() =>\n void invertAllModels(\n props.models.map((model) => model.id),\n props.viewport,\n )\n }\n >\n <SvgVisibilityHalf />\n </IconButton>\n );\n}\n\nfunction View2DButton(props: ModelsTreeHeaderButtonProps) {\n const models2d = useMemo(() => {\n return props.models.filter((model) => model.isPlanProjection).map((model) => model.id);\n }, [props.models]);\n\n const [is2dToggleActive, setIs2dToggleActive] = useState(false);\n\n useEffect(() => {\n setIs2dToggleActive(areAllModelsVisible(models2d, props.viewport));\n return props.viewport.onViewedModelsChanged.addListener((vp: Viewport) => setIs2dToggleActive(areAllModelsVisible(models2d, vp)));\n }, [models2d, props.viewport]);\n\n return (\n <Button\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"toggle2DViews\")}\n onClick={() => void toggleModels(models2d, is2dToggleActive, props.viewport)}\n disabled={models2d.length === 0}\n endIcon={is2dToggleActive ? <SvgVisibilityShow /> : <SvgVisibilityHide />}\n >\n {TreeWidget.translate(\"label2D\")}\n </Button>\n );\n}\n\nfunction View3DButton(props: ModelsTreeHeaderButtonProps) {\n const models3d = useMemo(() => {\n return props.models.filter((model) => !model.isPlanProjection).map((model) => model.id);\n }, [props.models]);\n\n const [is3dToggleActive, setIs3dToggleActive] = useState(false);\n\n useEffect(() => {\n setIs3dToggleActive(areAllModelsVisible(models3d, props.viewport));\n return props.viewport.onViewedModelsChanged.addListener((vp: Viewport) => setIs3dToggleActive(areAllModelsVisible(models3d, vp)));\n }, [models3d, props.viewport]);\n\n return (\n <Button\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"toggle3DViews\")}\n onClick={() => void toggleModels(models3d, is3dToggleActive, props.viewport)}\n disabled={models3d.length === 0}\n endIcon={is3dToggleActive ? <SvgVisibilityShow /> : <SvgVisibilityHide />}\n >\n {TreeWidget.translate(\"label3D\")}\n </Button>\n );\n}\n"]}
@@ -6,6 +6,7 @@
6
6
  "toggle3DViews": "Toggle 3D Views",
7
7
  "label2D": "2D",
8
8
  "label3D": "3D",
9
+ "dropdownMore": "More",
9
10
  "models": "Models",
10
11
  "categories": "Categories",
11
12
  "imodelContent": "iModel Content",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/tree-widget-react",
3
- "version": "2.0.0-dev.0",
3
+ "version": "2.0.0",
4
4
  "description": "Tree Widget React",
5
5
  "keywords": [
6
6
  "Bentley",
@@ -47,11 +47,11 @@
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@itwin/appui-abstract": "^4.0.0",
50
- "@itwin/appui-react": "^4.6.0",
51
- "@itwin/components-react": "^4.6.0",
50
+ "@itwin/appui-react": "^4.10.0",
51
+ "@itwin/components-react": "^4.10.0",
52
52
  "@itwin/core-frontend": "^4.0.0",
53
- "@itwin/core-react": "^4.6.0",
54
- "@itwin/presentation-components": "^5.0.0-dev.3",
53
+ "@itwin/core-react": "^4.10.0",
54
+ "@itwin/presentation-components": "^5.0.0",
55
55
  "react": "^17.0.0 || ^18.0.0",
56
56
  "react-dom": "^17.0.0 || ^18.0.0"
57
57
  },
@@ -59,7 +59,7 @@
59
59
  "@bentley/icons-generic": "^1.0.34",
60
60
  "@itwin/itwinui-icons-react": "^2.8.0",
61
61
  "@itwin/itwinui-illustrations-react": "^2.1.0",
62
- "@itwin/itwinui-react": "^3.4.2",
62
+ "@itwin/itwinui-react": "^3.5.0",
63
63
  "classnames": "^2.3.1",
64
64
  "i18next": "^10.2.2",
65
65
  "react-error-boundary": "^4.0.10",
@@ -67,9 +67,9 @@
67
67
  },
68
68
  "devDependencies": {
69
69
  "@itwin/appui-abstract": "^4.4.0",
70
- "@itwin/appui-react": "^4.9.0",
70
+ "@itwin/appui-react": "^4.10.0",
71
71
  "@itwin/build-tools": "^4.4.0",
72
- "@itwin/components-react": "^4.9.0",
72
+ "@itwin/components-react": "^4.10.0",
73
73
  "@itwin/core-backend": "^4.4.0",
74
74
  "@itwin/core-bentley": "^4.4.0",
75
75
  "@itwin/core-common": "^4.4.0",
@@ -79,16 +79,16 @@
79
79
  "@itwin/core-markup": "^4.4.0",
80
80
  "@itwin/core-orbitgt": "^4.4.0",
81
81
  "@itwin/core-quantity": "^4.4.0",
82
- "@itwin/core-react": "^4.9.0",
82
+ "@itwin/core-react": "^4.10.0",
83
83
  "@itwin/core-telemetry": "^4.4.0",
84
84
  "@itwin/ecschema-metadata": "^4.4.0",
85
85
  "@itwin/eslint-plugin": "^4.0.0-dev.38",
86
- "@itwin/imodel-components-react": "^4.9.0",
86
+ "@itwin/imodel-components-react": "^4.10.0",
87
87
  "@itwin/presentation-backend": "^4.4.0",
88
88
  "@itwin/presentation-common": "^4.4.0",
89
- "@itwin/presentation-components": "5.0.0-dev.3",
89
+ "@itwin/presentation-components": "^5.0.0",
90
90
  "@itwin/presentation-frontend": "^4.4.0",
91
- "@itwin/presentation-testing": "5.0.0-dev.3",
91
+ "@itwin/presentation-testing": "^5.0.0",
92
92
  "@itwin/webgl-compatibility": "^4.4.0",
93
93
  "@playwright/test": "^1.41.2",
94
94
  "@testing-library/dom": "^9.3.3",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=TreeWidget.test.d.ts.map
@@ -1,104 +0,0 @@
1
- "use strict";
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
- * See LICENSE.md in the project root for license terms and full copyright notice.
5
- *--------------------------------------------------------------------------------------------*/
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- const assert_1 = __importDefault(require("assert"));
11
- const test_1 = require("@playwright/test");
12
- const utils_1 = require("./utils");
13
- let treeWidget;
14
- test_1.test.beforeEach(async ({ page, baseURL }) => {
15
- (0, assert_1.default)(baseURL);
16
- await page.goto(baseURL, { waitUntil: "networkidle" });
17
- await page.evaluate(async () => document.fonts.ready);
18
- // expand panel size to ~300px
19
- await (0, utils_1.expandStagePanel)(page, "right", 100);
20
- treeWidget = (0, utils_1.locateWidget)(page, "tree");
21
- await treeWidget.waitFor();
22
- });
23
- test_1.test.describe("should match image snapshot", () => {
24
- (0, test_1.test)("initial tree", async ({ page }) => {
25
- // wait for element to be visible in the tree
26
- await (0, utils_1.locateNode)(treeWidget, "ProcessPhysicalModel").getByRole("checkbox", { name: "Visible", exact: true }).waitFor();
27
- await (0, utils_1.takeScreenshot)(page, treeWidget);
28
- });
29
- (0, test_1.test)("expanded tree node", async ({ page }) => {
30
- const node = (0, utils_1.locateNode)(treeWidget, "ProcessPhysicalModel");
31
- await node.getByTestId("tree-node-expansion-toggle").click();
32
- // wait for node at the bottom to be visible/loaded
33
- await (0, utils_1.locateNode)(treeWidget, "Tag-Category").waitFor();
34
- await (0, utils_1.takeScreenshot)(page, treeWidget);
35
- });
36
- (0, test_1.test)("fully expanded tree node", async ({ page }) => {
37
- const physicalModelNode = (0, utils_1.locateNode)(treeWidget, "ProcessPhysicalModel");
38
- await physicalModelNode.getByTestId("tree-node-expansion-toggle").click();
39
- // wait for node at the bottom to be visible/loaded
40
- await (0, utils_1.locateNode)(treeWidget, "Tag-Category").waitFor();
41
- const pipeSupportNode = (0, utils_1.locateNode)(treeWidget, "PipeSupport");
42
- await pipeSupportNode.getByTestId("tree-node-expansion-toggle").click();
43
- // wait for node at the bottom to be visible/loaded
44
- await (0, utils_1.locateNode)(treeWidget, "Hanger Rod [4-2UH]").waitFor();
45
- await (0, utils_1.takeScreenshot)(page, treeWidget);
46
- });
47
- // make sure to open the filter dialog before calling this.
48
- async function selectPropertyInDialog(page, propertyText) {
49
- const filterBuilder = page.locator(".presentation-property-filter-builder");
50
- await filterBuilder.getByPlaceholder("Choose property").click();
51
- // ensure that options are loaded
52
- await page.getByRole("menuitem", { name: "Model" }).waitFor();
53
- await page.getByRole("menuitem", { name: propertyText }).click();
54
- }
55
- (0, test_1.test)("node with active filtering - information message", async ({ page }) => {
56
- const physicalModelNode = (0, utils_1.locateNode)(treeWidget, "ProcessPhysicalModel");
57
- // hover the node for the button to appear
58
- await physicalModelNode.hover();
59
- await physicalModelNode.getByTitle("Apply filter").click();
60
- await (0, utils_1.locateInstanceFilter)(page).waitFor();
61
- await selectPropertyInDialog(page, "Is Private");
62
- await page.getByRole("button", { name: "Apply" }).click();
63
- // hover the node for the button to appear
64
- await physicalModelNode.hover();
65
- await treeWidget.getByTitle("Clear active filter").waitFor();
66
- await (0, utils_1.takeScreenshot)(page, treeWidget);
67
- });
68
- (0, test_1.test)("node with active filtering - filtered nodes", async ({ page }) => {
69
- const physicalModelNode = (0, utils_1.locateNode)(treeWidget, "ProcessPhysicalModel");
70
- // hover the node for the button to appear
71
- await physicalModelNode.hover();
72
- await physicalModelNode.getByTitle("Apply filter").click();
73
- await (0, utils_1.locateInstanceFilter)(page).waitFor();
74
- await selectPropertyInDialog(page, "Is Private");
75
- await page
76
- .getByRole("combobox")
77
- .filter({ has: page.getByText("Is true") })
78
- .click();
79
- await page.getByRole("option", { name: "Is true" }).waitFor();
80
- await page.getByRole("option", { name: "Is false" }).click();
81
- await page.getByRole("button", { name: "Apply" }).click();
82
- // hover the node for buttons to appear
83
- await physicalModelNode.hover();
84
- await treeWidget.getByTitle("Clear active filter").waitFor();
85
- // ensure the last node is loaded before taking a screenshot to avoid flakiness
86
- await (0, utils_1.locateNode)(treeWidget, "SWS-1-SWS-0311-EX-OPM").waitFor();
87
- await (0, utils_1.takeScreenshot)(page, treeWidget);
88
- });
89
- (0, test_1.test)("selected node", async ({ page }) => {
90
- const node = (0, utils_1.locateNode)(treeWidget, "BayTown");
91
- await node.click();
92
- // wait for node to become selected
93
- await (0, test_1.expect)(node).toHaveClass(/is-selected/);
94
- await (0, utils_1.takeScreenshot)(page, treeWidget);
95
- });
96
- (0, test_1.test)("search", async ({ page }) => {
97
- await treeWidget.getByText("BayTown").waitFor();
98
- await treeWidget.getByTitle("Search for something").click();
99
- await treeWidget.getByPlaceholder("Search...").fill("Model");
100
- await treeWidget.locator(".components-activehighlight").waitFor();
101
- await (0, utils_1.takeScreenshot)(page, treeWidget);
102
- });
103
- });
104
- //# sourceMappingURL=TreeWidget.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TreeWidget.test.js","sourceRoot":"","sources":["../../../src/e2e-tests/TreeWidget.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport type { Locator, Page } from \"@playwright/test\";\nimport assert from \"assert\";\nimport { expect, test } from \"@playwright/test\";\nimport { expandStagePanel, locateInstanceFilter, locateNode, locateWidget, takeScreenshot } from \"./utils\";\n\nlet treeWidget: Locator;\ntest.beforeEach(async ({ page, baseURL }) => {\n assert(baseURL);\n await page.goto(baseURL, { waitUntil: \"networkidle\" });\n await page.evaluate(async () => document.fonts.ready);\n // expand panel size to ~300px\n await expandStagePanel(page, \"right\", 100);\n treeWidget = locateWidget(page, \"tree\");\n await treeWidget.waitFor();\n});\n\ntest.describe(\"should match image snapshot\", () => {\n test(\"initial tree\", async ({ page }) => {\n // wait for element to be visible in the tree\n await locateNode(treeWidget, \"ProcessPhysicalModel\").getByRole(\"checkbox\", { name: \"Visible\", exact: true }).waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"expanded tree node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"ProcessPhysicalModel\");\n await node.getByTestId(\"tree-node-expansion-toggle\").click();\n\n // wait for node at the bottom to be visible/loaded\n await locateNode(treeWidget, \"Tag-Category\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"fully expanded tree node\", async ({ page }) => {\n const physicalModelNode = locateNode(treeWidget, \"ProcessPhysicalModel\");\n await physicalModelNode.getByTestId(\"tree-node-expansion-toggle\").click();\n\n // wait for node at the bottom to be visible/loaded\n await locateNode(treeWidget, \"Tag-Category\").waitFor();\n const pipeSupportNode = locateNode(treeWidget, \"PipeSupport\");\n await pipeSupportNode.getByTestId(\"tree-node-expansion-toggle\").click();\n\n // wait for node at the bottom to be visible/loaded\n await locateNode(treeWidget, \"Hanger Rod [4-2UH]\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n // make sure to open the filter dialog before calling this.\n async function selectPropertyInDialog(page: Page, propertyText: string) {\n const filterBuilder = page.locator(\".presentation-property-filter-builder\");\n\n await filterBuilder.getByPlaceholder(\"Choose property\").click();\n\n // ensure that options are loaded\n await page.getByRole(\"menuitem\", { name: \"Model\" }).waitFor();\n await page.getByRole(\"menuitem\", { name: propertyText }).click();\n }\n\n test(\"node with active filtering - information message\", async ({ page }) => {\n const physicalModelNode = locateNode(treeWidget, \"ProcessPhysicalModel\");\n\n // hover the node for the button to appear\n await physicalModelNode.hover();\n await physicalModelNode.getByTitle(\"Apply filter\").click();\n\n await locateInstanceFilter(page).waitFor();\n await selectPropertyInDialog(page, \"Is Private\");\n\n await page.getByRole(\"button\", { name: \"Apply\" }).click();\n\n // hover the node for the button to appear\n await physicalModelNode.hover();\n await treeWidget.getByTitle(\"Clear active filter\").waitFor();\n\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"node with active filtering - filtered nodes\", async ({ page }) => {\n const physicalModelNode = locateNode(treeWidget, \"ProcessPhysicalModel\");\n\n // hover the node for the button to appear\n await physicalModelNode.hover();\n await physicalModelNode.getByTitle(\"Apply filter\").click();\n\n await locateInstanceFilter(page).waitFor();\n await selectPropertyInDialog(page, \"Is Private\");\n\n await page\n .getByRole(\"combobox\")\n .filter({ has: page.getByText(\"Is true\") })\n .click();\n await page.getByRole(\"option\", { name: \"Is true\" }).waitFor();\n await page.getByRole(\"option\", { name: \"Is false\" }).click();\n\n await page.getByRole(\"button\", { name: \"Apply\" }).click();\n\n // hover the node for buttons to appear\n await physicalModelNode.hover();\n await treeWidget.getByTitle(\"Clear active filter\").waitFor();\n\n // ensure the last node is loaded before taking a screenshot to avoid flakiness\n await locateNode(treeWidget, \"SWS-1-SWS-0311-EX-OPM\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"selected node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"BayTown\");\n await node.click();\n\n // wait for node to become selected\n await expect(node).toHaveClass(/is-selected/);\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"search\", async ({ page }) => {\n await treeWidget.getByText(\"BayTown\").waitFor();\n await treeWidget.getByTitle(\"Search for something\").click();\n await treeWidget.getByPlaceholder(\"Search...\").fill(\"Model\");\n await treeWidget.locator(\".components-activehighlight\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n});\n"]}
@@ -1,10 +0,0 @@
1
- import type { Locator, Page } from "@playwright/test";
2
- export declare const locateNode: (tree: Page | Locator, name: string) => Locator;
3
- export declare const locateWidget: (page: Page | Locator, widgetName: string) => Locator;
4
- export declare const locateInstanceFilter: (page: Page | Locator) => Locator;
5
- type PanelSide = "left" | "right" | "top" | "bottom";
6
- export declare const locatePanel: (page: Page, side: PanelSide) => Locator;
7
- export declare const expandStagePanel: (page: Page, side: PanelSide, px: number) => Promise<void>;
8
- export declare function takeScreenshot(page: Page, component: Locator): Promise<void>;
9
- export {};
10
- //# sourceMappingURL=utils.d.ts.map
@@ -1,50 +0,0 @@
1
- "use strict";
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
- * See LICENSE.md in the project root for license terms and full copyright notice.
5
- *--------------------------------------------------------------------------------------------*/
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.takeScreenshot = exports.expandStagePanel = exports.locatePanel = exports.locateInstanceFilter = exports.locateWidget = exports.locateNode = void 0;
11
- const assert_1 = __importDefault(require("assert"));
12
- const test_1 = require("@playwright/test");
13
- const locateNode = (tree, name) => tree.getByRole("treeitem", { name });
14
- exports.locateNode = locateNode;
15
- const locateWidget = (page, widgetName) => page.locator(`.${widgetName}-widget`);
16
- exports.locateWidget = locateWidget;
17
- const locateInstanceFilter = (page) => page.locator(`.presentation-instance-filter`);
18
- exports.locateInstanceFilter = locateInstanceFilter;
19
- const locatePanel = (page, side) => page.locator(`.nz-widgetPanels-panel.nz-${side}`);
20
- exports.locatePanel = locatePanel;
21
- const expandStagePanel = async (page, side, px) => {
22
- const widgetPanel = (0, exports.locatePanel)(page, side);
23
- const handlePos = await widgetPanel.locator(".nz-grip-container").locator(".nz-handle").boundingBox();
24
- (0, assert_1.default)(handlePos);
25
- await page.mouse.move(handlePos.x, handlePos.y);
26
- await page.mouse.down();
27
- switch (side) {
28
- case "left":
29
- await page.mouse.move(handlePos.x + px, handlePos.y);
30
- break;
31
- case "right":
32
- await page.mouse.move(handlePos.x - px, handlePos.y);
33
- break;
34
- case "top":
35
- await page.mouse.move(handlePos.x, handlePos.y - px);
36
- break;
37
- case "bottom":
38
- await page.mouse.move(handlePos.x, handlePos.y + px);
39
- break;
40
- }
41
- await page.mouse.up();
42
- };
43
- exports.expandStagePanel = expandStagePanel;
44
- async function takeScreenshot(page, component) {
45
- const boundingBox = await component.boundingBox();
46
- (0, assert_1.default)(boundingBox);
47
- await (0, test_1.expect)(page).toHaveScreenshot({ clip: boundingBox });
48
- }
49
- exports.takeScreenshot = takeScreenshot;
50
- //# sourceMappingURL=utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/e2e-tests/utils.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;;;;AAEhG,oDAA4B;AAC5B,2CAA0C;AAInC,MAAM,UAAU,GAAG,CAAC,IAAoB,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AAA1F,QAAA,UAAU,cAAgF;AAChG,MAAM,YAAY,GAAG,CAAC,IAAoB,EAAE,UAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,SAAS,CAAC,CAAC;AAAnG,QAAA,YAAY,gBAAuF;AACzG,MAAM,oBAAoB,GAAG,CAAC,IAAoB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;AAA/F,QAAA,oBAAoB,wBAA2E;AAGrG,MAAM,WAAW,GAAG,CAAC,IAAU,EAAE,IAAe,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;AAAjG,QAAA,WAAW,eAAsF;AAEvG,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAU,EAAE,IAAe,EAAE,EAAU,EAAE,EAAE;IAChF,MAAM,WAAW,GAAG,IAAA,mBAAW,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;IACtG,IAAA,gBAAM,EAAC,SAAS,CAAC,CAAC;IAElB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAExB,QAAQ,IAAI,EAAE;QACZ,KAAK,MAAM;YACT,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,OAAO;YACV,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,KAAK;YACR,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;KACT;IACD,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AACxB,CAAC,CAAC;AAvBW,QAAA,gBAAgB,oBAuB3B;AAEK,KAAK,UAAU,cAAc,CAAC,IAAU,EAAE,SAAkB;IACjE,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;IAClD,IAAA,gBAAM,EAAC,WAAW,CAAC,CAAC;IACpB,MAAM,IAAA,aAAM,EAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC;AAJD,wCAIC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport assert from \"assert\";\nimport { expect } from \"@playwright/test\";\n\nimport type { Locator, Page } from \"@playwright/test\";\n\nexport const locateNode = (tree: Page | Locator, name: string) => tree.getByRole(\"treeitem\", { name });\nexport const locateWidget = (page: Page | Locator, widgetName: string) => page.locator(`.${widgetName}-widget`);\nexport const locateInstanceFilter = (page: Page | Locator) => page.locator(`.presentation-instance-filter`);\n\ntype PanelSide = \"left\" | \"right\" | \"top\" | \"bottom\";\nexport const locatePanel = (page: Page, side: PanelSide) => page.locator(`.nz-widgetPanels-panel.nz-${side}`);\n\nexport const expandStagePanel = async (page: Page, side: PanelSide, px: number) => {\n const widgetPanel = locatePanel(page, side);\n const handlePos = await widgetPanel.locator(\".nz-grip-container\").locator(\".nz-handle\").boundingBox();\n assert(handlePos);\n\n await page.mouse.move(handlePos.x, handlePos.y);\n await page.mouse.down();\n\n switch (side) {\n case \"left\":\n await page.mouse.move(handlePos.x + px, handlePos.y);\n break;\n case \"right\":\n await page.mouse.move(handlePos.x - px, handlePos.y);\n break;\n case \"top\":\n await page.mouse.move(handlePos.x, handlePos.y - px);\n break;\n case \"bottom\":\n await page.mouse.move(handlePos.x, handlePos.y + px);\n break;\n }\n await page.mouse.up();\n};\n\nexport async function takeScreenshot(page: Page, component: Locator) {\n const boundingBox = await component.boundingBox();\n assert(boundingBox);\n await expect(page).toHaveScreenshot({ clip: boundingBox });\n}\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=TreeWidget.test.d.ts.map
@@ -1,99 +0,0 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
- * See LICENSE.md in the project root for license terms and full copyright notice.
4
- *--------------------------------------------------------------------------------------------*/
5
- import assert from "assert";
6
- import { expect, test } from "@playwright/test";
7
- import { expandStagePanel, locateInstanceFilter, locateNode, locateWidget, takeScreenshot } from "./utils";
8
- let treeWidget;
9
- test.beforeEach(async ({ page, baseURL }) => {
10
- assert(baseURL);
11
- await page.goto(baseURL, { waitUntil: "networkidle" });
12
- await page.evaluate(async () => document.fonts.ready);
13
- // expand panel size to ~300px
14
- await expandStagePanel(page, "right", 100);
15
- treeWidget = locateWidget(page, "tree");
16
- await treeWidget.waitFor();
17
- });
18
- test.describe("should match image snapshot", () => {
19
- test("initial tree", async ({ page }) => {
20
- // wait for element to be visible in the tree
21
- await locateNode(treeWidget, "ProcessPhysicalModel").getByRole("checkbox", { name: "Visible", exact: true }).waitFor();
22
- await takeScreenshot(page, treeWidget);
23
- });
24
- test("expanded tree node", async ({ page }) => {
25
- const node = locateNode(treeWidget, "ProcessPhysicalModel");
26
- await node.getByTestId("tree-node-expansion-toggle").click();
27
- // wait for node at the bottom to be visible/loaded
28
- await locateNode(treeWidget, "Tag-Category").waitFor();
29
- await takeScreenshot(page, treeWidget);
30
- });
31
- test("fully expanded tree node", async ({ page }) => {
32
- const physicalModelNode = locateNode(treeWidget, "ProcessPhysicalModel");
33
- await physicalModelNode.getByTestId("tree-node-expansion-toggle").click();
34
- // wait for node at the bottom to be visible/loaded
35
- await locateNode(treeWidget, "Tag-Category").waitFor();
36
- const pipeSupportNode = locateNode(treeWidget, "PipeSupport");
37
- await pipeSupportNode.getByTestId("tree-node-expansion-toggle").click();
38
- // wait for node at the bottom to be visible/loaded
39
- await locateNode(treeWidget, "Hanger Rod [4-2UH]").waitFor();
40
- await takeScreenshot(page, treeWidget);
41
- });
42
- // make sure to open the filter dialog before calling this.
43
- async function selectPropertyInDialog(page, propertyText) {
44
- const filterBuilder = page.locator(".presentation-property-filter-builder");
45
- await filterBuilder.getByPlaceholder("Choose property").click();
46
- // ensure that options are loaded
47
- await page.getByRole("menuitem", { name: "Model" }).waitFor();
48
- await page.getByRole("menuitem", { name: propertyText }).click();
49
- }
50
- test("node with active filtering - information message", async ({ page }) => {
51
- const physicalModelNode = locateNode(treeWidget, "ProcessPhysicalModel");
52
- // hover the node for the button to appear
53
- await physicalModelNode.hover();
54
- await physicalModelNode.getByTitle("Apply filter").click();
55
- await locateInstanceFilter(page).waitFor();
56
- await selectPropertyInDialog(page, "Is Private");
57
- await page.getByRole("button", { name: "Apply" }).click();
58
- // hover the node for the button to appear
59
- await physicalModelNode.hover();
60
- await treeWidget.getByTitle("Clear active filter").waitFor();
61
- await takeScreenshot(page, treeWidget);
62
- });
63
- test("node with active filtering - filtered nodes", async ({ page }) => {
64
- const physicalModelNode = locateNode(treeWidget, "ProcessPhysicalModel");
65
- // hover the node for the button to appear
66
- await physicalModelNode.hover();
67
- await physicalModelNode.getByTitle("Apply filter").click();
68
- await locateInstanceFilter(page).waitFor();
69
- await selectPropertyInDialog(page, "Is Private");
70
- await page
71
- .getByRole("combobox")
72
- .filter({ has: page.getByText("Is true") })
73
- .click();
74
- await page.getByRole("option", { name: "Is true" }).waitFor();
75
- await page.getByRole("option", { name: "Is false" }).click();
76
- await page.getByRole("button", { name: "Apply" }).click();
77
- // hover the node for buttons to appear
78
- await physicalModelNode.hover();
79
- await treeWidget.getByTitle("Clear active filter").waitFor();
80
- // ensure the last node is loaded before taking a screenshot to avoid flakiness
81
- await locateNode(treeWidget, "SWS-1-SWS-0311-EX-OPM").waitFor();
82
- await takeScreenshot(page, treeWidget);
83
- });
84
- test("selected node", async ({ page }) => {
85
- const node = locateNode(treeWidget, "BayTown");
86
- await node.click();
87
- // wait for node to become selected
88
- await expect(node).toHaveClass(/is-selected/);
89
- await takeScreenshot(page, treeWidget);
90
- });
91
- test("search", async ({ page }) => {
92
- await treeWidget.getByText("BayTown").waitFor();
93
- await treeWidget.getByTitle("Search for something").click();
94
- await treeWidget.getByPlaceholder("Search...").fill("Model");
95
- await treeWidget.locator(".components-activehighlight").waitFor();
96
- await takeScreenshot(page, treeWidget);
97
- });
98
- });
99
- //# sourceMappingURL=TreeWidget.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TreeWidget.test.js","sourceRoot":"","sources":["../../../src/e2e-tests/TreeWidget.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport type { Locator, Page } from \"@playwright/test\";\nimport assert from \"assert\";\nimport { expect, test } from \"@playwright/test\";\nimport { expandStagePanel, locateInstanceFilter, locateNode, locateWidget, takeScreenshot } from \"./utils\";\n\nlet treeWidget: Locator;\ntest.beforeEach(async ({ page, baseURL }) => {\n assert(baseURL);\n await page.goto(baseURL, { waitUntil: \"networkidle\" });\n await page.evaluate(async () => document.fonts.ready);\n // expand panel size to ~300px\n await expandStagePanel(page, \"right\", 100);\n treeWidget = locateWidget(page, \"tree\");\n await treeWidget.waitFor();\n});\n\ntest.describe(\"should match image snapshot\", () => {\n test(\"initial tree\", async ({ page }) => {\n // wait for element to be visible in the tree\n await locateNode(treeWidget, \"ProcessPhysicalModel\").getByRole(\"checkbox\", { name: \"Visible\", exact: true }).waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"expanded tree node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"ProcessPhysicalModel\");\n await node.getByTestId(\"tree-node-expansion-toggle\").click();\n\n // wait for node at the bottom to be visible/loaded\n await locateNode(treeWidget, \"Tag-Category\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"fully expanded tree node\", async ({ page }) => {\n const physicalModelNode = locateNode(treeWidget, \"ProcessPhysicalModel\");\n await physicalModelNode.getByTestId(\"tree-node-expansion-toggle\").click();\n\n // wait for node at the bottom to be visible/loaded\n await locateNode(treeWidget, \"Tag-Category\").waitFor();\n const pipeSupportNode = locateNode(treeWidget, \"PipeSupport\");\n await pipeSupportNode.getByTestId(\"tree-node-expansion-toggle\").click();\n\n // wait for node at the bottom to be visible/loaded\n await locateNode(treeWidget, \"Hanger Rod [4-2UH]\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n // make sure to open the filter dialog before calling this.\n async function selectPropertyInDialog(page: Page, propertyText: string) {\n const filterBuilder = page.locator(\".presentation-property-filter-builder\");\n\n await filterBuilder.getByPlaceholder(\"Choose property\").click();\n\n // ensure that options are loaded\n await page.getByRole(\"menuitem\", { name: \"Model\" }).waitFor();\n await page.getByRole(\"menuitem\", { name: propertyText }).click();\n }\n\n test(\"node with active filtering - information message\", async ({ page }) => {\n const physicalModelNode = locateNode(treeWidget, \"ProcessPhysicalModel\");\n\n // hover the node for the button to appear\n await physicalModelNode.hover();\n await physicalModelNode.getByTitle(\"Apply filter\").click();\n\n await locateInstanceFilter(page).waitFor();\n await selectPropertyInDialog(page, \"Is Private\");\n\n await page.getByRole(\"button\", { name: \"Apply\" }).click();\n\n // hover the node for the button to appear\n await physicalModelNode.hover();\n await treeWidget.getByTitle(\"Clear active filter\").waitFor();\n\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"node with active filtering - filtered nodes\", async ({ page }) => {\n const physicalModelNode = locateNode(treeWidget, \"ProcessPhysicalModel\");\n\n // hover the node for the button to appear\n await physicalModelNode.hover();\n await physicalModelNode.getByTitle(\"Apply filter\").click();\n\n await locateInstanceFilter(page).waitFor();\n await selectPropertyInDialog(page, \"Is Private\");\n\n await page\n .getByRole(\"combobox\")\n .filter({ has: page.getByText(\"Is true\") })\n .click();\n await page.getByRole(\"option\", { name: \"Is true\" }).waitFor();\n await page.getByRole(\"option\", { name: \"Is false\" }).click();\n\n await page.getByRole(\"button\", { name: \"Apply\" }).click();\n\n // hover the node for buttons to appear\n await physicalModelNode.hover();\n await treeWidget.getByTitle(\"Clear active filter\").waitFor();\n\n // ensure the last node is loaded before taking a screenshot to avoid flakiness\n await locateNode(treeWidget, \"SWS-1-SWS-0311-EX-OPM\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"selected node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"BayTown\");\n await node.click();\n\n // wait for node to become selected\n await expect(node).toHaveClass(/is-selected/);\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"search\", async ({ page }) => {\n await treeWidget.getByText(\"BayTown\").waitFor();\n await treeWidget.getByTitle(\"Search for something\").click();\n await treeWidget.getByPlaceholder(\"Search...\").fill(\"Model\");\n await treeWidget.locator(\".components-activehighlight\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n});\n"]}
@@ -1,10 +0,0 @@
1
- import type { Locator, Page } from "@playwright/test";
2
- export declare const locateNode: (tree: Page | Locator, name: string) => Locator;
3
- export declare const locateWidget: (page: Page | Locator, widgetName: string) => Locator;
4
- export declare const locateInstanceFilter: (page: Page | Locator) => Locator;
5
- type PanelSide = "left" | "right" | "top" | "bottom";
6
- export declare const locatePanel: (page: Page, side: PanelSide) => Locator;
7
- export declare const expandStagePanel: (page: Page, side: PanelSide, px: number) => Promise<void>;
8
- export declare function takeScreenshot(page: Page, component: Locator): Promise<void>;
9
- export {};
10
- //# sourceMappingURL=utils.d.ts.map
@@ -1,38 +0,0 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
- * See LICENSE.md in the project root for license terms and full copyright notice.
4
- *--------------------------------------------------------------------------------------------*/
5
- import assert from "assert";
6
- import { expect } from "@playwright/test";
7
- export const locateNode = (tree, name) => tree.getByRole("treeitem", { name });
8
- export const locateWidget = (page, widgetName) => page.locator(`.${widgetName}-widget`);
9
- export const locateInstanceFilter = (page) => page.locator(`.presentation-instance-filter`);
10
- export const locatePanel = (page, side) => page.locator(`.nz-widgetPanels-panel.nz-${side}`);
11
- export const expandStagePanel = async (page, side, px) => {
12
- const widgetPanel = locatePanel(page, side);
13
- const handlePos = await widgetPanel.locator(".nz-grip-container").locator(".nz-handle").boundingBox();
14
- assert(handlePos);
15
- await page.mouse.move(handlePos.x, handlePos.y);
16
- await page.mouse.down();
17
- switch (side) {
18
- case "left":
19
- await page.mouse.move(handlePos.x + px, handlePos.y);
20
- break;
21
- case "right":
22
- await page.mouse.move(handlePos.x - px, handlePos.y);
23
- break;
24
- case "top":
25
- await page.mouse.move(handlePos.x, handlePos.y - px);
26
- break;
27
- case "bottom":
28
- await page.mouse.move(handlePos.x, handlePos.y + px);
29
- break;
30
- }
31
- await page.mouse.up();
32
- };
33
- export async function takeScreenshot(page, component) {
34
- const boundingBox = await component.boundingBox();
35
- assert(boundingBox);
36
- await expect(page).toHaveScreenshot({ clip: boundingBox });
37
- }
38
- //# sourceMappingURL=utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/e2e-tests/utils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI1C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAoB,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AACvG,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAoB,EAAE,UAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,SAAS,CAAC,CAAC;AAChH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,IAAoB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;AAG5G,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAU,EAAE,IAAe,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;AAE9G,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAU,EAAE,IAAe,EAAE,EAAU,EAAE,EAAE;IAChF,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;IACtG,MAAM,CAAC,SAAS,CAAC,CAAC;IAElB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAExB,QAAQ,IAAI,EAAE;QACZ,KAAK,MAAM;YACT,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,OAAO;YACV,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,KAAK;YACR,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;KACT;IACD,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AACxB,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAU,EAAE,SAAkB;IACjE,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;IAClD,MAAM,CAAC,WAAW,CAAC,CAAC;IACpB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport assert from \"assert\";\nimport { expect } from \"@playwright/test\";\n\nimport type { Locator, Page } from \"@playwright/test\";\n\nexport const locateNode = (tree: Page | Locator, name: string) => tree.getByRole(\"treeitem\", { name });\nexport const locateWidget = (page: Page | Locator, widgetName: string) => page.locator(`.${widgetName}-widget`);\nexport const locateInstanceFilter = (page: Page | Locator) => page.locator(`.presentation-instance-filter`);\n\ntype PanelSide = \"left\" | \"right\" | \"top\" | \"bottom\";\nexport const locatePanel = (page: Page, side: PanelSide) => page.locator(`.nz-widgetPanels-panel.nz-${side}`);\n\nexport const expandStagePanel = async (page: Page, side: PanelSide, px: number) => {\n const widgetPanel = locatePanel(page, side);\n const handlePos = await widgetPanel.locator(\".nz-grip-container\").locator(\".nz-handle\").boundingBox();\n assert(handlePos);\n\n await page.mouse.move(handlePos.x, handlePos.y);\n await page.mouse.down();\n\n switch (side) {\n case \"left\":\n await page.mouse.move(handlePos.x + px, handlePos.y);\n break;\n case \"right\":\n await page.mouse.move(handlePos.x - px, handlePos.y);\n break;\n case \"top\":\n await page.mouse.move(handlePos.x, handlePos.y - px);\n break;\n case \"bottom\":\n await page.mouse.move(handlePos.x, handlePos.y + px);\n break;\n }\n await page.mouse.up();\n};\n\nexport async function takeScreenshot(page: Page, component: Locator) {\n const boundingBox = await component.boundingBox();\n assert(boundingBox);\n await expect(page).toHaveScreenshot({ clip: boundingBox });\n}\n"]}