@powerhousedao/codegen 4.1.0-dev.9 → 4.1.0-dev.90

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 (164) 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 +4 -10
  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 +138 -223
  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 +7 -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 +103 -18
  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 +11 -15
  39. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/index.root.inject.esm.t +12 -0
  40. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/lib.esm.t +8 -6
  41. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/lib.inject_call.esm.t +1 -1
  42. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/lib.inject_import.esm.t +1 -1
  43. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/factory.esm.t +6 -5
  44. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.esm.t +6 -13
  45. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.js +11 -15
  46. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.root.inject.esm.t +12 -0
  47. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/lib.esm.t +8 -9
  48. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/lib.inject_call.esm.t +2 -2
  49. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/lib.inject_import.esm.t +1 -1
  50. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/migrations.esm.t +2 -2
  51. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/schema.esm.t +10 -2
  52. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.esm.t +5 -36
  53. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.js +9 -11
  54. package/dist/src/codegen/generate.d.ts +33 -0
  55. package/dist/src/codegen/generate.d.ts.map +1 -0
  56. package/dist/src/codegen/generate.js +202 -0
  57. package/dist/src/codegen/generate.js.map +1 -0
  58. package/dist/src/codegen/graphql.d.ts +2 -2
  59. package/dist/src/codegen/graphql.d.ts.map +1 -1
  60. package/dist/src/codegen/graphql.js +1 -1
  61. package/dist/src/codegen/graphql.js.map +1 -1
  62. package/dist/src/codegen/hygen.d.ts +18 -11
  63. package/dist/src/codegen/hygen.d.ts.map +1 -1
  64. package/dist/src/codegen/hygen.js +57 -21
  65. package/dist/src/codegen/hygen.js.map +1 -1
  66. package/dist/src/codegen/index.d.ts +6 -32
  67. package/dist/src/codegen/index.d.ts.map +1 -1
  68. package/dist/src/codegen/index.js +6 -182
  69. package/dist/src/codegen/index.js.map +1 -1
  70. package/dist/src/codegen/types.d.ts +9 -0
  71. package/dist/src/codegen/types.d.ts.map +1 -0
  72. package/dist/src/codegen/types.js +2 -0
  73. package/dist/src/codegen/types.js.map +1 -0
  74. package/dist/src/codegen/utils.d.ts +5 -2
  75. package/dist/src/codegen/utils.d.ts.map +1 -1
  76. package/dist/src/codegen/utils.js +42 -4
  77. package/dist/src/codegen/utils.js.map +1 -1
  78. package/dist/src/create-lib/create-project.d.ts.map +1 -1
  79. package/dist/src/create-lib/create-project.js +17 -2
  80. package/dist/src/create-lib/create-project.js.map +1 -1
  81. package/dist/src/index.d.ts +5 -0
  82. package/dist/src/index.d.ts.map +1 -0
  83. package/dist/src/index.js +5 -0
  84. package/dist/src/index.js.map +1 -0
  85. package/dist/src/ts-morph-generator/core/FileGenerator.d.ts +2 -3
  86. package/dist/src/ts-morph-generator/core/FileGenerator.d.ts.map +1 -1
  87. package/dist/src/ts-morph-generator/core/FileGenerator.js.map +1 -1
  88. package/dist/src/ts-morph-generator/core/GenerationContext.d.ts +18 -8
  89. package/dist/src/ts-morph-generator/core/GenerationContext.d.ts.map +1 -1
  90. package/dist/src/ts-morph-generator/core/ReducerGenerator.d.ts +12 -0
  91. package/dist/src/ts-morph-generator/core/ReducerGenerator.d.ts.map +1 -0
  92. package/dist/src/ts-morph-generator/core/ReducerGenerator.js +140 -0
  93. package/dist/src/ts-morph-generator/core/ReducerGenerator.js.map +1 -0
  94. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.d.ts +4 -3
  95. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.d.ts.map +1 -1
  96. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.js +11 -10
  97. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.js.map +1 -1
  98. package/dist/src/ts-morph-generator/index.d.ts +2 -2
  99. package/dist/src/ts-morph-generator/index.d.ts.map +1 -1
  100. package/dist/src/ts-morph-generator/index.js +2 -2
  101. package/dist/src/ts-morph-generator/index.js.map +1 -1
  102. package/dist/src/ts-morph-generator/utilities/DirectoryManager.d.ts +2 -2
  103. package/dist/src/ts-morph-generator/utilities/DirectoryManager.d.ts.map +1 -1
  104. package/dist/src/ts-morph-generator/utilities/ImportManager.d.ts +1 -1
  105. package/dist/src/ts-morph-generator/utilities/ImportManager.d.ts.map +1 -1
  106. package/dist/src/utils/index.d.ts +0 -1
  107. package/dist/src/utils/index.d.ts.map +1 -1
  108. package/dist/src/utils/index.js +0 -1
  109. package/dist/src/utils/index.js.map +1 -1
  110. package/dist/src/utils/validation.d.ts +6 -6
  111. package/dist/src/utils/validation.d.ts.map +1 -1
  112. package/dist/src/utils/validation.js +2 -2
  113. package/dist/src/utils/validation.js.map +1 -1
  114. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  115. package/package.json +25 -27
  116. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.d.ts +0 -25
  117. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.d.ts.map +0 -1
  118. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.js.map +0 -1
  119. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/object.esm.t +0 -49
  120. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.d.ts +0 -23
  121. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.d.ts.map +0 -1
  122. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.js.map +0 -1
  123. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/object.esm.t +0 -37
  124. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/index.d.ts +0 -22
  125. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/index.d.ts.map +0 -1
  126. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/index.js.map +0 -1
  127. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/EditorContainer.esm.t +0 -124
  128. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/FileItemsGrid.esm.t +0 -44
  129. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/FolderItemsGrid.esm.t +0 -96
  130. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/hooks/useSelectedFolderChildren.esm.t +0 -35
  131. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/hooks/useTransformedNodes.esm.t +0 -35
  132. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/types/css.d.esm.t +0 -8
  133. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.d.ts +0 -20
  134. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.d.ts.map +0 -1
  135. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.js.map +0 -1
  136. package/dist/src/codegen/.hygen/templates/powerhouse/generate-import-script/index.d.ts +0 -14
  137. package/dist/src/codegen/.hygen/templates/powerhouse/generate-import-script/index.d.ts.map +0 -1
  138. package/dist/src/codegen/.hygen/templates/powerhouse/generate-import-script/index.js.map +0 -1
  139. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/index.d.ts +0 -20
  140. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/index.d.ts.map +0 -1
  141. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-analytics/index.js.map +0 -1
  142. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.d.ts +0 -20
  143. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.d.ts.map +0 -1
  144. package/dist/src/codegen/.hygen/templates/powerhouse/generate-processor-relationalDb/index.js.map +0 -1
  145. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.d.ts +0 -16
  146. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.d.ts.map +0 -1
  147. package/dist/src/codegen/.hygen/templates/powerhouse/generate-subgraph/index.js.map +0 -1
  148. package/dist/src/ts-morph-generator/core/index.d.ts +0 -4
  149. package/dist/src/ts-morph-generator/core/index.d.ts.map +0 -1
  150. package/dist/src/ts-morph-generator/core/index.js +0 -4
  151. package/dist/src/ts-morph-generator/core/index.js.map +0 -1
  152. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.d.ts +0 -9
  153. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.d.ts.map +0 -1
  154. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.js +0 -69
  155. package/dist/src/ts-morph-generator/file-generators/ReducerGenerator.js.map +0 -1
  156. package/dist/src/ts-morph-generator/file-generators/index.d.ts +0 -2
  157. package/dist/src/ts-morph-generator/file-generators/index.d.ts.map +0 -1
  158. package/dist/src/ts-morph-generator/file-generators/index.js +0 -2
  159. package/dist/src/ts-morph-generator/file-generators/index.js.map +0 -1
  160. package/dist/src/utils/package-manager.d.ts +0 -5
  161. package/dist/src/utils/package-manager.d.ts.map +0 -1
  162. package/dist/src/utils/package-manager.js +0 -17
  163. package/dist/src/utils/package-manager.js.map +0 -1
  164. package/dist/tsconfig.hygen.tsbuildinfo +0 -1
@@ -3,236 +3,151 @@ 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,
12
10
  } 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";
11
+ import {
12
+ addFolder,
13
+ isFileNodeKind,
14
+ isFolderNodeKind,
15
+ useNodesInSelectedDriveOrFolder,
16
+ useSelectedDrive,
17
+ useSelectedFolder,
18
+ useUserPermissions,
19
+ } from "@powerhousedao/reactor-browser";
20
+ import type { EditorProps } from "document-model";
23
21
  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
- );
114
-
115
- const onGetDocumentRevision = useCallback(
116
- (options?: GetDocumentOptions) => {
117
- if (!activeDocumentId) return;
118
- return getDocumentRevision?.(activeDocumentId, options);
119
- },
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"
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;
22
+ import { FolderTree } from "./FolderTree.js";
155
23
 
24
+ /**
25
+ * Main drive explorer component with sidebar navigation and content area.
26
+ * Layout: Left sidebar (folder tree) + Right content area (files/folders + document editor)
27
+ */
28
+ export function DriveExplorer(props: EditorProps) {
29
+ const { children } = props;
30
+ const { isAllowedToCreateDocuments } = useUserPermissions();
31
+ const [selectedDrive] = useSelectedDrive(); // Currently selected drive
32
+ const selectedFolder = useSelectedFolder(); // Currently selected folder
33
+
34
+ const nodes = useNodesInSelectedDriveOrFolder();
35
+ const folderNodes = nodes.filter((n) => isFolderNodeKind(n));
36
+ const fileNodes = nodes.filter((n) => isFileNodeKind(n));
37
+
38
+ // Handle folder creation with optional name parameter
39
+ const handleCreateFolder = async (folderName?: string) => {
40
+ let name: string | undefined = folderName;
41
+
42
+ // If no name provided, prompt for it (for manual folder creation)
43
+ if (!name) {
44
+ const promptResult = prompt("Enter folder name:");
45
+ name = promptResult || undefined;
46
+ }
47
+
48
+ if (name?.trim()) {
49
+ try {
50
+ await addFolder(
51
+ selectedDrive.header.id,
52
+ name.trim(),
53
+ selectedFolder?.id,
54
+ );
55
+ } catch (error) {
56
+ console.error("Failed to create folder:", error);
57
+ }
58
+ }
59
+ };
60
+
61
+ // if a document is selected then it's editor will be passed as children
62
+ const showDocumentEditor = !!children;
63
+
64
+ // === RENDER ===
156
65
  return (
157
66
  <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
- />
67
+ {/* === LEFT SIDEBAR: Folder and File Navigation === */}
68
+ {/* Sidebar component manages its own width, styling, and overflow */}
69
+ <FolderTree />
70
+
71
+ {/* === RIGHT CONTENT AREA: Files/Folders or Document Editor === */}
72
+ <div className="flex-1 overflow-y-auto p-4">
73
+ {/* Conditional rendering: Document editor or folder contents */}
74
+ {showDocumentEditor ? (
75
+ // Document editor view
76
+ children
184
77
  ) : (
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
- </>
78
+ /* Folder contents view */
79
+ <div className="space-y-6 px-6">
80
+ {/* === HEADER SECTION === */}
81
+ <div className="space-y-3">
82
+ <div className="flex items-center justify-between">
83
+ {/* Folder title */}
84
+ <h2 className="text-lg font-semibold">
85
+ {selectedFolder
86
+ ? `Contents of "${selectedFolder.name}"`
87
+ : "Root Contents"}
88
+ </h2>
89
+ {/* Customize: Add more action buttons here */}
90
+ {isAllowedToCreateDocuments && (
91
+ <Button
92
+ onClick={() => handleCreateFolder()}
93
+ className="bg-gray-200 p-2 hover:bg-gray-300"
94
+ >
95
+ New Folder
96
+ </Button>
97
+ )}
98
+ </div>
99
+
100
+ {/* Navigation breadcrumbs */}
101
+ <div className="border-b border-gray-200 pb-3">
102
+ <Breadcrumbs />
103
+ </div>
104
+ </div>
105
+
106
+ {/* === FOLDERS SECTION === */}
107
+ {folderNodes.length > 0 && (
108
+ <div>
109
+ <h3 className="mb-2 text-sm font-bold text-gray-600">
110
+ Folders
111
+ </h3>
112
+ <div className="flex flex-wrap gap-4">
113
+ {folderNodes.map((folderNode) => (
114
+ <FolderItem key={folderNode.id} folderNode={folderNode} />
115
+ ))}
116
+ </div>
117
+ </div>
118
+ )}
119
+
120
+ {/* === FILES/DOCUMENTS SECTION === */}
121
+ {fileNodes.length > 0 && (
122
+ <div>
123
+ <h3 className="mb-2 text-sm font-semibold text-gray-600">
124
+ Documents
125
+ </h3>
126
+ <div className="flex flex-wrap gap-4">
127
+ {fileNodes.map((fileNode) => (
128
+ <FileItem key={fileNode.id} fileNode={fileNode} />
129
+ ))}
130
+ </div>
131
+ </div>
132
+ )}
133
+
134
+ {/* === EMPTY STATE === */}
135
+ {/* Customize empty state message and styling here */}
136
+ {folderNodes.length === 0 && fileNodes.length === 0 && (
137
+ <div className="py-12 text-center text-gray-500">
138
+ <p className="text-lg">This folder is empty</p>
139
+ <p className="mt-2 text-sm">
140
+ Create your first document or folder below
141
+ </p>
142
+ </div>
143
+ )}
144
+
145
+ {/* === DOCUMENT CREATION SECTION === */}
146
+ {/* Component for creating new documents */}
147
+ <CreateDocument />
148
+ </div>
227
149
  )}
228
150
  </div>
229
-
230
- {/* Create Document Modal */}
231
- <CreateDocumentModal
232
- onContinue={onCreateDocument}
233
- onOpenChange={(open) => setOpenModal(open)}
234
- open={openModal}
235
- />
236
151
  </div>
237
152
  );
238
- }
153
+ }
@@ -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
+ };
@@ -2,78 +2,14 @@
2
2
  to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/editor.tsx"
3
3
  unless_exists: true
4
4
  ---
5
- import { type DriveEditorProps } from "@powerhousedao/reactor-browser";
6
- import { AnalyticsProvider } from '@powerhousedao/reactor-browser/analytics/context';
7
- import { DriveContextProvider } from "@powerhousedao/reactor-browser/hooks/useDriveContext";
8
- import { type DocumentDriveDocument, addFolder, deleteNode, updateNode, generateNodesCopy, copyNode } from "document-drive";
9
- import { WagmiContext } from "@powerhousedao/design-system";
5
+ import { useSetPHDriveEditorConfig } from "@powerhousedao/reactor-browser";
6
+ import type { EditorProps } from "document-model";
10
7
  import { DriveExplorer } from "./components/DriveExplorer.js";
11
- import { useCallback } from "react";
12
- import { generateId } from "document-model";
8
+ import { editorConfig } from "./config.js";
13
9
 
14
- export type IProps = DriveEditorProps<DocumentDriveDocument>;
15
-
16
- export function BaseEditor(props: IProps) {
17
- const { dispatch, context } = props;
18
-
19
- const onAddFolder = useCallback((name: string, parentFolder?: string) => {
20
- dispatch(addFolder({
21
- id: generateId(),
22
- name,
23
- parentFolder,
24
- }));
25
- }, [dispatch]);
26
-
27
- const onDeleteNode = useCallback((nodeId: string) => {
28
- dispatch(deleteNode({ id: nodeId }));
29
- }, [dispatch]);
30
-
31
- const renameNode = useCallback((nodeId: string, name: string) => {
32
- dispatch(updateNode({ id: nodeId, name }));
33
- }, [dispatch]);
34
-
35
- const onCopyNode = useCallback((nodeId: string, targetName: string, parentId?: string) => {
36
- const copyNodesInput = generateNodesCopy({
37
- srcId: nodeId,
38
- targetParentFolder: parentId,
39
- targetName,
40
- }, () => generateId(), props.document.state.global.nodes);
41
-
42
- const copyNodesAction = copyNodesInput.map(input => {
43
- return copyNode(input);
44
- });
45
-
46
- for (const copyNodeAction of copyNodesAction) {
47
- dispatch(copyNodeAction);
48
- }
49
- }, [dispatch, props.document.state.global.nodes]);
50
-
51
- return (
52
- <div
53
- className="new-drive-explorer"
54
- style={{ height: "100%" }}
55
- >
56
- <DriveExplorer
57
- driveId={props.document.header.id}
58
- nodes={props.document.state.global.nodes}
59
- onAddFolder={onAddFolder}
60
- onDeleteNode={onDeleteNode}
61
- renameNode={renameNode}
62
- onCopyNode={onCopyNode}
63
- context={context}
64
- />
65
- </div>
66
- );
67
- }
68
-
69
- export default function Editor(props: IProps) {
10
+ export function Editor(props: EditorProps) {
11
+ useSetPHDriveEditorConfig(editorConfig);
70
12
  return (
71
- <DriveContextProvider value={props.context}>
72
- <WagmiContext>
73
- <AnalyticsProvider databaseName={props.context.analyticsDatabaseName}>
74
- <BaseEditor {...props} />
75
- </AnalyticsProvider>
76
- </WagmiContext>
77
- </DriveContextProvider>
13
+ <DriveExplorer {...props} />
78
14
  );
79
- }
15
+ }
@@ -2,19 +2,14 @@
2
2
  to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/index.ts"
3
3
  force: true
4
4
  ---
5
- import { type DriveEditorModule } from "@powerhousedao/reactor-browser";
6
- import { type DocumentDriveDocument } from "document-drive";
7
- import Editor from "./editor.js";
5
+ import { type EditorModule } from "document-model";
6
+ import { Editor } from "./editor.js";
8
7
 
9
- export const module: DriveEditorModule<DocumentDriveDocument> = {
8
+ export const module: EditorModule = {
10
9
  Component: Editor,
11
10
  documentTypes: ["powerhouse/document-drive"],
12
11
  config: {
13
- id: "<%= name %>",
14
- disableExternalControls: true,
15
- documentToolbarEnabled: true,
16
- showSwitchboardLink: true,
12
+ id: "<%= appId %>",
13
+ name: "<%= name %>",
17
14
  },
18
15
  };
19
-
20
- export default module;