@tldiagram/core-ui 1.95.1 → 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 (100) hide show
  1. package/dist/api/client.d.ts +184 -3
  2. package/dist/components/ConnectorPanel.d.ts +5 -1
  3. package/dist/components/CrossBranchControls.d.ts +4 -3
  4. package/dist/components/ElementNode.d.ts +5 -0
  5. package/dist/components/ElementPanel.d.ts +6 -1
  6. package/dist/components/LayoutSection.d.ts +2 -1
  7. package/dist/components/MergeDialog.d.ts +16 -0
  8. package/dist/components/NodeContainer.d.ts +2 -0
  9. package/dist/components/ProxyConnectorPanel.d.ts +4 -1
  10. package/dist/components/ViewExplorer/index.d.ts +1 -1
  11. package/dist/components/ViewFloatingMenu-vscode.d.ts +5 -0
  12. package/dist/components/ViewFloatingMenu.d.ts +8 -1
  13. package/dist/components/ViewGridNode.d.ts +3 -0
  14. package/dist/components/ViewPanel.d.ts +2 -1
  15. package/dist/components/WorkspacePanel.d.ts +2 -0
  16. package/dist/components/ZUI/ZUICanvas.d.ts +4 -0
  17. package/dist/components/ZUI/focus.d.ts +32 -0
  18. package/dist/components/ZUI/focus.test.d.ts +1 -0
  19. package/dist/components/ZUI/layout.d.ts +2 -2
  20. package/dist/components/ZUI/proxy.d.ts +20 -4
  21. package/dist/components/ZUI/renderer.d.ts +35 -1
  22. package/dist/components/ZUI/types.d.ts +6 -0
  23. package/dist/components/ZUI/useZUIInteraction.d.ts +1 -0
  24. package/dist/context/WorkspaceVersionContext.d.ts +49 -0
  25. package/dist/crossBranch/resolve.d.ts +39 -2
  26. package/dist/crossBranch/resolve.test.d.ts +1 -0
  27. package/dist/crossBranch/settings.d.ts +6 -1
  28. package/dist/crossBranch/types.d.ts +8 -0
  29. package/dist/hooks/useElementSearch.d.ts +8 -0
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +16529 -14030
  32. package/dist/pages/InfiniteZoom.d.ts +1 -0
  33. package/dist/pages/ViewEditor/hooks/useCanvasInteractions.d.ts +6 -1
  34. package/dist/pages/ViewEditor/hooks/useViewContextNeighbours.d.ts +2 -0
  35. package/dist/pages/ViewEditor/hooks/useViewData.d.ts +4 -2
  36. package/dist/pages/ViewEditor/hooks/useViewEditHistory.d.ts +13 -0
  37. package/dist/pages/viewsJumpSearch.d.ts +22 -0
  38. package/dist/pages/viewsJumpSearch.test.d.ts +1 -0
  39. package/dist/store/useStore.d.ts +3 -0
  40. package/dist/types/index.d.ts +9 -0
  41. package/dist/utils/elementIcon.d.ts +2 -0
  42. package/dist/utils/elementIcon.test.d.ts +1 -0
  43. package/dist/utils/sourceEditor.d.ts +7 -0
  44. package/dist/utils/watchDiffSummary.d.ts +34 -0
  45. package/package.json +2 -2
  46. package/src/App.tsx +12 -8
  47. package/src/api/client.ts +488 -26
  48. package/src/components/CodePreviewPanel.tsx +90 -16
  49. package/src/components/ConnectorPanel.tsx +34 -3
  50. package/src/components/ContextNeighborElement.tsx +2 -5
  51. package/src/components/CrossBranchControls.tsx +46 -17
  52. package/src/components/ElementNode.tsx +98 -47
  53. package/src/components/ElementPanel.tsx +62 -25
  54. package/src/components/InlineElementAdder.tsx +8 -3
  55. package/src/components/LayoutSection.tsx +4 -1
  56. package/src/components/MergeDialog.tsx +269 -0
  57. package/src/components/NodeContainer.tsx +55 -17
  58. package/src/components/ProxyConnectorPanel.tsx +58 -16
  59. package/src/components/ViewBezierConnector.tsx +116 -21
  60. package/src/components/ViewExplorer/index.tsx +1 -1
  61. package/src/components/ViewFloatingMenu-vscode.tsx +5 -0
  62. package/src/components/ViewFloatingMenu.tsx +110 -1
  63. package/src/components/ViewGridNode.tsx +59 -8
  64. package/src/components/ViewPanel.tsx +3 -2
  65. package/src/components/WorkspacePanel.tsx +938 -0
  66. package/src/components/ZUI/ZUICanvas.tsx +216 -122
  67. package/src/components/ZUI/focus.test.ts +534 -0
  68. package/src/components/ZUI/focus.ts +293 -0
  69. package/src/components/ZUI/layout.ts +7 -11
  70. package/src/components/ZUI/proxy.ts +470 -114
  71. package/src/components/ZUI/renderer.ts +510 -134
  72. package/src/components/ZUI/types.ts +6 -0
  73. package/src/components/ZUI/useZUIInteraction.ts +66 -29
  74. package/src/context/WorkspaceVersionContext.tsx +126 -0
  75. package/src/crossBranch/resolve.test.ts +342 -0
  76. package/src/crossBranch/resolve.ts +368 -68
  77. package/src/crossBranch/settings.ts +49 -3
  78. package/src/crossBranch/types.ts +9 -0
  79. package/src/hooks/useElementSearch.ts +45 -0
  80. package/src/index.css +11 -0
  81. package/src/index.ts +7 -0
  82. package/src/pages/AppearanceSettings.tsx +24 -1
  83. package/src/pages/Dependencies.tsx +231 -65
  84. package/src/pages/InfiniteZoom.tsx +41 -19
  85. package/src/pages/Settings.tsx +1 -1
  86. package/src/pages/ViewEditor/hooks/useCanvasInteractions.ts +103 -24
  87. package/src/pages/ViewEditor/hooks/useViewContextNeighbours.ts +102 -6
  88. package/src/pages/ViewEditor/hooks/useViewData.ts +42 -26
  89. package/src/pages/ViewEditor/hooks/useViewEditHistory.ts +62 -0
  90. package/src/pages/ViewEditor/index.tsx +549 -59
  91. package/src/pages/Views.tsx +112 -41
  92. package/src/pages/ViewsGrid.tsx +332 -113
  93. package/src/pages/viewsJumpSearch.test.ts +193 -0
  94. package/src/pages/viewsJumpSearch.ts +111 -0
  95. package/src/store/useStore.ts +58 -0
  96. package/src/types/index.ts +10 -0
  97. package/src/utils/elementIcon.test.ts +28 -0
  98. package/src/utils/elementIcon.ts +20 -0
  99. package/src/utils/sourceEditor.ts +46 -0
  100. package/src/utils/watchDiffSummary.ts +159 -0
@@ -5,6 +5,7 @@ interface Props {
5
5
  }
6
6
  export interface InfiniteZoomHandle {
7
7
  focusDiagram(viewId: number): boolean;
8
+ focusElement(viewId: number, elementId: number): boolean;
8
9
  setCameraFrame(frame: ZUICameraFrame): boolean;
9
10
  }
10
11
  declare const InfiniteZoom: import("react").ForwardRefExoticComponent<Props & import("react").RefAttributes<InfiniteZoomHandle>>;
@@ -54,6 +54,11 @@ interface CanvasInteractionOptions {
54
54
  handleElementDeleted: (id: number) => void;
55
55
  handleElementPermanentlyDeleted: (id: number) => void;
56
56
  handleConnectorDeleted: (id: number) => void;
57
+ onPlacementMoved?: (before: PlacedElement, after: PlacedElement) => void;
58
+ onPlacementRemoved?: (placement: PlacedElement) => void;
59
+ onConnectorUpdated?: (before: Connector, after: Connector) => void;
60
+ onConnectorDeleted?: (connector: Connector) => void;
61
+ onUnsupportedMutation?: () => void;
57
62
  handleUpdateTags: (elementId: number, tags: string[]) => Promise<void>;
58
63
  drawingCanvasRef: React.MutableRefObject<DrawingCanvasHandle | null>;
59
64
  snapToGrid?: boolean;
@@ -85,7 +90,7 @@ type InteractionStartOptions = {
85
90
  clientX?: number;
86
91
  clientY?: number;
87
92
  };
88
- export declare function useCanvasInteractions({ viewId, canEdit, drawingMode: _drawingMode, isMobileLayout: _isMobileLayout, rfNodesRef, rfEdgesRef: _rfEdgesRef, viewElementsRef, viewIdRef, incomingLinksRef, treeDataRef, navigateRef, containerRef, interactionSourceIdRef, hoveredZoomRef, hoverPanLockedUntilRef, setViewElements: _setViewElements, setConnectors: _setConnectors, setRfNodes, setRfEdges, setLinksMap, setParentLinksMap: _setParentLinksMap, setHoveredZoom, refreshGrid, refreshElements, stableOnConnectTo, existingElementIds, linksMapRef, parentLinksMapRef, openElementPanel: _openElementPanel, closeElementPanel: closeElementPanel, openConnectorPanel: openConnectorPanel, closeConnectorPanel: closeConnectorPanel, selectedElement, selectedConnector, connectors, layers, setSelectedElement, setSelectedEdge, setSelectedProxyConnectorDetails, openProxyConnectorPanel, closeProxyConnectorPanel, handleElementDeleted, handleElementPermanentlyDeleted, handleConnectorDeleted, handleUpdateTags, drawingCanvasRef, snapToGrid, onMoveStateChange, }: CanvasInteractionOptions): {
93
+ export declare function useCanvasInteractions({ viewId, canEdit, drawingMode: _drawingMode, isMobileLayout: _isMobileLayout, rfNodesRef, rfEdgesRef: _rfEdgesRef, viewElementsRef, viewIdRef, incomingLinksRef, treeDataRef, navigateRef, containerRef, interactionSourceIdRef, hoveredZoomRef, hoverPanLockedUntilRef, setViewElements: _setViewElements, setConnectors: _setConnectors, setRfNodes, setRfEdges, setLinksMap, setParentLinksMap: _setParentLinksMap, setHoveredZoom, refreshGrid, refreshElements, stableOnConnectTo, existingElementIds, linksMapRef, parentLinksMapRef, openElementPanel: _openElementPanel, closeElementPanel: closeElementPanel, openConnectorPanel: openConnectorPanel, closeConnectorPanel: closeConnectorPanel, selectedElement, selectedConnector, connectors, layers, setSelectedElement, setSelectedEdge, setSelectedProxyConnectorDetails, openProxyConnectorPanel, closeProxyConnectorPanel, handleElementDeleted, handleElementPermanentlyDeleted, handleConnectorDeleted, onPlacementMoved, onPlacementRemoved, onConnectorUpdated, onConnectorDeleted, onUnsupportedMutation, handleUpdateTags, drawingCanvasRef, snapToGrid, onMoveStateChange, }: CanvasInteractionOptions): {
89
94
  canvasMenu: {
90
95
  x: number;
91
96
  y: number;
@@ -16,5 +16,7 @@ export declare function useViewContextNeighbours({ snapshot, settings, viewId, v
16
16
  contextNodes: RFNode[];
17
17
  contextConnectors: RFEdge[];
18
18
  proxyConnectorDetailsByKey: Record<string, ProxyConnectorDetails>;
19
+ hiddenProxyCountsByPair: Record<string, number>;
20
+ hiddenProxyDetailsByPair: Record<string, ProxyConnectorDetails>;
19
21
  };
20
22
  export {};
@@ -1,4 +1,5 @@
1
1
  import type { ViewTreeNode, PlacedElement, LibraryElement, Connector, Tag } from '../../../types';
2
+ import type { WorkspaceVersionFollowTarget, WorkspaceVersionPreview } from '../../../context/WorkspaceVersionContext';
2
3
  interface ViewDataOptions {
3
4
  viewId: number | null;
4
5
  interactionSourceId: number | null;
@@ -13,6 +14,8 @@ interface ViewDataOptions {
13
14
  hoveredLayerTags: string[] | null;
14
15
  hoveredLayerColor: string | null;
15
16
  tagColors: Record<string, Tag>;
17
+ versionPreview?: WorkspaceVersionPreview | null;
18
+ versionFollowTarget?: WorkspaceVersionFollowTarget | null;
16
19
  stableOnZoomIn: (elementId: number) => Promise<void>;
17
20
  stableOnZoomOut: (elementId: number) => Promise<void>;
18
21
  stableOnNavigateToView: (id: number) => void;
@@ -38,7 +41,7 @@ interface ViewDataOptions {
38
41
  type: 'in' | 'out' | null;
39
42
  } | null>;
40
43
  }
41
- export declare function useViewData({ viewId, interactionSourceId, clickConnectMode, selectedConnector, activeTags, hiddenLayerTags, hoveredLayerTags, hoveredLayerColor, tagColors, stableOnZoomIn, stableOnZoomOut, stableOnNavigateToView, stableOnSelect, stableOnOpenCodePreview, stableOnInteractionStart, stableOnConnectTo, stableOnStartHandleReconnect, stableOnRemoveElement, stableOnHoverZoom, hoveredZoomRef, }: ViewDataOptions): {
44
+ export declare function useViewData({ viewId, interactionSourceId, clickConnectMode, selectedConnector, activeTags, hiddenLayerTags, hoveredLayerTags, hoveredLayerColor, tagColors, versionPreview, versionFollowTarget, stableOnZoomIn, stableOnZoomOut, stableOnNavigateToView, stableOnSelect, stableOnOpenCodePreview, stableOnInteractionStart, stableOnConnectTo, stableOnStartHandleReconnect, stableOnRemoveElement, stableOnHoverZoom, hoveredZoomRef, }: ViewDataOptions): {
42
45
  view: ViewTreeNode | null | undefined;
43
46
  setView: (view: ViewTreeNode | null | undefined) => void;
44
47
  viewElements: PlacedElement[];
@@ -70,6 +73,5 @@ export declare function useViewData({ viewId, interactionSourceId, clickConnectM
70
73
  handleElementDeleted: (deletedId: number) => void;
71
74
  handleElementPermanentlyDeleted: (deletedId: number) => void;
72
75
  handleElementSaved: (saved: LibraryElement) => void;
73
- setAllElements: (next: import("../../../store/useStore").StoreSetter<LibraryElement[]>) => void;
74
76
  };
75
77
  export {};
@@ -0,0 +1,13 @@
1
+ export interface ViewEditHistoryAction {
2
+ undo: () => Promise<void>;
3
+ redo: () => Promise<void>;
4
+ }
5
+ export declare function useViewEditHistory(): {
6
+ canUndo: boolean;
7
+ canRedo: boolean;
8
+ isApplyingHistory: boolean;
9
+ pushAction: (action: ViewEditHistoryAction) => void;
10
+ clearHistory: () => void;
11
+ undo: () => Promise<void>;
12
+ redo: () => Promise<void>;
13
+ };
@@ -0,0 +1,22 @@
1
+ import type { ExploreData, ViewTreeNode } from '../types';
2
+ export type JumpViewMode = 'explore' | 'hierarchy';
3
+ export type JumpSearchResult = {
4
+ type: 'view';
5
+ key: string;
6
+ name: string;
7
+ viewId: number;
8
+ level: number;
9
+ levelLabel: string | null;
10
+ } | {
11
+ type: 'element';
12
+ key: string;
13
+ name: string;
14
+ viewId: number;
15
+ viewName: string;
16
+ elementId: number;
17
+ kind: string | null;
18
+ };
19
+ export declare function flattenTree(roots: ViewTreeNode[]): ViewTreeNode[];
20
+ export declare function jumpResultSubtitle(result: JumpSearchResult): string;
21
+ export declare function jumpResultActionLabel(view: JumpViewMode): string;
22
+ export declare function buildJumpSearchResults(term: string, flatTree: ViewTreeNode[], exploreData: ExploreData | null): JumpSearchResult[];
@@ -0,0 +1 @@
1
+ export {};
@@ -52,6 +52,7 @@ export type CanvasStoreState = ViewEditorUiState & {
52
52
  removeElementPlacement: (elementId: number) => void;
53
53
  removeElementEverywhere: (elementId: number) => void;
54
54
  mergeSavedElement: (saved: LibraryElement) => void;
55
+ mergeElementsInto: (sourceId: number, survivor: LibraryElement) => void;
55
56
  upsertConnector: (connector: Connector) => void;
56
57
  replaceConnector: (connector: Connector) => void;
57
58
  removeConnector: (connectorId: number) => void;
@@ -70,6 +71,8 @@ export declare function buildElementLibraryItems(allElements: LibraryElement[],
70
71
  export declare function mergeSavedElementIntoPlacements(elements: PlacedElement[], saved: LibraryElement): PlacedElement[];
71
72
  export declare function upsertConnectorInList(connectors: Connector[], connector: Connector): Connector[];
72
73
  export declare function removeConnectorFromList(connectors: Connector[], connectorId: number): Connector[];
74
+ export declare function reassignConnectorsToElement(connectors: Connector[], fromId: number, toId: number): Connector[];
75
+ export declare function mergeElementReplacements(elements: PlacedElement[], sourceId: number, survivor: LibraryElement): PlacedElement[];
73
76
  export declare const useStore: import("zustand").UseBoundStore<import("zustand").StoreApi<CanvasStoreState>>;
74
77
  export declare const canvasSelectors: {
75
78
  existingElementIds: typeof selectExistingElementIds;
@@ -3,6 +3,7 @@ export interface TechnologyConnector {
3
3
  slug?: string;
4
4
  label: string;
5
5
  is_primary_icon?: boolean;
6
+ isPrimaryIcon?: boolean;
6
7
  }
7
8
  export interface TechnologyCatalogItem {
8
9
  iconUrl: string;
@@ -75,6 +76,14 @@ export interface PlacedElement {
75
76
  has_view: boolean;
76
77
  view_label: string | null;
77
78
  }
79
+ export interface VisibilityOverride {
80
+ view_id: number;
81
+ resource_type: 'element' | 'connector';
82
+ resource_id: number;
83
+ level_delta: number;
84
+ created_at?: string;
85
+ updated_at?: string;
86
+ }
78
87
  export interface NavigationConnector {
79
88
  id: number;
80
89
  element_id: number | null;
@@ -0,0 +1,2 @@
1
+ import type { TechnologyConnector } from '../types';
2
+ export declare function resolveElementIconUrl(logoUrl: string | null | undefined, technologyConnectors: TechnologyConnector[] | null | undefined): string | null;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { SourceEditor } from '../api/client';
2
+ export declare function getSourceEditor(): SourceEditor;
3
+ export declare function setSourceEditor(value: SourceEditor): void;
4
+ export declare function useSourceEditor(): {
5
+ editor: SourceEditor;
6
+ setEditor: (value: SourceEditor) => void;
7
+ };
@@ -0,0 +1,34 @@
1
+ import type { ExploreData } from '../types';
2
+ import type { WatchDiff } from '../api/client';
3
+ export type WatchChangeType = 'added' | 'updated' | 'deleted' | 'initialized';
4
+ export interface WatchResourceStat {
5
+ added: number;
6
+ updated: number;
7
+ deleted: number;
8
+ initialized: number;
9
+ addedLines: number;
10
+ removedLines: number;
11
+ }
12
+ export interface WatchDiffLocation {
13
+ key: string;
14
+ label: string;
15
+ resourceType: string;
16
+ resourceId?: number;
17
+ changeType: WatchChangeType;
18
+ summary?: string;
19
+ addedLines: number;
20
+ removedLines: number;
21
+ viewId: number;
22
+ viewName: string;
23
+ }
24
+ export interface WatchDiffSummary {
25
+ files: WatchResourceStat;
26
+ elements: WatchResourceStat;
27
+ connectors: WatchResourceStat;
28
+ }
29
+ export declare function normalizeWatchChangeType(value: string): WatchChangeType;
30
+ export declare function emptyWatchResourceStat(): WatchResourceStat;
31
+ export declare function summarizeWatchDiffs(diffs: WatchDiff[] | null | undefined): WatchDiffSummary;
32
+ export declare function formatStatLine(label: string, stat: WatchResourceStat): string;
33
+ export declare function formatTldStatLine(summary: WatchDiffSummary): string;
34
+ export declare function buildWatchDiffLocations(data: ExploreData, diffs: WatchDiff[] | null | undefined): WatchDiffLocation[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tldiagram/core-ui",
3
- "version": "1.95.1",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,7 +36,7 @@
36
36
  "test": "vitest run"
37
37
  },
38
38
  "dependencies": {
39
- "@buf/tldiagramcom_diagram.bufbuild_es": "^2.11.0-20260419172603-8192c519478e.1",
39
+ "@buf/tldiagramcom_diagram.bufbuild_es": "^2.12.0-20260503002426-45e3166b5ec1.1",
40
40
  "@bufbuild/protobuf": "^2.11.0",
41
41
  "esbuild": "^0.25.12",
42
42
  "zustand": "^5.0.12"
package/src/App.tsx CHANGED
@@ -10,7 +10,9 @@ import Settings from './pages/Settings'
10
10
  import AppearanceSettings from './pages/AppearanceSettings'
11
11
  import { HeaderProvider, useHeader } from './components/HeaderContext'
12
12
  import TopMenuBar from './components/TopMenuBar'
13
+ import WorkspacePanel from './components/WorkspacePanel'
13
14
  import { ThemeProvider } from './context/ThemeContext'
15
+ import { WorkspaceVersionProvider } from './context/WorkspaceVersionContext'
14
16
  import { ACCENT_DEFAULT, BACKGROUND_DEFAULT, ELEMENT_DEFAULT, hexToRgba } from './constants/colors'
15
17
  import { platform } from './platform/local'
16
18
 
@@ -20,8 +22,8 @@ function AppLayout() {
20
22
  const hideMobileBar = header && typeof header === 'object' && 'hideMobileBar' in header ? !!(header as { hideMobileBar?: boolean }).hideMobileBar : false
21
23
 
22
24
  return (
23
- <Box h="100vh" display="flex" flexDirection="column" bg="var(--bg-canvas)" overflow="hidden">
24
- <TopMenuBar hideMobileBar={hideMobileBar}>
25
+ <Box h="100dvh" display="flex" flexDirection="column" bg="var(--bg-canvas)" overflow="hidden">
26
+ <TopMenuBar hideMobileBar={hideMobileBar} rightSlot={<WorkspacePanel />}>
25
27
  {node}
26
28
  </TopMenuBar>
27
29
  <Box
@@ -29,7 +31,7 @@ function AppLayout() {
29
31
  mb={{ base: 'var(--topbar-content-gap)', sm: '0px' }}
30
32
  flexShrink={0}
31
33
  />
32
- <Box flex="1" overflow="hidden" position="relative">
34
+ <Box flex="1" minH={0} overflow="hidden" position="relative">
33
35
  <Outlet />
34
36
  </Box>
35
37
  </Box>
@@ -77,7 +79,7 @@ function HomeRedirect() {
77
79
 
78
80
  if (loading) {
79
81
  return (
80
- <Center h="100vh">
82
+ <Center h="100%">
81
83
  <Spinner size="xl" />
82
84
  </Center>
83
85
  )
@@ -97,7 +99,7 @@ export default function App() {
97
99
 
98
100
  if (!ready) {
99
101
  return (
100
- <Center h="100vh">
102
+ <Center h="100dvh">
101
103
  <Spinner size="xl" />
102
104
  </Center>
103
105
  )
@@ -105,15 +107,17 @@ export default function App() {
105
107
 
106
108
  return (
107
109
  <ThemeProvider>
108
- <Box minH="100vh" bg="var(--bg-canvas)">
110
+ <Box h="100dvh" bg="var(--bg-canvas)" overflow="hidden">
109
111
  <Routes>
110
112
  {platform.getRoutes({ user: null })}
111
113
 
112
- <Route path="/explore/shared/:token" element={<Box h="100vh" overflow="hidden"><HeaderProvider><SharedInfiniteZoom /></HeaderProvider></Box>} />
114
+ <Route path="/explore/shared/:token" element={<Box h="100dvh" overflow="hidden"><HeaderProvider><WorkspaceVersionProvider><SharedInfiniteZoom /></WorkspaceVersionProvider></HeaderProvider></Box>} />
113
115
  <Route
114
116
  element={
115
117
  <HeaderProvider>
116
- <AppLayout />
118
+ <WorkspaceVersionProvider>
119
+ <AppLayout />
120
+ </WorkspaceVersionProvider>
117
121
  </HeaderProvider>
118
122
  }
119
123
  >