@powerhousedao/codegen 4.1.0-dev.9 → 5.0.0-staging.1

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 (75) hide show
  1. package/dist/src/codegen/.hygen/templates/powerhouse/generate-custom-subgraph/index.d.ts +14 -0
  2. package/dist/src/codegen/.hygen/templates/powerhouse/generate-custom-subgraph/index.d.ts.map +1 -0
  3. package/dist/src/codegen/.hygen/templates/powerhouse/generate-custom-subgraph/index.js +12 -0
  4. package/dist/src/codegen/.hygen/templates/powerhouse/generate-custom-subgraph/index.js.map +1 -0
  5. package/dist/src/codegen/.hygen/templates/powerhouse/generate-custom-subgraph/resolvers.esm.t +17 -0
  6. package/dist/src/codegen/.hygen/templates/powerhouse/generate-custom-subgraph/schema.esm.t +16 -0
  7. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.esm.t +9 -1
  8. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/object.esm.t +6 -6
  9. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/ph-factories.esm.t +96 -0
  10. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/reducer.esm.t +7 -3
  11. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/rootIndex.esm.t +2 -4
  12. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/types.esm.t +8 -6
  13. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/utils.esm.t +45 -38
  14. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/customTest.esm.t +2 -2
  15. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/error.esm.t +6 -10
  16. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.d.ts +4 -0
  17. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.d.ts.map +1 -1
  18. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.js +13 -1
  19. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.js.map +1 -1
  20. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/object.esm.t +2 -7
  21. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/resolvers.esm.t +59 -50
  22. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/schema.esm.t +3 -3
  23. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/CreateDocument.esm.t +38 -24
  24. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/DriveExplorer.esm.t +244 -181
  25. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/EditorContainer.esm.t +53 -74
  26. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/FolderTree.esm.t +44 -26
  27. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/editor.esm.t +22 -58
  28. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/index.d.ts +16 -0
  29. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/index.d.ts.map +1 -0
  30. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/index.esm.t +2 -3
  31. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/index.js +12 -0
  32. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/index.js.map +1 -0
  33. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/editor.esm.t +1 -1
  34. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.d.ts +2 -0
  35. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.d.ts.map +1 -1
  36. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.esm.t +2 -5
  37. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.js +1 -0
  38. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.js.map +1 -1
  39. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/factory.esm.t +3 -2
  40. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/index.esm.t +2 -7
  41. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/lib.esm.t +7 -5
  42. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/lib.inject_call.esm.t +1 -1
  43. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/lib.inject_import.esm.t +1 -1
  44. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/factory.esm.t +3 -2
  45. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.esm.t +2 -8
  46. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/lib.esm.t +8 -9
  47. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/lib.inject_call.esm.t +2 -2
  48. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/lib.inject_import.esm.t +1 -1
  49. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/schema.esm.t +9 -1
  50. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.esm.t +2 -33
  51. package/dist/src/codegen/hygen.d.ts +6 -4
  52. package/dist/src/codegen/hygen.d.ts.map +1 -1
  53. package/dist/src/codegen/hygen.js +35 -8
  54. package/dist/src/codegen/hygen.js.map +1 -1
  55. package/dist/src/codegen/index.d.ts +5 -3
  56. package/dist/src/codegen/index.d.ts.map +1 -1
  57. package/dist/src/codegen/index.js +74 -7
  58. package/dist/src/codegen/index.js.map +1 -1
  59. package/dist/src/ts-morph-generator/core/GenerationContext.d.ts +8 -6
  60. package/dist/src/ts-morph-generator/core/GenerationContext.d.ts.map +1 -1
  61. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.d.ts +1 -0
  62. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.d.ts.map +1 -1
  63. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.js +9 -7
  64. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.js.map +1 -1
  65. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.d.ts +3 -0
  66. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.d.ts.map +1 -1
  67. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.js +85 -14
  68. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.js.map +1 -1
  69. package/dist/tsconfig.hygen.tsbuildinfo +1 -1
  70. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  71. package/package.json +13 -6
  72. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/FileItemsGrid.esm.t +0 -44
  73. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/FolderItemsGrid.esm.t +0 -96
  74. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/hooks/useSelectedFolderChildren.esm.t +0 -35
  75. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/hooks/useTransformedNodes.esm.t +0 -35
@@ -3,231 +3,294 @@ 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
+ CreateDocumentModal,
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";
12
+ import {
13
+ addDocument,
14
+ type DriveEditorProps,
15
+ getSyncStatusSync,
16
+ setSelectedNode,
17
+ useAllFolderNodes,
18
+ useDocumentModelModules,
19
+ useDriveContext,
20
+ useDriveSharingType,
21
+ useEditorModules,
22
+ useFileChildNodes,
23
+ useFolderChildNodes,
24
+ useSelectedDrive,
25
+ useSelectedFolder,
26
+ useSelectedNodePath,
27
+ useUserPermissions,
28
+ } from "@powerhousedao/reactor-browser";
21
29
  import type { DocumentModelModule } from "document-model";
22
- import { CreateDocumentModal } from "@powerhousedao/design-system";
23
- 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
- }
30
+ import { useCallback, useRef, useState } from "react";
31
+ import { CreateDocument } from "./CreateDocument.jsx";
32
+ import { EditorContainer } from "./EditorContainer.jsx";
33
+ import { FolderTree } from "./FolderTree.jsx";
35
34
 
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>();
35
+ /**
36
+ * Main drive explorer component with sidebar navigation and content area.
37
+ * Layout: Left sidebar (folder tree) + Right content area (files/folders + document editor)
38
+ */
39
+ export function DriveExplorer(props: DriveEditorProps) {
40
+ // === DOCUMENT EDITOR STATE ===
41
+ // Customize document opening/closing behavior here
48
42
  const [activeDocumentId, setActiveDocumentId] = useState<
49
43
  string | undefined
50
44
  >();
51
45
  const [openModal, setOpenModal] = useState(false);
52
46
  const selectedDocumentModel = useRef<DocumentModelModule | null>(null);
53
- const { addDocument, documentModels } = useDriveContext();
47
+ const editorModules = useEditorModules();
48
+ // === DRIVE CONTEXT HOOKS ===
49
+ // Core drive operations and document models
50
+ const {
51
+ onAddFile,
52
+ onAddFolder,
53
+ onCopyNode,
54
+ onDuplicateNode,
55
+ onMoveNode,
56
+ onRenameNode,
57
+ showDeleteNodeModal,
58
+ } = useDriveContext();
54
59
 
55
- // Dummy functions to satisfy component types
56
- const dummyDuplicateNode = useCallback((node: BaseUiNode) => {
57
- console.log("Duplicate node:", node);
58
- }, []);
60
+ const { isAllowedToCreateDocuments } = useUserPermissions();
61
+ // === STATE MANAGEMENT HOOKS ===
62
+ // Core state hooks for drive navigation
63
+ const [selectedDrive] = useSelectedDrive(); // Currently selected drive
64
+ const selectedFolder = useSelectedFolder(); // Currently selected folder
65
+ const selectedNodePath = useSelectedNodePath();
66
+ const sharingType = useDriveSharingType(selectedDrive?.header.id);
59
67
 
60
- const dummyAddFile = useCallback(
61
- async (file: File, parentNode: BaseUiNode | null) => {
62
- console.log("Add file:", file, parentNode);
63
- },
64
- []
65
- );
68
+ // === NAVIGATION SETUP ===
69
+ // Breadcrumbs for folder navigation
70
+ const { breadcrumbs, onBreadcrumbSelected } = useBreadcrumbs({
71
+ selectedNodePath,
72
+ setSelectedNode,
73
+ });
66
74
 
67
- const dummyMoveNode = useCallback(
68
- async (uiNode: BaseUiNode, targetNode: BaseUiNode) => {
69
- console.log("Move node:", uiNode, targetNode);
70
- },
71
- []
72
- );
75
+ const folderChildren = useFolderChildNodes();
76
+ const fileChildren = useFileChildNodes();
77
+
78
+ // All folders for the sidebar tree view
79
+ const allFolders = useAllFolderNodes();
73
80
 
74
- const handleNodeSelect = useCallback((node: BaseUiFolderNode) => {
75
- console.log("Selected node:", node);
76
- setSelectedNodeId(node.id);
77
- }, []);
81
+ // === EVENT HANDLERS ===
78
82
 
79
- const handleFileSelect = useCallback((node: BaseUiFileNode) => {
80
- setActiveDocumentId(node.id);
81
- }, []);
83
+ // Handle folder creation with optional name parameter
84
+ const handleCreateFolder = useCallback(
85
+ async (folderName?: string) => {
86
+ let name: string | undefined = folderName;
82
87
 
83
- const handleEditorClose = useCallback(() => {
84
- setActiveDocumentId(undefined);
85
- }, []);
88
+ // If no name provided, prompt for it (for manual folder creation)
89
+ if (!name) {
90
+ const promptResult = prompt("Enter folder name:");
91
+ name = promptResult || undefined;
92
+ }
86
93
 
94
+ if (name?.trim()) {
95
+ try {
96
+ await onAddFolder(name.trim(), selectedFolder);
97
+ } catch (error) {
98
+ console.error("Failed to create folder:", error);
99
+ }
100
+ }
101
+ },
102
+ [onAddFolder, selectedFolder],
103
+ );
104
+
105
+ // Handle document creation from modal
87
106
  const onCreateDocument = useCallback(
88
107
  async (fileName: string) => {
89
108
  setOpenModal(false);
90
109
 
91
110
  const documentModel = selectedDocumentModel.current;
92
- if (!documentModel) return;
111
+ if (!documentModel || !selectedDrive?.header.id) return;
93
112
 
94
- const node = await addDocument(
95
- driveId,
96
- fileName,
97
- documentModel.documentModel.id,
98
- selectedNodeId,
99
- );
113
+ try {
114
+ const node = await addDocument(
115
+ selectedDrive.header.id,
116
+ fileName,
117
+ documentModel.documentModel.id,
118
+ selectedFolder?.id,
119
+ );
100
120
 
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
- );
121
+ selectedDocumentModel.current = null;
114
122
 
115
- const onGetDocumentRevision = useCallback(
116
- (options?: GetDocumentOptions) => {
117
- if (!activeDocumentId) return;
118
- return getDocumentRevision?.(activeDocumentId, options);
123
+ if (node) {
124
+ // Customize: Auto-open created document by uncommenting below
125
+ // setActiveDocumentId(node.id);
126
+ }
127
+ } catch (error) {
128
+ console.error("Failed to create document:", error);
129
+ }
119
130
  },
120
- [getDocumentRevision, activeDocumentId],
131
+ [addDocument, editorModules, selectedDrive?.header.id, selectedFolder?.id],
121
132
  );
122
133
 
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
- );
134
+ // === DOCUMENT EDITOR DATA ===
135
+ // Filter available document types here if needed
136
+ const documentModelModules = useDocumentModelModules();
142
137
 
143
- // Get the active document info from nodes
138
+ // Get active document and its editor components
144
139
  const activeDocument = activeDocumentId
145
- ? files.find((file) => file.id === activeDocumentId)
140
+ ? fileChildren.find((file) => file.id === activeDocumentId)
146
141
  : undefined;
147
142
 
148
143
  const documentModelModule = activeDocument
149
- ? context.getDocumentModelModule(activeDocument.documentType)
144
+ ? documentModelModules?.find(
145
+ (m) => m.documentModel.id === activeDocument.documentType,
146
+ )
150
147
  : null;
151
148
 
152
149
  const editorModule = activeDocument
153
- ? context.getEditor(activeDocument.documentType)
150
+ ? editorModules?.find((e) =>
151
+ e.documentTypes.includes(activeDocument.documentType),
152
+ )
154
153
  : null;
155
154
 
155
+ // === RENDER ===
156
156
  return (
157
157
  <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
- />
158
+ {/* === LEFT SIDEBAR: Folder Navigation === */}
159
+ {/* Customize sidebar width by changing w-64 */}
160
+ <div className="w-64 overflow-y-auto border-r border-gray-200 bg-white">
161
+ <div className="p-4">
162
+ {/* Customize sidebar title here */}
163
+ <h2 className="mb-4 text-lg font-semibold text-gray-700">
164
+ Drive Explorer
165
+ </h2>
166
+
167
+ {/* Folder tree navigation component */}
168
+ <FolderTree folders={allFolders} onSelectNode={setSelectedNode} />
169
+ </div>
166
170
  </div>
167
171
 
168
- {/* Main Content */}
169
- <div className="flex-1 p-4 overflow-y-auto">
172
+ {/* === RIGHT CONTENT AREA: Files/Folders or Document Editor === */}
173
+ <div className="flex-1 overflow-y-auto p-4">
174
+ {/* Conditional rendering: Document editor or folder contents */}
170
175
  {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
- />
176
+ // Document editor view
177
+ <EditorContainer handleClose={() => setActiveDocumentId(undefined)} />
184
178
  ) : (
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
- </>
179
+ /* Folder contents view */
180
+ <div className="space-y-6">
181
+ {/* === HEADER SECTION === */}
182
+ <div className="space-y-3">
183
+ <div className="flex items-center justify-between">
184
+ {/* Folder title */}
185
+ <h2 className="text-lg font-semibold">
186
+ {selectedFolder
187
+ ? `Contents of "${selectedFolder.name}"`
188
+ : "Root Contents"}
189
+ </h2>
190
+ {/* Customize: Add more action buttons here */}
191
+ {isAllowedToCreateDocuments && (
192
+ <button
193
+ onClick={() => handleCreateFolder()}
194
+ className="rounded bg-blue-500 px-3 py-1 text-sm text-white hover:bg-blue-600"
195
+ >
196
+ + New Folder
197
+ </button>
198
+ )}
199
+ </div>
200
+
201
+ {/* Navigation breadcrumbs */}
202
+ {breadcrumbs.length > 1 && (
203
+ <div className="border-b border-gray-200 pb-3">
204
+ <Breadcrumbs
205
+ breadcrumbs={breadcrumbs}
206
+ createEnabled={isAllowedToCreateDocuments}
207
+ onCreate={handleCreateFolder}
208
+ onBreadcrumbSelected={onBreadcrumbSelected}
209
+ />
210
+ </div>
211
+ )}
212
+ </div>
213
+
214
+ {/* === FOLDERS SECTION === */}
215
+ {/* Customize grid layout by changing grid-cols-1 */}
216
+ {folderChildren.length > 0 && (
217
+ <div>
218
+ <h3 className="mb-2 text-sm font-medium text-gray-500">
219
+ 📁 Folders
220
+ </h3>
221
+ <div className="grid grid-cols-1 gap-2">
222
+ {folderChildren.map((folderNode) => (
223
+ <FolderItem
224
+ key={folderNode.id}
225
+ folderNode={folderNode}
226
+ isAllowedToCreateDocuments={isAllowedToCreateDocuments}
227
+ sharingType={sharingType || "LOCAL"}
228
+ getSyncStatusSync={getSyncStatusSync}
229
+ setSelectedNode={setSelectedNode}
230
+ onAddFile={onAddFile}
231
+ onCopyNode={onCopyNode}
232
+ onMoveNode={onMoveNode}
233
+ onRenameNode={onRenameNode}
234
+ onDuplicateNode={onDuplicateNode}
235
+ onAddFolder={onAddFolder}
236
+ onAddAndSelectNewFolder={handleCreateFolder}
237
+ showDeleteNodeModal={showDeleteNodeModal}
238
+ />
239
+ ))}
240
+ </div>
241
+ </div>
242
+ )}
243
+
244
+ {/* === FILES/DOCUMENTS SECTION === */}
245
+ {/* Customize grid layout by changing grid-cols-1 */}
246
+ {fileChildren.length > 0 && (
247
+ <div>
248
+ <h3 className="mb-2 text-sm font-medium text-gray-500">
249
+ 📄 Documents
250
+ </h3>
251
+ <div className="grid grid-cols-1 gap-2">
252
+ {fileChildren.map((fileNode) => (
253
+ <FileItem
254
+ key={fileNode.id}
255
+ fileNode={fileNode}
256
+ isAllowedToCreateDocuments={isAllowedToCreateDocuments}
257
+ sharingType={sharingType || "LOCAL"}
258
+ getSyncStatusSync={getSyncStatusSync}
259
+ setSelectedNode={setSelectedNode}
260
+ showDeleteNodeModal={showDeleteNodeModal}
261
+ onRenameNode={onRenameNode}
262
+ onDuplicateNode={onDuplicateNode}
263
+ onAddFile={onAddFile}
264
+ onCopyNode={onCopyNode}
265
+ onMoveNode={onMoveNode}
266
+ onAddFolder={onAddFolder}
267
+ onAddAndSelectNewFolder={handleCreateFolder}
268
+ />
269
+ ))}
270
+ </div>
271
+ </div>
272
+ )}
273
+
274
+ {/* === EMPTY STATE === */}
275
+ {/* Customize empty state message and styling here */}
276
+ {folderChildren.length === 0 && fileChildren.length === 0 && (
277
+ <div className="py-12 text-center text-gray-500">
278
+ <p className="text-lg">📁 This folder is empty</p>
279
+ <p className="mt-2 text-sm">
280
+ Create your first document or folder below
281
+ </p>
282
+ </div>
283
+ )}
284
+
285
+ {/* === DOCUMENT CREATION SECTION === */}
286
+ {/* Component for creating new documents */}
287
+ <CreateDocument />
288
+ </div>
227
289
  )}
228
290
  </div>
229
291
 
230
- {/* Create Document Modal */}
292
+ {/* === DOCUMENT CREATION MODAL === */}
293
+ {/* Modal for entering document name after selecting type */}
231
294
  <CreateDocumentModal
232
295
  onContinue={onCreateDocument}
233
296
  onOpenChange={(open) => setOpenModal(open)}
@@ -235,4 +298,4 @@ export function DriveExplorer({
235
298
  />
236
299
  </div>
237
300
  );
238
- }
301
+ }
@@ -2,123 +2,102 @@
2
2
  to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/components/EditorContainer.tsx"
3
3
  unless_exists: true
4
4
  ---
5
+ import { getRevisionFromDate, useTimelineItems } from "@powerhousedao/common";
5
6
  import {
6
- useDriveContext,
7
- exportDocument,
8
- type User,
9
- type DriveEditorContext,
10
- } from "@powerhousedao/reactor-browser";
11
- import {
12
- type EditorContext,
13
- type DocumentModelModule,
14
- type EditorModule,
15
- type EditorProps,
16
- type PHDocument,
17
- } from "document-model";
18
- import {
7
+ DefaultEditorLoader,
19
8
  DocumentToolbar,
20
9
  RevisionHistory,
21
- DefaultEditorLoader,
22
10
  type TimelineItem,
23
11
  } from "@powerhousedao/design-system";
24
- import { useTimelineItems, getRevisionFromDate } from "@powerhousedao/common";
25
- import { useState, Suspense, type FC, useCallback } from "react";
26
-
27
- export interface EditorContainerProps {
28
- driveId: string;
29
- documentId: string;
30
- documentType: string;
31
- onClose: () => void;
32
- title: string;
33
- context: Omit<DriveEditorContext, "getDocumentRevision"> & Pick<EditorContext, "getDocumentRevision">;
34
- documentModelModule: DocumentModelModule<PHDocument>;
35
- editorModule: EditorModule;
36
- }
37
-
38
- export const EditorContainer: React.FC<EditorContainerProps> = (props) => {
39
- const {
40
- title,
41
- driveId,
42
- context,
43
- onClose,
44
- documentId,
45
- documentType,
46
- editorModule,
47
- documentModelModule,
48
- } = props;
12
+ import {
13
+ exportFile,
14
+ useEditorModuleById,
15
+ useSelectedDocument,
16
+ useSelectedDrive,
17
+ } from "@powerhousedao/reactor-browser";
18
+ import { Suspense, useCallback, useState } from "react";
49
19
 
50
- const [selectedTimelineItem, setSelectedTimelineItem] = useState<TimelineItem | null>(null);
20
+ /**
21
+ * Document editor container that wraps individual document editors.
22
+ * Handles document loading, toolbar, revision history, and dynamic editor loading.
23
+ * Customize toolbar actions and editor context here.
24
+ */
25
+ export const EditorContainer = (props: { handleClose: () => void }) => {
26
+ const { handleClose } = props;
27
+ // UI state for revision history and timeline
28
+ const [selectedTimelineItem, setSelectedTimelineItem] =
29
+ useState<TimelineItem | null>(null);
51
30
  const [showRevisionHistory, setShowRevisionHistory] = useState(false);
52
- const { useDocumentEditorProps } = useDriveContext();
53
-
54
- const user = context.user as User | undefined;
55
-
56
- const { dispatch, error, document } = useDocumentEditorProps({
57
- documentId,
58
- documentType,
59
- driveId,
60
- documentModelModule,
61
- user,
62
- });
63
-
31
+ const [selectedDocument, dispatch] = useSelectedDocument();
32
+ const [selectedDrive] = useSelectedDrive();
33
+ // Timeline data for revision history
64
34
  const timelineItems = useTimelineItems(
65
- documentId,
66
- document?.header.createdAtUtcIso,
67
- driveId,
35
+ selectedDocument?.header.id,
36
+ selectedDocument?.header.createdAtUtcIso,
37
+ selectedDrive?.header.id,
38
+ );
39
+ const editorModule = useEditorModuleById(
40
+ selectedDocument?.header.meta?.preferredEditor,
68
41
  );
69
42
 
43
+ // Document export functionality - customize export behavior here
70
44
  const onExport = useCallback(async () => {
71
- if (document) {
72
- const ext = documentModelModule.documentModel.extension;
73
- await exportDocument(document, title, ext);
45
+ if (selectedDocument) {
46
+ await exportFile(selectedDocument);
74
47
  }
75
- }, [document?.header.revision.global, document?.header.revision.local]);
48
+ }, [selectedDocument]);
76
49
 
50
+ // Loading state component
77
51
  const loadingContent = (
78
- <div className="flex-1 flex justify-center items-center h-full">
52
+ <div className="flex h-full flex-1 items-center justify-center">
79
53
  <DefaultEditorLoader />
80
54
  </div>
81
55
  );
82
56
 
83
- if (!document) return loadingContent;
57
+ if (!selectedDocument) return loadingContent;
84
58
 
85
- const EditorComponent = editorModule.Component as FC<EditorProps<PHDocument>>;
59
+ // Dynamically load the appropriate editor component for this document type
60
+ const EditorComponent = editorModule?.Component;
61
+ if (!EditorComponent) return loadingContent;
86
62
 
87
63
  return showRevisionHistory ? (
64
+ // Revision history view
88
65
  <RevisionHistory
89
- documentId={documentId}
90
- documentTitle={title}
91
- globalOperations={document.operations.global}
92
- key={documentId}
93
- localOperations={document.operations.local}
66
+ documentId={selectedDocument.header.id}
67
+ documentTitle={selectedDocument.header.name}
68
+ globalOperations={selectedDocument.operations.global}
69
+ key={selectedDocument.header.id}
70
+ localOperations={selectedDocument.operations.local}
94
71
  onClose={() => setShowRevisionHistory(false)}
95
72
  />
96
73
  ) : (
74
+ // Main editor view
97
75
  <Suspense fallback={loadingContent}>
76
+ {/* Document toolbar - customize available actions here */}
98
77
  <DocumentToolbar
99
- onClose={onClose}
78
+ onClose={handleClose}
100
79
  onExport={onExport}
101
80
  onShowRevisionHistory={() => setShowRevisionHistory(true)}
102
- onSwitchboardLinkClick={() => {}}
103
- title={title}
81
+ onSwitchboardLinkClick={() => {}} // Customize switchboard integration
82
+ title={selectedDocument.header.name}
104
83
  timelineButtonVisible={editorModule.config.timelineEnabled}
105
84
  timelineItems={timelineItems.data}
106
85
  onTimelineItemClick={setSelectedTimelineItem}
107
86
  />
87
+ {/* Dynamic editor component based on document type */}
108
88
  <EditorComponent
109
89
  context={{
110
- ...context,
111
90
  readMode: !!selectedTimelineItem,
112
91
  selectedTimelineRevision: getRevisionFromDate(
113
92
  selectedTimelineItem?.startDate,
114
93
  selectedTimelineItem?.endDate,
115
- document.operations.global,
94
+ selectedDocument.operations.global,
116
95
  ),
117
96
  }}
118
97
  dispatch={dispatch}
119
98
  document={document}
120
- error={error}
99
+ error={console.error}
121
100
  />
122
101
  </Suspense>
123
102
  );
124
- };
103
+ };