@powerhousedao/codegen 4.1.0-dev.8 → 4.1.0-dev.81

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