@powerhousedao/codegen 4.1.0-dev.7 → 4.1.0-dev.71

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 (161) hide show
  1. package/README.md +0 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/src/codegen/.hygen/templates/powerhouse/generate-custom-subgraph/index.js +10 -0
  7. package/dist/src/codegen/.hygen/templates/powerhouse/generate-custom-subgraph/resolvers.esm.t +17 -0
  8. package/dist/src/codegen/.hygen/templates/powerhouse/generate-custom-subgraph/schema.esm.t +16 -0
  9. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/documentModel.esm.t +2 -2
  10. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.esm.t +8 -2
  11. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.js +69 -54
  12. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/ph-factories.esm.t +93 -0
  13. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/reducer.esm.t +9 -4
  14. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/rootIndex.esm.t +6 -7
  15. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/types.esm.t +20 -8
  16. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/utils.esm.t +19 -26
  17. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/creators.esm.t +1 -1
  18. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/customTest.esm.t +2 -2
  19. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/error.esm.t +6 -10
  20. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.js +52 -27
  21. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/index.js +21 -20
  22. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/resolvers.esm.t +64 -51
  23. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/schema.esm.t +3 -3
  24. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/CreateDocument.esm.t +48 -26
  25. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/DriveExplorer.esm.t +213 -218
  26. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/FolderTree.esm.t +96 -67
  27. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/editor.esm.t +2 -73
  28. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/index.esm.t +8 -7
  29. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/index.js +12 -0
  30. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/editor.esm.t +87 -20
  31. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/hooks.esm.t +16 -0
  32. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.esm.t +4 -9
  33. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.js +28 -15
  34. package/dist/src/codegen/.hygen/templates/powerhouse/generate-import-script/index.js +8 -10
  35. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/factory.esm.t +5 -4
  36. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/index.esm.t +5 -9
  37. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/index.js +13 -15
  38. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/lib.esm.t +8 -6
  39. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/lib.inject_call.esm.t +1 -1
  40. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/lib.inject_import.esm.t +1 -1
  41. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/factory.esm.t +6 -5
  42. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.esm.t +7 -9
  43. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.js +13 -15
  44. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/lib.esm.t +8 -9
  45. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/lib.inject_call.esm.t +2 -2
  46. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/lib.inject_import.esm.t +1 -1
  47. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/migrations.esm.t +2 -2
  48. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/schema.esm.t +10 -2
  49. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.esm.t +5 -36
  50. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.js +9 -11
  51. package/dist/src/codegen/generate.d.ts +30 -0
  52. package/dist/src/codegen/generate.d.ts.map +1 -0
  53. package/dist/src/codegen/generate.js +199 -0
  54. package/dist/src/codegen/generate.js.map +1 -0
  55. package/dist/src/codegen/graphql.d.ts +2 -2
  56. package/dist/src/codegen/graphql.d.ts.map +1 -1
  57. package/dist/src/codegen/graphql.js +1 -1
  58. package/dist/src/codegen/graphql.js.map +1 -1
  59. package/dist/src/codegen/hygen.d.ts +15 -10
  60. package/dist/src/codegen/hygen.d.ts.map +1 -1
  61. package/dist/src/codegen/hygen.js +47 -17
  62. package/dist/src/codegen/hygen.js.map +1 -1
  63. package/dist/src/codegen/index.d.ts +6 -32
  64. package/dist/src/codegen/index.d.ts.map +1 -1
  65. package/dist/src/codegen/index.js +6 -182
  66. package/dist/src/codegen/index.js.map +1 -1
  67. package/dist/src/codegen/types.d.ts +9 -0
  68. package/dist/src/codegen/types.d.ts.map +1 -0
  69. package/dist/src/codegen/types.js +2 -0
  70. package/dist/src/codegen/types.js.map +1 -0
  71. package/dist/src/codegen/utils.d.ts +5 -2
  72. package/dist/src/codegen/utils.d.ts.map +1 -1
  73. package/dist/src/codegen/utils.js +42 -4
  74. package/dist/src/codegen/utils.js.map +1 -1
  75. package/dist/src/create-lib/create-project.d.ts.map +1 -1
  76. package/dist/src/create-lib/create-project.js +17 -2
  77. package/dist/src/create-lib/create-project.js.map +1 -1
  78. package/dist/src/index.d.ts +5 -0
  79. package/dist/src/index.d.ts.map +1 -0
  80. package/dist/src/index.js +5 -0
  81. package/dist/src/index.js.map +1 -0
  82. package/dist/src/ts-morph-generator/core/FileGenerator.d.ts +2 -3
  83. package/dist/src/ts-morph-generator/core/FileGenerator.d.ts.map +1 -1
  84. package/dist/src/ts-morph-generator/core/FileGenerator.js.map +1 -1
  85. package/dist/src/ts-morph-generator/core/GenerationContext.d.ts +18 -8
  86. package/dist/src/ts-morph-generator/core/GenerationContext.d.ts.map +1 -1
  87. package/dist/src/ts-morph-generator/core/ReducerGenerator.d.ts +12 -0
  88. package/dist/src/ts-morph-generator/core/ReducerGenerator.d.ts.map +1 -0
  89. package/dist/src/ts-morph-generator/core/ReducerGenerator.js +140 -0
  90. package/dist/src/ts-morph-generator/core/ReducerGenerator.js.map +1 -0
  91. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.d.ts +4 -3
  92. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.d.ts.map +1 -1
  93. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.js +11 -10
  94. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.js.map +1 -1
  95. package/dist/src/ts-morph-generator/index.d.ts +2 -2
  96. package/dist/src/ts-morph-generator/index.d.ts.map +1 -1
  97. package/dist/src/ts-morph-generator/index.js +2 -2
  98. package/dist/src/ts-morph-generator/index.js.map +1 -1
  99. package/dist/src/ts-morph-generator/utilities/DirectoryManager.d.ts +2 -2
  100. package/dist/src/ts-morph-generator/utilities/DirectoryManager.d.ts.map +1 -1
  101. package/dist/src/ts-morph-generator/utilities/ImportManager.d.ts +1 -1
  102. package/dist/src/ts-morph-generator/utilities/ImportManager.d.ts.map +1 -1
  103. package/dist/src/utils/index.d.ts +0 -1
  104. package/dist/src/utils/index.d.ts.map +1 -1
  105. package/dist/src/utils/index.js +0 -1
  106. package/dist/src/utils/index.js.map +1 -1
  107. package/dist/src/utils/validation.d.ts +6 -6
  108. package/dist/src/utils/validation.d.ts.map +1 -1
  109. package/dist/src/utils/validation.js +2 -2
  110. package/dist/src/utils/validation.js.map +1 -1
  111. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  112. package/package.json +23 -25
  113. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.d.ts +0 -25
  114. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.d.ts.map +0 -1
  115. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.js.map +0 -1
  116. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/object.esm.t +0 -49
  117. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.d.ts +0 -23
  118. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.d.ts.map +0 -1
  119. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.js.map +0 -1
  120. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/object.esm.t +0 -37
  121. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/index.d.ts +0 -22
  122. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/index.d.ts.map +0 -1
  123. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/index.js.map +0 -1
  124. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/EditorContainer.esm.t +0 -124
  125. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/FileItemsGrid.esm.t +0 -44
  126. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/FolderItemsGrid.esm.t +0 -96
  127. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/hooks/useSelectedFolderChildren.esm.t +0 -35
  128. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/hooks/useTransformedNodes.esm.t +0 -35
  129. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/types/css.d.esm.t +0 -8
  130. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.d.ts +0 -20
  131. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.d.ts.map +0 -1
  132. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.js.map +0 -1
  133. package/dist/src/codegen/.hygen/templates/powerhouse/generate-import-script/index.d.ts +0 -14
  134. package/dist/src/codegen/.hygen/templates/powerhouse/generate-import-script/index.d.ts.map +0 -1
  135. package/dist/src/codegen/.hygen/templates/powerhouse/generate-import-script/index.js.map +0 -1
  136. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/index.d.ts +0 -20
  137. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/index.d.ts.map +0 -1
  138. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/index.js.map +0 -1
  139. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.d.ts +0 -20
  140. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.d.ts.map +0 -1
  141. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.js.map +0 -1
  142. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.d.ts +0 -16
  143. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.d.ts.map +0 -1
  144. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.js.map +0 -1
  145. package/dist/src/ts-morph-generator/core/index.d.ts +0 -4
  146. package/dist/src/ts-morph-generator/core/index.d.ts.map +0 -1
  147. package/dist/src/ts-morph-generator/core/index.js +0 -4
  148. package/dist/src/ts-morph-generator/core/index.js.map +0 -1
  149. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.d.ts +0 -9
  150. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.d.ts.map +0 -1
  151. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.js +0 -69
  152. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.js.map +0 -1
  153. package/dist/src/ts-morph-generator/file-generators/index.d.ts +0 -2
  154. package/dist/src/ts-morph-generator/file-generators/index.d.ts.map +0 -1
  155. package/dist/src/ts-morph-generator/file-generators/index.js +0 -2
  156. package/dist/src/ts-morph-generator/file-generators/index.js.map +0 -1
  157. package/dist/src/utils/package-manager.d.ts +0 -5
  158. package/dist/src/utils/package-manager.d.ts.map +0 -1
  159. package/dist/src/utils/package-manager.js +0 -17
  160. package/dist/src/utils/package-manager.js.map +0 -1
  161. package/dist/tsconfig.hygen.tsbuildinfo +0 -1
@@ -3,236 +3,231 @@ to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/components/DriveExplorer.tsx
3
3
  unless_exists: true
4
4
  ---
5
5
  import {
6
- type BaseUiFileNode,
7
- type BaseUiFolderNode,
8
- type BaseUiNode,
9
- type UiFileNode,
10
- type UiFolderNode,
11
- type UiNode,
6
+ Breadcrumbs,
7
+ Button,
8
+ FileItem,
9
+ FolderItem,
10
+ useBreadcrumbs,
12
11
  } from "@powerhousedao/design-system";
13
- import { useCallback, useState, useRef, useEffect } from "react";
14
- import type { FileNode, GetDocumentOptions, Node } from "document-drive";
15
- import { FileItemsGrid } from "./FileItemsGrid.js";
16
- import { FolderItemsGrid } from "./FolderItemsGrid.js";
17
- import { FolderTree } from "./FolderTree.js";
18
- import { useTransformedNodes } from "../hooks/useTransformedNodes.js";
19
- import { useSelectedFolderChildren } from "../hooks/useSelectedFolderChildren.js";
20
- import { EditorContainer } from "./EditorContainer.js";
21
- import type { DocumentModelModule } from "document-model";
22
- import { CreateDocumentModal } from "@powerhousedao/design-system";
12
+ import {
13
+ type DriveEditorProps,
14
+ getSyncStatusSync,
15
+ setSelectedNode,
16
+ showDeleteNodeModal,
17
+ useDriveSharingType,
18
+ useFileChildNodesForId,
19
+ useFolderChildNodesForId,
20
+ useNodeActions,
21
+ useNodes,
22
+ useSelectedDrive,
23
+ useSelectedFolder,
24
+ useSelectedNodePath,
25
+ useUserPermissions,
26
+ } from "@powerhousedao/reactor-browser";
27
+ import { useCallback } from "react";
23
28
  import { CreateDocument } from "./CreateDocument.js";
24
- import { type DriveEditorContext, useDriveContext } from "@powerhousedao/reactor-browser";
25
-
26
- interface DriveExplorerProps {
27
- driveId: string;
28
- nodes: Node[];
29
- onAddFolder: (name: string, parentFolder?: string) => void;
30
- onDeleteNode: (nodeId: string) => void;
31
- renameNode: (nodeId: string, name: string) => void;
32
- onCopyNode: (nodeId: string, targetName: string, parentId?: string) => void;
33
- context: DriveEditorContext;
34
- }
35
-
36
- export function DriveExplorer({
37
- driveId,
38
- nodes,
39
- onDeleteNode,
40
- renameNode,
41
- onAddFolder,
42
- onCopyNode,
43
- context,
44
- }: DriveExplorerProps) {
45
- const { getDocumentRevision } = context;
46
-
47
- const [selectedNodeId, setSelectedNodeId] = useState<string | undefined>();
48
- const [activeDocumentId, setActiveDocumentId] = useState<
49
- string | undefined
50
- >();
51
- const [openModal, setOpenModal] = useState(false);
52
- const selectedDocumentModel = useRef<DocumentModelModule | null>(null);
53
- const { addDocument, documentModels } = useDriveContext();
54
-
55
- // Dummy functions to satisfy component types
56
- const dummyDuplicateNode = useCallback((node: BaseUiNode) => {
57
- console.log("Duplicate node:", node);
58
- }, []);
59
-
60
- const dummyAddFile = useCallback(
61
- async (file: File, parentNode: BaseUiNode | null) => {
62
- console.log("Add file:", file, parentNode);
63
- },
64
- []
65
- );
66
-
67
- const dummyMoveNode = useCallback(
68
- async (uiNode: BaseUiNode, targetNode: BaseUiNode) => {
69
- console.log("Move node:", uiNode, targetNode);
70
- },
71
- []
72
- );
73
-
74
- const handleNodeSelect = useCallback((node: BaseUiFolderNode) => {
75
- console.log("Selected node:", node);
76
- setSelectedNodeId(node.id);
77
- }, []);
78
-
79
- const handleFileSelect = useCallback((node: BaseUiFileNode) => {
80
- setActiveDocumentId(node.id);
81
- }, []);
82
-
83
- const handleEditorClose = useCallback(() => {
84
- setActiveDocumentId(undefined);
85
- }, []);
86
-
87
- const onCreateDocument = useCallback(
88
- async (fileName: string) => {
89
- setOpenModal(false);
90
-
91
- const documentModel = selectedDocumentModel.current;
92
- if (!documentModel) return;
93
-
94
- const node = await addDocument(
95
- driveId,
96
- fileName,
97
- documentModel.documentModel.id,
98
- selectedNodeId,
99
- );
100
-
101
- selectedDocumentModel.current = null;
102
- setActiveDocumentId(node.id);
103
- },
104
- [addDocument, driveId, selectedNodeId]
105
- );
106
-
107
- const onSelectDocumentModel = useCallback(
108
- (documentModel: DocumentModelModule) => {
109
- selectedDocumentModel.current = documentModel;
110
- setOpenModal(true);
111
- },
112
- []
113
- );
29
+ import { FolderTree } from "./FolderTree.js";
114
30
 
115
- const onGetDocumentRevision = useCallback(
116
- (options?: GetDocumentOptions) => {
117
- if (!activeDocumentId) return;
118
- return getDocumentRevision?.(activeDocumentId, options);
31
+ /**
32
+ * Main drive explorer component with sidebar navigation and content area.
33
+ * Layout: Left sidebar (folder tree) + Right content area (files/folders + document editor)
34
+ */
35
+ export function DriveExplorer(props: DriveEditorProps) {
36
+ const { children, editorConfig } = props;
37
+
38
+ // === DRIVE CONTEXT HOOKS ===
39
+ // Core drive operations and document models
40
+ const {
41
+ onAddFile,
42
+ onAddFolder,
43
+ onCopyNode,
44
+ onDuplicateNode,
45
+ onMoveNode,
46
+ onRenameNode,
47
+ } = useNodeActions();
48
+
49
+ const { isAllowedToCreateDocuments } = useUserPermissions();
50
+ // === STATE MANAGEMENT HOOKS ===
51
+ // Core state hooks for drive navigation
52
+ const [selectedDrive] = useSelectedDrive(); // Currently selected drive
53
+ const selectedFolder = useSelectedFolder(); // Currently selected folder
54
+ const selectedNodePath = useSelectedNodePath();
55
+ const sharingType = useDriveSharingType(selectedDrive.header.id);
56
+
57
+ // === NAVIGATION SETUP ===
58
+ // Breadcrumbs for folder navigation
59
+ const { breadcrumbs, onBreadcrumbSelected } = useBreadcrumbs({
60
+ selectedNodePath,
61
+ setSelectedNode,
62
+ });
63
+
64
+ const selectedNodeId = selectedFolder?.id || selectedDrive.header.id;
65
+
66
+ const folderChildren = useFolderChildNodesForId(selectedNodeId);
67
+ const fileChildren = useFileChildNodesForId(selectedNodeId);
68
+
69
+ // All nodes (folders and files) for the sidebar tree view
70
+ const allNodes = useNodes() || [];
71
+
72
+ // === EVENT HANDLERS ===
73
+
74
+ // Handle folder creation with optional name parameter
75
+ const handleCreateFolder = useCallback(
76
+ async (folderName?: string) => {
77
+ let name: string | undefined = folderName;
78
+
79
+ // If no name provided, prompt for it (for manual folder creation)
80
+ if (!name) {
81
+ const promptResult = prompt("Enter folder name:");
82
+ name = promptResult || undefined;
83
+ }
84
+
85
+ if (name?.trim()) {
86
+ try {
87
+ await onAddFolder(name.trim(), selectedFolder);
88
+ } catch (error) {
89
+ console.error("Failed to create folder:", error);
90
+ }
91
+ }
119
92
  },
120
- [getDocumentRevision, activeDocumentId],
121
- );
122
-
123
- const filteredDocumentModels = documentModels;
124
-
125
- // Transform nodes using the custom hook
126
- const transformedNodes = useTransformedNodes(nodes, driveId);
127
-
128
- // Separate folders and files
129
- const folders = transformedNodes.filter(
130
- (node): node is UiFolderNode => node.kind === "FOLDER"
131
- );
132
- const files = transformedNodes.filter(
133
- (node): node is UiFileNode => node.kind === "FILE"
93
+ [onAddFolder, selectedFolder],
134
94
  );
135
95
 
136
- // Get children of selected folder using the custom hook
137
- const selectedFolderChildren = useSelectedFolderChildren(
138
- selectedNodeId,
139
- folders,
140
- files
141
- );
142
-
143
- // Get the active document info from nodes
144
- const activeDocument = activeDocumentId
145
- ? files.find((file) => file.id === activeDocumentId)
146
- : undefined;
147
-
148
- const documentModelModule = activeDocument
149
- ? context.getDocumentModelModule(activeDocument.documentType)
150
- : null;
151
-
152
- const editorModule = activeDocument
153
- ? context.getEditor(activeDocument.documentType)
154
- : null;
96
+ // if a document is selected then it's editor will be passed as children
97
+ const showDocumentEditor = !!children;
155
98
 
99
+ // === RENDER ===
156
100
  return (
157
101
  <div className="flex h-full">
158
- {/* Sidebar */}
159
- <div className="w-64 border-r border-gray-200 p-4 overflow-y-auto">
160
- <h2 className="text-lg font-semibold mb-4">Folders</h2>
161
- <FolderTree
162
- folders={folders}
163
- selectedNodeId={selectedNodeId}
164
- onSelectNode={handleNodeSelect}
165
- />
166
- </div>
102
+ {/* === LEFT SIDEBAR: Folder and File Navigation === */}
103
+ {/* Sidebar component manages its own width, styling, and overflow */}
104
+ <FolderTree
105
+ driveId={selectedDrive.header.id}
106
+ driveName={selectedDrive.state.global.name}
107
+ nodes={allNodes}
108
+ selectedNodeId={selectedNodeId}
109
+ onSelectNode={setSelectedNode}
110
+ />
167
111
 
168
- {/* Main Content */}
169
- <div className="flex-1 p-4 overflow-y-auto">
170
- {activeDocument && documentModelModule && editorModule ? (
171
- <EditorContainer
172
- context={{
173
- ...context,
174
- getDocumentRevision: onGetDocumentRevision,
175
- }}
176
- documentId={activeDocumentId!}
177
- documentType={activeDocument.documentType}
178
- driveId={driveId}
179
- onClose={handleEditorClose}
180
- title={activeDocument.name}
181
- documentModelModule={documentModelModule}
182
- editorModule={editorModule}
183
- />
112
+ {/* === RIGHT CONTENT AREA: Files/Folders or Document Editor === */}
113
+ <div className="flex-1 overflow-y-auto p-4">
114
+ {/* Conditional rendering: Document editor or folder contents */}
115
+ {showDocumentEditor ? (
116
+ // Document editor view
117
+ children
184
118
  ) : (
185
- <>
186
- <h2 className="text-lg font-semibold mb-4">Contents</h2>
187
-
188
- {/* Folders Section */}
189
- <FolderItemsGrid
190
- folders={selectedFolderChildren.folders}
191
- onSelectNode={handleNodeSelect}
192
- onRenameNode={renameNode}
193
- onDuplicateNode={(uiNode) =>
194
- onCopyNode(
195
- uiNode.id,
196
- "Copy of " + uiNode.name,
197
- uiNode.parentFolder
198
- )
199
- }
200
- onDeleteNode={onDeleteNode}
201
- onAddFile={dummyAddFile}
202
- onCopyNode={async (uiNode, targetNode) =>
203
- onCopyNode(uiNode.id, "Copy of " + uiNode.name, targetNode.id)
204
- }
205
- onMoveNode={dummyMoveNode}
206
- isAllowedToCreateDocuments={true}
207
- onAddFolder={onAddFolder}
208
- parentFolderId={selectedNodeId}
209
- />
210
-
211
- {/* Files Section */}
212
- <FileItemsGrid
213
- files={selectedFolderChildren.files}
214
- onSelectNode={handleFileSelect}
215
- onRenameNode={renameNode}
216
- onDuplicateNode={dummyDuplicateNode}
217
- onDeleteNode={onDeleteNode}
218
- isAllowedToCreateDocuments={true}
219
- />
220
-
221
- {/* Create Document Section */}
222
- <CreateDocument
223
- createDocument={onSelectDocumentModel}
224
- documentModels={filteredDocumentModels}
225
- />
226
- </>
119
+ /* Folder contents view */
120
+ <div className="space-y-6 px-6">
121
+ {/* === HEADER SECTION === */}
122
+ <div className="space-y-3">
123
+ <div className="flex items-center justify-between">
124
+ {/* Folder title */}
125
+ <h2 className="text-lg font-semibold">
126
+ {selectedFolder
127
+ ? `Contents of "${selectedFolder.name}"`
128
+ : "Root Contents"}
129
+ </h2>
130
+ {/* Customize: Add more action buttons here */}
131
+ {isAllowedToCreateDocuments && (
132
+ <Button
133
+ onClick={() => handleCreateFolder()}
134
+ className="bg-gray-200 p-2 hover:bg-gray-300"
135
+ >
136
+ New Folder
137
+ </Button>
138
+ )}
139
+ </div>
140
+
141
+ {/* Navigation breadcrumbs */}
142
+ <div className="border-b border-gray-200 pb-3">
143
+ <Breadcrumbs
144
+ breadcrumbs={breadcrumbs}
145
+ createEnabled={isAllowedToCreateDocuments}
146
+ onCreate={handleCreateFolder}
147
+ onBreadcrumbSelected={onBreadcrumbSelected}
148
+ />
149
+ </div>
150
+ </div>
151
+
152
+ {/* === FOLDERS SECTION === */}
153
+ {folderChildren.length > 0 && (
154
+ <div>
155
+ <h3 className="mb-2 text-sm font-bold text-gray-600">
156
+ Folders
157
+ </h3>
158
+ <div className="flex flex-wrap gap-4">
159
+ {folderChildren.map((folderNode) => (
160
+ <FolderItem
161
+ key={folderNode.id}
162
+ folderNode={folderNode}
163
+ isAllowedToCreateDocuments={isAllowedToCreateDocuments}
164
+ sharingType={sharingType || "LOCAL"}
165
+ getSyncStatusSync={getSyncStatusSync}
166
+ setSelectedNode={setSelectedNode}
167
+ onAddFile={onAddFile}
168
+ onCopyNode={onCopyNode}
169
+ onMoveNode={onMoveNode}
170
+ onRenameNode={onRenameNode}
171
+ onDuplicateNode={onDuplicateNode}
172
+ onAddFolder={onAddFolder}
173
+ onAddAndSelectNewFolder={handleCreateFolder}
174
+ showDeleteNodeModal={(node) =>
175
+ showDeleteNodeModal(node.id)
176
+ }
177
+ />
178
+ ))}
179
+ </div>
180
+ </div>
181
+ )}
182
+
183
+ {/* === FILES/DOCUMENTS SECTION === */}
184
+ {fileChildren.length > 0 && (
185
+ <div>
186
+ <h3 className="mb-2 text-sm font-semibold text-gray-600">
187
+ Documents
188
+ </h3>
189
+ <div className="flex flex-wrap gap-4">
190
+ {fileChildren.map((fileNode) => (
191
+ <FileItem
192
+ key={fileNode.id}
193
+ fileNode={fileNode}
194
+ isAllowedToCreateDocuments={isAllowedToCreateDocuments}
195
+ sharingType={sharingType || "LOCAL"}
196
+ getSyncStatusSync={getSyncStatusSync}
197
+ setSelectedNode={setSelectedNode}
198
+ showDeleteNodeModal={(node) =>
199
+ showDeleteNodeModal(node.id)
200
+ }
201
+ onRenameNode={onRenameNode}
202
+ onDuplicateNode={onDuplicateNode}
203
+ onAddFile={onAddFile}
204
+ onCopyNode={onCopyNode}
205
+ onMoveNode={onMoveNode}
206
+ onAddFolder={onAddFolder}
207
+ onAddAndSelectNewFolder={handleCreateFolder}
208
+ />
209
+ ))}
210
+ </div>
211
+ </div>
212
+ )}
213
+
214
+ {/* === EMPTY STATE === */}
215
+ {/* Customize empty state message and styling here */}
216
+ {folderChildren.length === 0 && fileChildren.length === 0 && (
217
+ <div className="py-12 text-center text-gray-500">
218
+ <p className="text-lg">This folder is empty</p>
219
+ <p className="mt-2 text-sm">
220
+ Create your first document or folder below
221
+ </p>
222
+ </div>
223
+ )}
224
+
225
+ {/* === DOCUMENT CREATION SECTION === */}
226
+ {/* Component for creating new documents */}
227
+ <CreateDocument documentTypes={editorConfig?.documentTypes} />
228
+ </div>
227
229
  )}
228
230
  </div>
229
-
230
- {/* Create Document Modal */}
231
- <CreateDocumentModal
232
- onContinue={onCreateDocument}
233
- onOpenChange={(open) => setOpenModal(open)}
234
- open={openModal}
235
- />
236
231
  </div>
237
232
  );
238
- }
233
+ }
@@ -2,84 +2,113 @@
2
2
  to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/components/FolderTree.tsx"
3
3
  unless_exists: true
4
4
  ---
5
- import { useState } from 'react';
6
- import type { UiFolderNode } from "@powerhousedao/design-system";
5
+ import {
6
+ Sidebar,
7
+ SidebarProvider,
8
+ type SidebarNode,
9
+ } from "@powerhousedao/document-engineering";
10
+ import type { Node } from "document-drive";
11
+ import { useMemo } from "react";
7
12
 
8
13
  interface FolderTreeProps {
9
- folders: UiFolderNode[];
14
+ driveId: string;
15
+ driveName: string;
16
+ nodes: Node[];
10
17
  selectedNodeId?: string;
11
- onSelectNode: (node: UiFolderNode) => void;
18
+ onSelectNode: (nodeId: string | undefined) => void;
12
19
  }
13
20
 
14
- export function FolderTree({ folders, selectedNodeId, onSelectNode }: FolderTreeProps) {
15
- const [expandedFolders, setExpandedFolders] = useState<Set<string>>(new Set());
21
+ function isFolder(node: Node): boolean {
22
+ return node.kind === "folder";
23
+ }
16
24
 
17
- const toggleFolder = (folderId: string) => {
18
- setExpandedFolders(prev => {
19
- const next = new Set(prev);
20
- if (next.has(folderId)) {
21
- next.delete(folderId);
22
- } else {
23
- next.add(folderId);
25
+ function buildSidebarNodes(
26
+ nodes: Node[],
27
+ parentId: string | null | undefined,
28
+ ): SidebarNode[] {
29
+ return nodes
30
+ .filter((n) => {
31
+ if (parentId == null) {
32
+ return n.parentFolder == null;
33
+ }
34
+ return n.parentFolder === parentId;
35
+ })
36
+ .map((node): SidebarNode => {
37
+ if (isFolder(node)) {
38
+ return {
39
+ id: node.id,
40
+ title: node.name,
41
+ icon: "FolderClose" as const,
42
+ expandedIcon: "FolderOpen" as const,
43
+ children: buildSidebarNodes(nodes, node.id),
44
+ };
24
45
  }
25
- return next;
46
+ return {
47
+ id: node.id,
48
+ title: node.name,
49
+ icon: "File" as const,
50
+ };
26
51
  });
27
- };
52
+ }
28
53
 
29
- const renderFolder = (folder: UiFolderNode, level: number = 0) => {
30
- const hasChildren = folders.some(f => f.parentFolder === folder.id);
31
- const isExpanded = expandedFolders.has(folder.id);
32
- const isSelected = selectedNodeId === folder.id;
54
+ function transformNodesToSidebarNodes(
55
+ nodes: Node[],
56
+ driveName: string,
57
+ ): SidebarNode[] {
58
+ return [
59
+ {
60
+ id: "root",
61
+ title: driveName,
62
+ icon: "Drive" as const,
63
+ children: buildSidebarNodes(nodes, null),
64
+ },
65
+ ];
66
+ }
67
+
68
+ /**
69
+ * Hierarchical folder tree navigation component using Sidebar from document-engineering.
70
+ * Displays folders and files in a tree structure with expand/collapse functionality, search, and resize support.
71
+ */
72
+ export function FolderTree({
73
+ driveId,
74
+ driveName,
75
+ nodes,
76
+ selectedNodeId,
77
+ onSelectNode,
78
+ }: FolderTreeProps) {
79
+ // Transform Node[] to hierarchical SidebarNode structure
80
+ const sidebarNodes = useMemo(
81
+ () => transformNodesToSidebarNodes(nodes, driveName),
82
+ [nodes, driveName],
83
+ );
33
84
 
34
- return (
35
- <div key={folder.id}>
36
- <div
37
- className={`flex items-center py-1 px-2 cursor-pointer hover:bg-gray-100 rounded ${
38
- isSelected ? 'bg-gray-100' : ''
39
- }`}
40
- style={{ paddingLeft: `${level * 16 + 8}px` }}
41
- onClick={() => onSelectNode(folder)}
42
- >
43
- {hasChildren && (
44
- <button
45
- className="w-4 h-4 mr-1 flex items-center justify-center"
46
- onClick={(e) => {
47
- e.stopPropagation();
48
- toggleFolder(folder.id);
49
- }}
50
- >
51
- {isExpanded ? '▼' : '▶'}
52
- </button>
53
- )}
54
- <span className="text-sm">{folder.name}</span>
55
- </div>
56
- {isExpanded && hasChildren && (
57
- <div>
58
- {folders
59
- .filter(f => f.parentFolder === folder.id)
60
- .map(child => renderFolder(child, level + 1))}
61
- </div>
62
- )}
63
- </div>
64
- );
85
+ const handleActiveNodeChange = (node: SidebarNode) => {
86
+ // If root node is selected, pass undefined to match existing behavior
87
+ if (node.id === "root") {
88
+ onSelectNode(undefined);
89
+ } else {
90
+ onSelectNode(node.id);
91
+ }
65
92
  };
93
+ // Map selectedNodeId to activeNodeId (use "root" when undefined)
94
+ const activeNodeId =
95
+ !selectedNodeId || selectedNodeId === driveId ? "root" : selectedNodeId;
66
96
 
67
97
  return (
68
- <div className="space-y-1">
69
- {/* Root Directory Option */}
70
- <div
71
- className={`flex items-center py-1 px-2 cursor-pointer hover:bg-gray-100 rounded ${
72
- !selectedNodeId ? 'bg-gray-100' : ''
73
- }`}
74
- onClick={() => onSelectNode({ id: '', name: 'Root', kind: 'FOLDER' } as UiFolderNode)}
75
- >
76
- <span className="text-sm font-medium">Root</span>
77
- </div>
78
-
79
- {/* Folder Tree */}
80
- {folders
81
- .filter(folder => !folder.parentFolder)
82
- .map(folder => renderFolder(folder))}
83
- </div>
98
+ <SidebarProvider nodes={sidebarNodes}>
99
+ <Sidebar
100
+ className="pt-1"
101
+ nodes={sidebarNodes}
102
+ activeNodeId={activeNodeId}
103
+ onActiveNodeChange={handleActiveNodeChange}
104
+ sidebarTitle="Drive Explorer"
105
+ showSearchBar={true}
106
+ resizable={true}
107
+ allowPinning={false}
108
+ showStatusFilter={false}
109
+ initialWidth={256}
110
+ defaultLevel={2}
111
+ />
112
+ </SidebarProvider>
84
113
  );
85
- }
114
+ }