@powerhousedao/codegen 5.0.0 → 5.0.1-staging.11

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 (179) hide show
  1. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/actions.esm.t +3 -3
  2. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/creators.esm.t +3 -2
  3. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/customUtils.esm.t +1 -1
  4. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/document-models.esm.t +14 -0
  5. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/document-schema.esm.t +56 -0
  6. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/document-type.esm.t +6 -0
  7. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/documentModel.esm.t +1 -1
  8. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/documentModelTest.esm.t +110 -15
  9. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/hooks.esm.t +49 -0
  10. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.esm.t +12 -4
  11. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/index.js +66 -7
  12. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/lib.esm.t +4 -2
  13. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/module.esm.t +22 -0
  14. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/ph-factories.esm.t +23 -23
  15. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/reducer.esm.t +16 -9
  16. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/root-utils.esm.t +11 -0
  17. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/rootActions.esm.t +13 -0
  18. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/rootIndex.esm.t +6 -26
  19. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/schema.esm.t +2 -2
  20. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/src-index.esm.t +5 -0
  21. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/types.esm.t +16 -16
  22. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/utils.esm.t +31 -10
  23. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/creators.esm.t +10 -5
  24. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/customTest.esm.t +13 -18
  25. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-module/index.js +15 -0
  26. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/index.js +99 -4
  27. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/resolvers.esm.t +21 -10
  28. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model-subgraph/schema.esm.t +4 -3
  29. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/CreateDocument.esm.t +25 -28
  30. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/DriveContents.esm.t +23 -0
  31. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/DriveExplorer.esm.t +4 -125
  32. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/EmptyState.esm.t +19 -0
  33. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/Files.esm.t +29 -0
  34. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/Folders.esm.t +28 -0
  35. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/components/NavigationBreadcrumbs.esm.t +14 -0
  36. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/config.esm.t +1 -0
  37. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/editor.esm.t +4 -1
  38. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/editors.esm.t +14 -0
  39. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/index.js +21 -3
  40. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/lib.esm.t +4 -2
  41. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/module.esm.t +15 -0
  42. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/edit-name.esm.t +78 -0
  43. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/editor.esm.t +6 -103
  44. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/editors.esm.t +14 -0
  45. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.js +71 -2
  46. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/lib.esm.t +4 -2
  47. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/module.esm.t +16 -0
  48. package/dist/src/codegen/.hygen/templates/powerhouse/utils.js +43 -0
  49. package/dist/src/codegen/__tests__/config.d.ts +2 -0
  50. package/dist/src/codegen/__tests__/config.d.ts.map +1 -0
  51. package/dist/src/codegen/__tests__/config.js +2 -0
  52. package/dist/src/codegen/__tests__/config.js.map +1 -0
  53. package/dist/src/codegen/__tests__/constants.d.ts +16 -0
  54. package/dist/src/codegen/__tests__/constants.d.ts.map +1 -0
  55. package/dist/src/codegen/__tests__/constants.js +16 -0
  56. package/dist/src/codegen/__tests__/constants.js.map +1 -0
  57. package/dist/src/codegen/__tests__/fixtures/expected-reducer-content-v3.d.ts +2 -0
  58. package/dist/src/codegen/__tests__/fixtures/expected-reducer-content-v3.d.ts.map +1 -0
  59. package/dist/src/codegen/__tests__/fixtures/expected-reducer-content-v3.js +9 -0
  60. package/dist/src/codegen/__tests__/fixtures/expected-reducer-content-v3.js.map +1 -0
  61. package/dist/src/codegen/__tests__/fixtures/expected-reducer-content.d.ts +3 -0
  62. package/dist/src/codegen/__tests__/fixtures/expected-reducer-content.d.ts.map +1 -0
  63. package/dist/src/codegen/__tests__/fixtures/expected-reducer-content.js +33 -0
  64. package/dist/src/codegen/__tests__/fixtures/expected-reducer-content.js.map +1 -0
  65. package/dist/src/codegen/__tests__/fixtures/run-generated-tests.d.ts +2 -0
  66. package/dist/src/codegen/__tests__/fixtures/run-generated-tests.d.ts.map +1 -0
  67. package/dist/src/codegen/__tests__/fixtures/run-generated-tests.js +23 -0
  68. package/dist/src/codegen/__tests__/fixtures/run-generated-tests.js.map +1 -0
  69. package/dist/src/codegen/__tests__/fixtures/typecheck.d.ts +2 -0
  70. package/dist/src/codegen/__tests__/fixtures/typecheck.d.ts.map +1 -0
  71. package/dist/src/codegen/__tests__/fixtures/typecheck.js +23 -0
  72. package/dist/src/codegen/__tests__/fixtures/typecheck.js.map +1 -0
  73. package/dist/src/codegen/__tests__/generate-doc-model.test.d.ts +2 -0
  74. package/dist/src/codegen/__tests__/generate-doc-model.test.d.ts.map +1 -0
  75. package/dist/src/codegen/__tests__/generate-doc-model.test.js +206 -0
  76. package/dist/src/codegen/__tests__/generate-doc-model.test.js.map +1 -0
  77. package/dist/src/codegen/__tests__/generate-drive-editor.test.d.ts +2 -0
  78. package/dist/src/codegen/__tests__/generate-drive-editor.test.d.ts.map +1 -0
  79. package/dist/src/codegen/__tests__/generate-drive-editor.test.js +153 -0
  80. package/dist/src/codegen/__tests__/generate-drive-editor.test.js.map +1 -0
  81. package/dist/src/codegen/__tests__/generate-editor.test.d.ts +2 -0
  82. package/dist/src/codegen/__tests__/generate-editor.test.d.ts.map +1 -0
  83. package/dist/src/codegen/__tests__/generate-editor.test.js +94 -0
  84. package/dist/src/codegen/__tests__/generate-editor.test.js.map +1 -0
  85. package/dist/src/codegen/__tests__/generate-manifest.test.d.ts +2 -0
  86. package/dist/src/codegen/__tests__/generate-manifest.test.d.ts.map +1 -0
  87. package/dist/src/codegen/__tests__/generate-manifest.test.js +192 -0
  88. package/dist/src/codegen/__tests__/generate-manifest.test.js.map +1 -0
  89. package/dist/src/codegen/__tests__/generate-schemas.test.d.ts +2 -0
  90. package/dist/src/codegen/__tests__/generate-schemas.test.d.ts.map +1 -0
  91. package/dist/src/codegen/__tests__/generate-schemas.test.js +143 -0
  92. package/dist/src/codegen/__tests__/generate-schemas.test.js.map +1 -0
  93. package/dist/src/codegen/__tests__/global-setup.d.ts +2 -0
  94. package/dist/src/codegen/__tests__/global-setup.d.ts.map +1 -0
  95. package/dist/src/codegen/__tests__/global-setup.js +21 -0
  96. package/dist/src/codegen/__tests__/global-setup.js.map +1 -0
  97. package/dist/src/codegen/__tests__/ts-morph-generator.test.d.ts +2 -0
  98. package/dist/src/codegen/__tests__/ts-morph-generator.test.d.ts.map +1 -0
  99. package/dist/src/codegen/__tests__/ts-morph-generator.test.js +72 -0
  100. package/dist/src/codegen/__tests__/ts-morph-generator.test.js.map +1 -0
  101. package/dist/src/codegen/__tests__/utils.d.ts +7 -0
  102. package/dist/src/codegen/__tests__/utils.d.ts.map +1 -0
  103. package/dist/src/codegen/__tests__/utils.js +52 -0
  104. package/dist/src/codegen/__tests__/utils.js.map +1 -0
  105. package/dist/src/codegen/generate.d.ts +2 -2
  106. package/dist/src/codegen/generate.d.ts.map +1 -1
  107. package/dist/src/codegen/generate.js +13 -10
  108. package/dist/src/codegen/generate.js.map +1 -1
  109. package/dist/src/codegen/graphql.js +1 -1
  110. package/dist/src/codegen/graphql.js.map +1 -1
  111. package/dist/src/codegen/hygen.d.ts +5 -7
  112. package/dist/src/codegen/hygen.d.ts.map +1 -1
  113. package/dist/src/codegen/hygen.js +51 -15
  114. package/dist/src/codegen/hygen.js.map +1 -1
  115. package/dist/src/create-lib/checkout-project.d.ts +13 -0
  116. package/dist/src/create-lib/checkout-project.d.ts.map +1 -0
  117. package/dist/src/create-lib/checkout-project.js +47 -0
  118. package/dist/src/create-lib/checkout-project.js.map +1 -0
  119. package/dist/src/create-lib/create-project.d.ts +9 -5
  120. package/dist/src/create-lib/create-project.d.ts.map +1 -1
  121. package/dist/src/create-lib/create-project.js +37 -45
  122. package/dist/src/create-lib/create-project.js.map +1 -1
  123. package/dist/src/create-lib/feature-flags.d.ts +4 -0
  124. package/dist/src/create-lib/feature-flags.d.ts.map +1 -0
  125. package/dist/src/create-lib/feature-flags.js +4 -0
  126. package/dist/src/create-lib/feature-flags.js.map +1 -0
  127. package/dist/src/create-lib/index.d.ts +1 -0
  128. package/dist/src/create-lib/index.d.ts.map +1 -1
  129. package/dist/src/create-lib/index.js +1 -0
  130. package/dist/src/create-lib/index.js.map +1 -1
  131. package/dist/src/create-lib/utils.d.ts +7 -0
  132. package/dist/src/create-lib/utils.d.ts.map +1 -0
  133. package/dist/src/create-lib/utils.js +28 -0
  134. package/dist/src/create-lib/utils.js.map +1 -0
  135. package/dist/src/ts-morph-generator/__tests__/ReducerGenerator.test.d.ts +2 -0
  136. package/dist/src/ts-morph-generator/__tests__/ReducerGenerator.test.d.ts.map +1 -0
  137. package/dist/src/ts-morph-generator/__tests__/ReducerGenerator.test.js +491 -0
  138. package/dist/src/ts-morph-generator/__tests__/ReducerGenerator.test.js.map +1 -0
  139. package/dist/src/ts-morph-generator/core/FileGenerator.d.ts +3 -1
  140. package/dist/src/ts-morph-generator/core/FileGenerator.d.ts.map +1 -1
  141. package/dist/src/ts-morph-generator/core/FileGenerator.js +3 -1
  142. package/dist/src/ts-morph-generator/core/FileGenerator.js.map +1 -1
  143. package/dist/src/ts-morph-generator/core/GenerationContext.d.ts +1 -0
  144. package/dist/src/ts-morph-generator/core/GenerationContext.d.ts.map +1 -1
  145. package/dist/src/ts-morph-generator/core/ReducerGenerator.d.ts.map +1 -1
  146. package/dist/src/ts-morph-generator/core/ReducerGenerator.js +14 -7
  147. package/dist/src/ts-morph-generator/core/ReducerGenerator.js.map +1 -1
  148. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.d.ts +2 -1
  149. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.d.ts.map +1 -1
  150. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.js +10 -3
  151. package/dist/src/ts-morph-generator/core/TSMorphCodeGenerator.js.map +1 -1
  152. package/dist/src/ts-morph-generator/utilities/DeclarationManager.d.ts +5 -0
  153. package/dist/src/ts-morph-generator/utilities/DeclarationManager.d.ts.map +1 -0
  154. package/dist/src/ts-morph-generator/utilities/DeclarationManager.js +10 -0
  155. package/dist/src/ts-morph-generator/utilities/DeclarationManager.js.map +1 -0
  156. package/dist/src/ts-morph-generator/utilities/ImportManager.d.ts +1 -0
  157. package/dist/src/ts-morph-generator/utilities/ImportManager.d.ts.map +1 -1
  158. package/dist/src/ts-morph-generator/utilities/ImportManager.js +13 -3
  159. package/dist/src/ts-morph-generator/utilities/ImportManager.js.map +1 -1
  160. package/dist/src/ts-morph-generator/utilities/index.d.ts +1 -0
  161. package/dist/src/ts-morph-generator/utilities/index.d.ts.map +1 -1
  162. package/dist/src/ts-morph-generator/utilities/index.js +1 -0
  163. package/dist/src/ts-morph-generator/utilities/index.js.map +1 -1
  164. package/dist/src/utils/validation.d.ts.map +1 -1
  165. package/dist/src/utils/validation.js +3 -4
  166. package/dist/src/utils/validation.js.map +1 -1
  167. package/dist/tsconfig.tsbuildinfo +1 -0
  168. package/dist/vitest.config.d.ts +3 -0
  169. package/dist/vitest.config.d.ts.map +1 -0
  170. package/dist/vitest.config.js +16 -0
  171. package/dist/vitest.config.js.map +1 -0
  172. package/package.json +13 -12
  173. package/dist/src/codegen/.hygen/templates/powerhouse/generate-document-model/lib.inject_export.esm.t +0 -7
  174. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/index.esm.t +0 -15
  175. package/dist/src/codegen/.hygen/templates/powerhouse/generate-drive-editor/lib.inject_export.esm.t +0 -7
  176. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/hooks.esm.t +0 -16
  177. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/index.esm.t +0 -15
  178. package/dist/src/codegen/.hygen/templates/powerhouse/generate-editor/lib.inject_export.esm.t +0 -7
  179. package/dist/tsconfig.lib.tsbuildinfo +0 -1
@@ -2,150 +2,29 @@
2
2
  to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/components/DriveExplorer.tsx"
3
3
  unless_exists: true
4
4
  ---
5
- import {
6
- Breadcrumbs,
7
- Button,
8
- FileItem,
9
- FolderItem,
10
- } 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
5
  import type { EditorProps } from "document-model";
21
- import { CreateDocument } from "./CreateDocument.js";
22
6
  import { FolderTree } from "./FolderTree.js";
7
+ import { DriveContents } from "./DriveContents.js";
23
8
 
24
9
  /**
25
10
  * Main drive explorer component with sidebar navigation and content area.
26
11
  * Layout: Left sidebar (folder tree) + Right content area (files/folders + document editor)
27
12
  */
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
-
13
+ export function DriveExplorer({ children }: EditorProps) {
61
14
  // if a document is selected then it's editor will be passed as children
62
15
  const showDocumentEditor = !!children;
63
16
 
64
- // === RENDER ===
65
17
  return (
66
18
  <div className="flex h-full">
67
- {/* === LEFT SIDEBAR: Folder and File Navigation === */}
68
- {/* Sidebar component manages its own width, styling, and overflow */}
69
19
  <FolderTree />
70
-
71
- {/* === RIGHT CONTENT AREA: Files/Folders or Document Editor === */}
72
20
  <div className="flex-1 overflow-y-auto p-4">
73
21
  {/* Conditional rendering: Document editor or folder contents */}
74
22
  {showDocumentEditor ? (
75
- // Document editor view
23
+ /* Document editor view */
76
24
  children
77
25
  ) : (
78
26
  /* 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>
27
+ <DriveContents />
149
28
  )}
150
29
  </div>
151
30
  </div>
@@ -0,0 +1,19 @@
1
+ ---
2
+ to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/components/EmptyState.tsx"
3
+ unless_exists: true
4
+ ---
5
+ import { useNodesInSelectedDriveOrFolder } from "@powerhousedao/reactor-browser";
6
+
7
+ /** Shows a message when the selected drive or folder is empty */
8
+ export function EmptyState() {
9
+ const nodes = useNodesInSelectedDriveOrFolder();
10
+ const hasNodes = nodes.length > 0;
11
+ if (hasNodes) return null;
12
+
13
+ return (
14
+ <div className="py-12 text-center text-gray-500">
15
+ <p className="text-lg">This folder is empty</p>
16
+ <p className="mt-2 text-sm">Create your first document or folder below</p>
17
+ </div>
18
+ );
19
+ }
@@ -0,0 +1,29 @@
1
+ ---
2
+ to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/components/Files.tsx"
3
+ unless_exists: true
4
+ ---
5
+ import { FileItem } from "@powerhousedao/design-system/connect";
6
+ import {
7
+ useNodesInSelectedDriveOrFolder,
8
+ isFileNodeKind,
9
+ } from "@powerhousedao/reactor-browser";
10
+
11
+ /** Shows the files in the selected drive or folder */
12
+ export function Files() {
13
+ const nodes = useNodesInSelectedDriveOrFolder();
14
+ const fileNodes = nodes.filter((n) => isFileNodeKind(n));
15
+ const hasFiles = fileNodes.length > 0;
16
+
17
+ if (!hasFiles) return null;
18
+
19
+ return (
20
+ <div>
21
+ <h3 className="mb-2 text-sm font-semibold text-gray-600">Documents</h3>
22
+ <div className="flex flex-wrap gap-4">
23
+ {fileNodes.map((fileNode) => (
24
+ <FileItem key={fileNode.id} fileNode={fileNode} />
25
+ ))}
26
+ </div>
27
+ </div>
28
+ );
29
+ }
@@ -0,0 +1,28 @@
1
+ ---
2
+ to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/components/Folders.tsx"
3
+ unless_exists: true
4
+ ---
5
+ import { FolderItem } from "@powerhousedao/design-system/connect";
6
+ import {
7
+ useNodesInSelectedDriveOrFolder,
8
+ isFolderNodeKind,
9
+ } from "@powerhousedao/reactor-browser";
10
+
11
+ /** Shows the folders in the selected drive or folder */
12
+ export function Folders() {
13
+ const nodes = useNodesInSelectedDriveOrFolder();
14
+ const folderNodes = nodes.filter((n) => isFolderNodeKind(n));
15
+ const hasFolders = folderNodes.length > 0;
16
+ if (!hasFolders) return null;
17
+
18
+ return (
19
+ <div>
20
+ <h3 className="mb-2 text-sm font-bold text-gray-600">Folders</h3>
21
+ <div className="flex flex-wrap gap-4">
22
+ {folderNodes.map((folderNode) => (
23
+ <FolderItem key={folderNode.id} folderNode={folderNode} />
24
+ ))}
25
+ </div>
26
+ </div>
27
+ );
28
+ }
@@ -0,0 +1,14 @@
1
+ ---
2
+ to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/components/NavigationBreadcrumbs.tsx"
3
+ unless_exists: true
4
+ ---
5
+ import { Breadcrumbs } from "@powerhousedao/design-system/connect";
6
+
7
+ /** Shows the navigation breadcrumbs for the selected drive or folder */
8
+ export function NavigationBreadcrumbs() {
9
+ return (
10
+ <div className="border-b border-gray-200 pb-3 space-y-3">
11
+ <Breadcrumbs />
12
+ </div>
13
+ );
14
+ }
@@ -4,6 +4,7 @@ unless_exists: true
4
4
  ---
5
5
  import type { PHDriveEditorConfig } from "@powerhousedao/reactor-browser";
6
6
 
7
+ /** Editor config for the <%= pascalCaseDriveEditorName %> */
7
8
  export const editorConfig: PHDriveEditorConfig = {
8
9
  isDragAndDropEnabled: <%- isDragAndDropEnabled %>,
9
10
  allowedDocumentTypes: <%- allowedDocumentTypes %>
@@ -7,7 +7,10 @@ import type { EditorProps } from "document-model";
7
7
  import { DriveExplorer } from "./components/DriveExplorer.js";
8
8
  import { editorConfig } from "./config.js";
9
9
 
10
- export function Editor(props: EditorProps) {
10
+ /** Editor component for the <%= pascalCaseDriveEditorName %> drive editor */
11
+ export default function Editor(props: EditorProps) {
12
+ // set the config for this drive editor
13
+ // you can update these configs in `./config.ts`
11
14
  useSetPHDriveEditorConfig(editorConfig);
12
15
  return (
13
16
  <DriveExplorer {...props} />
@@ -0,0 +1,14 @@
1
+ ---
2
+ force: true
3
+ to: "<%= rootDir %>/editors.ts"
4
+ ---
5
+ import type { EditorModule } from "document-model";
6
+ <% moduleExports.forEach(me => { _%>
7
+ import { <%= me.pascalCaseName %> } from "./<%= me.paramCaseName %>/module.js";
8
+ <% }); _%>
9
+
10
+ export const editors: EditorModule[] = [
11
+ <% moduleExports.forEach(me => { _%>
12
+ <%= me.pascalCaseName %>,
13
+ <% }); _%>
14
+ ]
@@ -1,12 +1,30 @@
1
+ const { pascalCase, paramCase } = require("change-case");
2
+ const { getModuleExports } = require("../utils.js");
3
+
1
4
  // @ts-check
2
5
  module.exports = {
3
6
  params: ({ args }) => {
7
+ const name = args.name;
8
+ const rootDir = args.rootDir;
9
+ const pascalCaseDriveEditorName = pascalCase(name);
10
+ const paramCaseDriveEditorName = paramCase(name);
11
+ const moduleExports = getModuleExports(
12
+ rootDir,
13
+ /export\s+const\s+(\w+)\s*:\s*EditorModule\s*=/,
14
+ {
15
+ paramCaseName: paramCaseDriveEditorName,
16
+ pascalCaseName: pascalCaseDriveEditorName,
17
+ }
18
+ );
4
19
  return {
5
- rootDir: args.rootDir,
20
+ rootDir,
21
+ moduleExports,
6
22
  name: args.name,
7
23
  appId: args.appId,
8
- isDragAndDropEnabled: args.isDragAndDropEnabled,
9
- allowedDocumentTypes: args.allowedDocumentTypes,
24
+ isDragAndDropEnabled: args.isDragAndDropEnabled,
25
+ allowedDocumentTypes: args.allowedDocumentTypes,
26
+ pascalCaseDriveEditorName,
27
+ paramCaseDriveEditorName,
10
28
  };
11
29
  },
12
30
  };
@@ -1,9 +1,11 @@
1
1
  ---
2
2
  to: "<%= rootDir %>/index.ts"
3
- unless_exists: true
3
+ force: true
4
4
  ---
5
5
  /**
6
6
  * This is a scaffold file meant for customization.
7
7
  * Delete the file and run the code generator again to have it reset
8
8
  */
9
-
9
+ <% moduleExports.forEach(me => { _%>
10
+ export { <%= me.pascalCaseName %> } from "./<%= me.paramCaseName %>/module.js";
11
+ <% }); _%>
@@ -0,0 +1,15 @@
1
+ ---
2
+ to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/module.ts"
3
+ force: true
4
+ ---
5
+ import { type EditorModule } from "document-model";
6
+ import { lazy } from "react";
7
+
8
+ export const <%= pascalCaseDriveEditorName %>: EditorModule = {
9
+ Component: lazy(() => import("./editor.js")),
10
+ documentTypes: ["powerhouse/document-drive"],
11
+ config: {
12
+ id: "<%= appId || paramCaseDriveEditorName %>",
13
+ name: "<%= name %>",
14
+ },
15
+ };
@@ -0,0 +1,78 @@
1
+ ---
2
+ to: "<%= rootDir %>/<%= paramCaseEditorName %>/components/EditName.tsx"
3
+ unless_exists: true
4
+ ---
5
+ import { setName } from "document-model";
6
+ import type { FormEventHandler, MouseEventHandler } from "react";
7
+ import { useState } from "react";
8
+ <% if(!documentType){ %>import { useSelectedDocument } from "@powerhousedao/reactor-browser";<% } else { %>import { <%= useSelectedHookName %> %>} from "<%= documentModelDir %>";<% } %>
9
+
10
+ /** Displays the name of the selected <%= pascalCaseDocumentType %> document and allows editing it */
11
+ export function <%= editNameComponentName %>() {
12
+ const [<%= documentVariableName %>, dispatch] = <%= useSelectedHookName %>();
13
+ const [isEditing, setIsEditing] = useState(false);
14
+
15
+ if (!<%= documentVariableName %>) return null;
16
+
17
+ const <%= documentVariableName %>Name = <%= documentVariableName %>.header.name;
18
+
19
+ const onClickEdit<%= pascalCaseDocumentType %>Name: MouseEventHandler<HTMLButtonElement> = () => {
20
+ setIsEditing(true);
21
+ };
22
+
23
+ const onClickCancelEdit<%= pascalCaseDocumentType %>Name: MouseEventHandler<
24
+ HTMLButtonElement
25
+ > = () => {
26
+ setIsEditing(false);
27
+ };
28
+
29
+ const onSubmitSetName: FormEventHandler<HTMLFormElement> = (event) => {
30
+ event.preventDefault();
31
+ const form = event.currentTarget;
32
+ const nameInput = form.elements.namedItem("name") as HTMLInputElement;
33
+ const name = nameInput.value;
34
+ if (!name) return;
35
+
36
+ dispatch(setName(name));
37
+ setIsEditing(false);
38
+ };
39
+
40
+ if (isEditing)
41
+ return (
42
+ <form
43
+ className="flex gap-2 items-center justify-between"
44
+ onSubmit={onSubmitSetName}
45
+ >
46
+ <input
47
+ className="text-lg font-semibold text-gray-900 p-1"
48
+ type="text"
49
+ name="name"
50
+ defaultValue={<%= documentVariableName %>Name}
51
+ autoFocus
52
+ />
53
+ <div className="flex gap-2">
54
+ <button type="submit" className="text-sm text-gray-600">
55
+ Save
56
+ </button>
57
+ <button
58
+ className="text-sm text-red-800"
59
+ onClick={onClickCancelEdit<%= pascalCaseDocumentType %>Name}
60
+ >
61
+ Cancel
62
+ </button>
63
+ </div>
64
+ </form>
65
+ );
66
+
67
+ return (
68
+ <div className="flex justify-between items-center">
69
+ <h2 className="text-lg font-semibold text-gray-900">{<%= documentVariableName %>Name}</h2>
70
+ <button
71
+ className="text-sm text-gray-600"
72
+ onClick={onClickEdit<%= pascalCaseDocumentType %>Name}
73
+ >
74
+ Edit Name
75
+ </button>
76
+ </div>
77
+ );
78
+ }
@@ -2,110 +2,13 @@
2
2
  to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/editor.tsx"
3
3
  unless_exists: true
4
4
  ---
5
- import { DocumentToolbar } from "@powerhousedao/design-system";
6
- import {
7
- Button,
8
- Form,
9
- FormLabel,
10
- StringField,
11
- } from "@powerhousedao/document-engineering";
12
- import {
13
- setSelectedNode,
14
- useParentFolderForSelectedNode,
15
- } from "@powerhousedao/reactor-browser";
16
- <% if(!documentType){ %>import { useSelectedDocument } from "@powerhousedao/reactor-browser";<% } else { %>import { useSelected<%= documentType.name %>Document %>} from "../hooks/use<%= documentType.name %>Document%>.js";<% } %>
17
- import { setName } from "document-model";<% if(documentType) { %>
18
- import { actions } from "<%= documentType.importPath %>";<% } %>
19
-
20
- export function Editor() {
21
- const [document, dispatch] = <% if(documentType) { %>useSelected<%= documentType.name %>Document()<% } else { %>useSelectedDocument()<% } %>;
22
-
23
- // Get the parent folder node for the currently selected node
24
- const parentFolder = useParentFolderForSelectedNode();
25
-
26
- <% if(!documentType){ %>
27
- if (!document) {
28
- return null;
29
- }
30
- <% } %>
31
- function handleSetName(values: { name: string }) {
32
- if (values.name) {
33
- dispatch(setName(values.name));
34
- }
35
- }
36
-
37
- // Set the selected node to the parent folder node (close the editor)
38
- function handleClose() {
39
- setSelectedNode(parentFolder?.id);
40
- }
5
+ import { <%= editNameComponentName %> } from "./components/EditName.js";
41
6
 
7
+ /** Implement your editor behavior here */
8
+ export default function Editor() {
42
9
  return (
43
- <div>
44
- <DocumentToolbar document={document} onClose={handleClose} />
45
- <div className="ph-default-styles py-10 text-center">
46
- <div className="inline-flex flex-col gap-10 text-start">
47
- {/* Edit document name form */}
48
- <section className="flex justify-between">
49
- <h1 className="text-start">{document.header.name}</h1>
50
- <div className="flex flex-col space-y-2">
51
- <Form
52
- onSubmit={handleSetName}
53
- defaultValues={{ name: document.header.name }}
54
- className="flex flex-col gap-3 pt-2"
55
- >
56
- <div className="flex items-end gap-3">
57
- <div>
58
- <FormLabel htmlFor="name">
59
- <b className="mb-1">Change document name</b>
60
- </FormLabel>
61
- <StringField
62
- name="name"
63
- placeholder="Enter document name"
64
- className="mt-1"
65
- />
66
- </div>
67
- <Button type="submit">Edit</Button>
68
- </div>
69
- </Form>
70
- </div>
71
- </section>
72
-
73
- {/* Document metadata */}
74
- <section>
75
- <ul className="grid grid-cols-2 gap-x-4 gap-y-1 text-gray-700">
76
- <li>
77
- <b className="mr-1">Id:</b>
78
- {document.header.id}
79
- </li>
80
- <li>
81
- <b className="mr-1">Created:</b>
82
- {new Date(document.header.createdAtUtcIso).toLocaleString()}
83
- </li>
84
- <li>
85
- <b className="mr-1">Type:</b>
86
- {document.header.documentType}
87
- </li>
88
- <li>
89
- <b className="mr-1">Last Modified:</b>
90
- {new Date(
91
- document.header.lastModifiedAtUtcIso,
92
- ).toLocaleString()}
93
- </li>
94
- </ul>
95
- </section>
96
-
97
- {/* Document state */}
98
- <section className="inline-block">
99
- <h2 className="mb-4">Document state</h2>
100
- <textarea
101
- rows={10}
102
- readOnly
103
- value={JSON.stringify(document.state, null, 2)}
104
- className="font-mono"
105
- ></textarea>
106
- </section>
107
- </div>
108
- </div>
10
+ <div className="py-4 px-8">
11
+ <<%= editNameComponentName %> />
109
12
  </div>
110
13
  );
111
- }
14
+ }
@@ -0,0 +1,14 @@
1
+ ---
2
+ force: true
3
+ to: "<%= rootDir %>/editors.ts"
4
+ ---
5
+ import type { EditorModule } from "document-model";
6
+ <% moduleExports.forEach(me => { _%>
7
+ import { <%= me.pascalCaseName %> } from "./<%= me.paramCaseName %>/module.js";
8
+ <% }); _%>
9
+
10
+ export const editors: EditorModule[] = [
11
+ <% moduleExports.forEach(me => { _%>
12
+ <%= me.pascalCaseName %>,
13
+ <% }); _%>
14
+ ]
@@ -1,6 +1,17 @@
1
+ const {
2
+ pascalCase,
3
+ paramCase,
4
+ capitalCase,
5
+ camelCase,
6
+ } = require("change-case");
7
+ const { readdirSync, readFileSync } = require("fs");
8
+ const { join } = require("path");
9
+ const { getModuleExports } = require("../utils.js");
10
+
1
11
  // @ts-check
2
12
  module.exports = {
3
13
  params: ({ args }) => {
14
+ const rootDir = args.rootDir;
4
15
  const documentTypes = args.documentTypes
5
16
  .split(",")
6
17
  .map((type) => type.trim())
@@ -13,17 +24,75 @@ module.exports = {
13
24
  const documentType = singleDocumentType
14
25
  ? { ...documentTypesMap[singleDocumentType], type: singleDocumentType }
15
26
  : undefined;
16
-
27
+ const packageName = args.packageName;
28
+ const pascalCaseEditorName = pascalCase(args.name);
29
+ const paramCaseEditorName = paramCase(args.name);
30
+ const pascalCaseDocumentType = pascalCase(documentType?.name);
31
+ const paramCaseDocumentType = paramCase(documentType?.name);
32
+ const camelCaseDocumentType = camelCase(documentType?.name);
33
+ const documentVariableName = documentType
34
+ ? `${camelCaseDocumentType}Document`
35
+ : "document";
36
+ const phDocumentTypeName = documentType
37
+ ? `${pascalCaseDocumentType}Document`
38
+ : "Document";
39
+ const actionTypeName = `${pascalCaseDocumentType}Action`;
40
+ const documentModelDir = `${packageName}/document-models/${paramCaseDocumentType}`;
41
+ const hooksDir = `${packageName}/editors/hooks`;
42
+ const isDocumentOfTypeFunctionName = `is${phDocumentTypeName}`;
43
+ const assertIsDocumentOfTypeFunctionName = `assertIs${phDocumentTypeName}`;
44
+ const useByIdHookName = documentType
45
+ ? `use${phDocumentTypeName}ById`
46
+ : "useDocumentById";
47
+ const useSelectedHookName = documentType
48
+ ? `useSelected${phDocumentTypeName}`
49
+ : "useSelectedDocument";
50
+ const useInSelectedDriveHookName = documentType
51
+ ? `use${phDocumentTypeName}sInSelectedDrive`
52
+ : "useDocumentsInSelectedDrive";
53
+ const useInSelectedFolderHookName = documentType
54
+ ? `use${phDocumentTypeName}sInSelectedFolder`
55
+ : "useDocumentsInSelectedFolder";
56
+ const editNameComponentName = documentType
57
+ ? `Edit${pascalCaseDocumentType}Name`
58
+ : "EditDocumentName";
59
+ const moduleExports = getModuleExports(
60
+ rootDir,
61
+ /export\s+const\s+(\w+)\s*:\s*EditorModule\s*=/,
62
+ {
63
+ paramCaseName: paramCaseEditorName,
64
+ pascalCaseName: pascalCaseEditorName,
65
+ }
66
+ );
17
67
  return {
18
- rootDir: args.rootDir,
68
+ rootDir,
69
+ moduleExports,
19
70
  documentModelsDir: args.documentModelsDir,
20
71
  name: args.name,
72
+ pascalCaseEditorName,
73
+ paramCaseEditorName,
74
+ pascalCaseDocumentType,
75
+ paramCaseDocumentType,
76
+ camelCaseDocumentType,
77
+ documentVariableName,
78
+ phDocumentTypeName,
79
+ actionTypeName,
80
+ hooksDir,
81
+ documentModelDir,
82
+ isDocumentOfTypeFunctionName,
83
+ assertIsDocumentOfTypeFunctionName,
84
+ useByIdHookName,
85
+ useSelectedHookName,
86
+ useInSelectedDriveHookName,
87
+ useInSelectedFolderHookName,
88
+ editNameComponentName,
21
89
  documentTypes: args.documentTypes
22
90
  .split(",")
23
91
  .filter((type) => type !== ""),
24
92
  documentTypesMap,
25
93
  editorId: args.editorId,
26
94
  documentType,
95
+ packageName,
27
96
  };
28
97
  },
29
98
  };
@@ -1,9 +1,11 @@
1
1
  ---
2
2
  to: "<%= rootDir %>/index.ts"
3
- unless_exists: true
3
+ force: true
4
4
  ---
5
5
  /**
6
6
  * This is a scaffold file meant for customization.
7
7
  * Delete the file and run the code generator again to have it reset
8
8
  */
9
-
9
+ <% moduleExports.forEach(me => { _%>
10
+ export { <%= me.pascalCaseName %> } from "./<%= me.paramCaseName %>/module.js";
11
+ <% }); _%>