@powerhousedao/codegen 0.49.3-dev.0 → 0.49.3-dev.2

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.
@@ -11,17 +11,17 @@ import {
11
11
  type UiNode,
12
12
  } from "@powerhousedao/design-system";
13
13
  import { useCallback, useState, useRef, useEffect } from "react";
14
- import type { FileNode, Node } from "document-drive";
14
+ import type { FileNode, GetDocumentOptions, Node } from "document-drive";
15
15
  import { FileItemsGrid } from "./FileItemsGrid.js";
16
16
  import { FolderItemsGrid } from "./FolderItemsGrid.js";
17
17
  import { FolderTree } from "./FolderTree.js";
18
18
  import { useTransformedNodes } from "../hooks/useTransformedNodes.js";
19
19
  import { useSelectedFolderChildren } from "../hooks/useSelectedFolderChildren.js";
20
20
  import { EditorContainer } from "./EditorContainer.js";
21
- import type { EditorContext, DocumentModelModule } from "document-model";
21
+ import type { DocumentModelModule } from "document-model";
22
22
  import { CreateDocumentModal } from "@powerhousedao/design-system";
23
23
  import { CreateDocument } from "./CreateDocument.js";
24
- import { useDriveContext } from "@powerhousedao/reactor-browser";
24
+ import { type DriveEditorContext, useDriveContext } from "@powerhousedao/reactor-browser";
25
25
 
26
26
  interface DriveExplorerProps {
27
27
  driveId: string;
@@ -30,7 +30,7 @@ interface DriveExplorerProps {
30
30
  onDeleteNode: (nodeId: string) => void;
31
31
  renameNode: (nodeId: string, name: string) => void;
32
32
  onCopyNode: (nodeId: string, targetName: string, parentId?: string) => void;
33
- context: EditorContext;
33
+ context: DriveEditorContext;
34
34
  }
35
35
 
36
36
  export function DriveExplorer({
@@ -42,6 +42,8 @@ export function DriveExplorer({
42
42
  onCopyNode,
43
43
  context,
44
44
  }: DriveExplorerProps) {
45
+ const { getDocumentRevision } = context;
46
+
45
47
  const [selectedNodeId, setSelectedNodeId] = useState<string | undefined>();
46
48
  const [activeDocumentId, setActiveDocumentId] = useState<
47
49
  string | undefined
@@ -109,6 +111,14 @@ export function DriveExplorer({
109
111
  []
110
112
  );
111
113
 
114
+ const onGetDocumentRevision = useCallback(
115
+ (options?: GetDocumentOptions) => {
116
+ if (!activeDocumentId) return;
117
+ return getDocumentRevision?.(activeDocumentId, options);
118
+ },
119
+ [getDocumentRevision, activeDocumentId],
120
+ );
121
+
112
122
  const filteredDocumentModels = documentModels;
113
123
 
114
124
  // Transform nodes using the custom hook
@@ -150,7 +160,10 @@ export function DriveExplorer({
150
160
  <div className="flex-1 p-4 overflow-y-auto">
151
161
  {activeDocument ? (
152
162
  <EditorContainer
153
- context={context}
163
+ context={{
164
+ ...context,
165
+ getDocumentRevision: onGetDocumentRevision,
166
+ }}
154
167
  documentId={activeDocumentId!}
155
168
  documentType={activeDocument.documentType}
156
169
  driveId={driveId}
@@ -8,18 +8,21 @@ import {
8
8
  type User,
9
9
  } from "@powerhousedao/reactor-browser";
10
10
  import {
11
- documentModelDocumentModelModule,
11
+ documentModelDocumentModelModule,
12
+ type EditorModule,
12
13
  type DocumentModelModule,
13
14
  type EditorContext,
14
- type EditorProps,
15
15
  type PHDocument,
16
16
  } from "document-model";
17
17
  import {
18
18
  DocumentToolbar,
19
19
  RevisionHistory,
20
20
  DefaultEditorLoader,
21
+ type TimelineItem,
21
22
  } from "@powerhousedao/design-system";
23
+ import { useTimelineItems, getRevisionFromDate } from "@powerhousedao/common";
22
24
  import { useState, Suspense, type FC, useCallback, lazy } from "react";
25
+ import { useDocumentModel, useDocumentEditorModule } from "../hooks/useDocumentModels.js";
23
26
 
24
27
  export interface EditorContainerProps {
25
28
  driveId: string;
@@ -30,39 +33,22 @@ export interface EditorContainerProps {
30
33
  context: EditorContext;
31
34
  }
32
35
 
33
- const documentModelsMap = {
34
- [documentModelDocumentModelModule.documentModel.id]: documentModelDocumentModelModule,
35
- };
36
-
37
- const documentEditorMap = {
38
- [documentModelDocumentModelModule.documentModel.id]: lazy(() =>
39
- import('@powerhousedao/builder-tools/style.css').then(() =>
40
- import("@powerhousedao/builder-tools/document-model-editor").then((m) => ({
41
- default: m.documentModelEditorModule.Component,
42
- }))
43
- )
44
- ),
45
- } as const;
46
-
47
- function getDocumentModel(documentType: string) {
48
- return documentModelsMap[documentType];
49
- }
50
-
51
- function getDocumentEditor(documentType: string) {
52
- return documentEditorMap[documentType];
53
- }
54
-
55
36
  export const EditorContainer: React.FC<EditorContainerProps> = (props) => {
56
37
  const { driveId, documentId, documentType, onClose, title, context } = props;
57
38
 
39
+ const [selectedTimelineItem, setSelectedTimelineItem] = useState<TimelineItem | null>(null);
58
40
  const [showRevisionHistory, setShowRevisionHistory] = useState(false);
59
41
  const { useDocumentEditorProps } = useDriveContext();
42
+ const timelineItems = useTimelineItems(documentId);
43
+
60
44
  const user = context.user as User | undefined;
61
45
 
62
- const documentModelModule = getDocumentModel(
46
+ const documentModelModule = useDocumentModel(
63
47
  documentType,
64
48
  ) as DocumentModelModule<PHDocument>;
65
49
 
50
+ const { editorModule, isLoading } = useDocumentEditorModule(documentType);
51
+
66
52
  const { dispatch, error, document } = useDocumentEditorProps({
67
53
  documentId,
68
54
  documentType,
@@ -84,11 +70,9 @@ export const EditorContainer: React.FC<EditorContainerProps> = (props) => {
84
70
  </div>
85
71
  );
86
72
 
87
- if (!document) return loadingContent;
73
+ if (!document || isLoading) return loadingContent;
88
74
 
89
- const Editor = getDocumentEditor(documentType);
90
-
91
- if (!Editor) {
75
+ if (!editorModule) {
92
76
  console.error("No editor found for document type:", documentType);
93
77
  return (
94
78
  <div className="flex-1">
@@ -96,7 +80,9 @@ export const EditorContainer: React.FC<EditorContainerProps> = (props) => {
96
80
  </div>
97
81
  );
98
82
  }
99
- const EditorComponent = Editor as FC<EditorProps<PHDocument>>;
83
+
84
+ const moduleWithComponent = editorModule as EditorModule<PHDocument>;
85
+ const EditorComponent = moduleWithComponent.Component;
100
86
 
101
87
  return showRevisionHistory ? (
102
88
  <RevisionHistory
@@ -115,9 +101,20 @@ export const EditorContainer: React.FC<EditorContainerProps> = (props) => {
115
101
  onShowRevisionHistory={() => setShowRevisionHistory(true)}
116
102
  onSwitchboardLinkClick={() => {}}
117
103
  title={title}
104
+ timelineButtonVisible={moduleWithComponent.config.timelineEnabled}
105
+ timelineItems={timelineItems.data}
106
+ onTimelineItemClick={setSelectedTimelineItem}
118
107
  />
119
108
  <EditorComponent
120
- context={context}
109
+ context={{
110
+ ...context,
111
+ readMode: !!selectedTimelineItem,
112
+ selectedTimelineRevision: getRevisionFromDate(
113
+ selectedTimelineItem?.startDate,
114
+ selectedTimelineItem?.endDate,
115
+ document.operations.global,
116
+ ),
117
+ }}
121
118
  dispatch={dispatch}
122
119
  document={document}
123
120
  error={error}
@@ -0,0 +1,44 @@
1
+ ---
2
+ to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/document-models.ts"
3
+ unless_exists: true
4
+ ---
5
+ import { documentModelDocumentModelModule, type DocumentModelModule } from "document-model";
6
+ // Replace with your document model (you can support multiple document models)
7
+ // import { ToDo } from "../../document-models/index.js";
8
+
9
+ export const createLazyModuleLoader = <T,>(loader: () => Promise<T>) => {
10
+ let modulePromise: Promise<T> | null = null;
11
+ let loadedModule: T | null = null;
12
+
13
+ return () => {
14
+ if (loadedModule) return Promise.resolve(loadedModule);
15
+ if (!modulePromise) {
16
+ modulePromise = loader().then(module => {
17
+ loadedModule = module;
18
+ return module;
19
+ });
20
+ }
21
+ return modulePromise;
22
+ };
23
+ };
24
+
25
+ export const documentModelsMap: Record<string, DocumentModelModule<any>> = {
26
+ // Replace with your document model (you can support multiple document models)
27
+ // [ToDo.documentModel.id]: ToDo,
28
+ [documentModelDocumentModelModule.documentModel.id]:
29
+ documentModelDocumentModelModule,
30
+ };
31
+
32
+ export const documentEditorMap = {
33
+ // Replace with your document model editor (you can support multiple document models editors)
34
+ // [ToDo.documentModel.id]: createLazyModuleLoader(() =>
35
+ // import("../to-do-list/index.js").then(m => m.default)
36
+ // ),
37
+ [documentModelDocumentModelModule.documentModel.id]: createLazyModuleLoader(() =>
38
+ import("@powerhousedao/builder-tools/style.css").then(() =>
39
+ import("@powerhousedao/builder-tools/document-model-editor").then(
40
+ m => m.documentModelEditorModule
41
+ )
42
+ )
43
+ ),
44
+ } as const;
@@ -3,11 +3,13 @@ to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/editor.tsx"
3
3
  unless_exists: true
4
4
  ---
5
5
  import { type DriveEditorProps } from "@powerhousedao/reactor-browser";
6
+ import { AnalyticsProvider } from '@powerhousedao/reactor-browser/analytics/context';
6
7
  import { DriveContextProvider } from "@powerhousedao/reactor-browser/hooks/useDriveContext";
7
8
  import { type DocumentDriveDocument, addFolder, deleteNode, updateNode, generateNodesCopy, copyNode } from "document-drive";
8
9
  import { WagmiContext } from "@powerhousedao/design-system";
9
10
  import { DriveExplorer } from "./components/DriveExplorer.js";
10
11
  import { useCallback } from "react";
12
+ import { hashKey } from "document-model";
11
13
 
12
14
  export type IProps = DriveEditorProps<DocumentDriveDocument>;
13
15
 
@@ -67,10 +69,18 @@ export function BaseEditor(props: IProps) {
67
69
  }
68
70
 
69
71
  export default function Editor(props: IProps) {
72
+ const baseEditor = props.context.analyticsStore ? (
73
+ <AnalyticsProvider store={props.context.analyticsStore}>
74
+ <BaseEditor {...props} />
75
+ </AnalyticsProvider>
76
+ ) : (
77
+ <BaseEditor {...props} />
78
+ );
79
+
70
80
  return (
71
81
  <DriveContextProvider value={props.context}>
72
82
  <WagmiContext>
73
- <BaseEditor {...props} />
83
+ {baseEditor}
74
84
  </WagmiContext>
75
85
  </DriveContextProvider>
76
86
  );
@@ -0,0 +1,41 @@
1
+ ---
2
+ to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/hooks/useDocumentModels.ts"
3
+ unless_exists: true
4
+ ---
5
+ import { useState, useEffect } from 'react';
6
+ import { documentModelsMap, documentEditorMap } from "../document-models.js";
7
+ import { type DocumentModelModule } from "document-model";
8
+
9
+ export function useDocumentModel(documentType: string): DocumentModelModule<any> {
10
+ return documentModelsMap[documentType];
11
+ }
12
+
13
+ export function useDocumentEditorModule(documentType: string) {
14
+ const [editorModule, setEditorModule] = useState<unknown>(null);
15
+ const [isLoading, setIsLoading] = useState(false);
16
+ const [error, setError] = useState<Error | null>(null);
17
+
18
+ useEffect(() => {
19
+ const editorLoader = documentEditorMap[documentType];
20
+
21
+ if (editorLoader && !editorModule) {
22
+ setIsLoading(true);
23
+
24
+ editorLoader()
25
+ .then(module => {
26
+ setEditorModule(module);
27
+ setIsLoading(false);
28
+ })
29
+ .catch(err => {
30
+ setError(err instanceof Error ? err : new Error('Failed to load editor module'));
31
+ setIsLoading(false);
32
+ });
33
+ }
34
+ }, [documentType, editorModule]);
35
+
36
+ return {
37
+ editorModule,
38
+ isLoading,
39
+ error
40
+ };
41
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powerhousedao/codegen",
3
- "version": "0.49.3-dev.0",
3
+ "version": "0.49.3-dev.2",
4
4
  "license": "AGPL-3.0-only",
5
5
  "private": false,
6
6
  "type": "module",