@powerhousedao/academy 5.1.0-staging.0 → 5.1.0
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.
- package/CHANGELOG.md +46 -1148
- package/blog/BeyondCommunication-ABlueprintForDevelopment.md +1 -2
- package/blog/TheChallengeOfChange.md +0 -1
- package/docs/academy/00-EthereumArgentinaHackathon.md +207 -0
- package/docs/academy/01-GetStarted/00-ExploreDemoPackage.mdx +27 -24
- package/docs/academy/01-GetStarted/01-CreateNewPowerhouseProject.md +10 -155
- package/docs/academy/01-GetStarted/02-DefineToDoListDocumentModel.md +35 -122
- package/docs/academy/01-GetStarted/03-ImplementOperationReducers.md +155 -178
- package/docs/academy/01-GetStarted/04-BuildToDoListEditor.md +218 -0
- package/docs/academy/{02-MasteryTrack/01-BuilderEnvironment → 01-GetStarted}/05-VetraStudio.md +22 -62
- package/docs/academy/01-GetStarted/06-ReactorMCP.md +58 -0
- package/docs/academy/01-GetStarted/_04-BuildToDoListEditor +1 -1
- package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/03-BuilderTools.md +2 -2
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/02-SpecifyTheStateSchema.md +44 -75
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/03-SpecifyDocumentOperations.md +22 -28
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/04-UseTheDocumentModelGenerator.md +31 -28
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/05-ImplementDocumentReducers.md +206 -211
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/06-ImplementDocumentModelTests.md +62 -176
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/07-ExampleToDoListRepository.md +0 -21
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/01-BuildingDocumentEditors.md +319 -309
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/00-DocumentToolbar.mdx +0 -4
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/01-OperationHistory.md +0 -4
- package/docs/academy/02-MasteryTrack/05-Launch/04-ConfigureEnvironment.md +1 -1
- package/docs/academy/03-ExampleUsecases/Chatroom/02-CreateNewPowerhouseProject.md +35 -111
- package/docs/academy/03-ExampleUsecases/Chatroom/03-DefineChatroomDocumentModel.md +79 -195
- package/docs/academy/03-ExampleUsecases/Chatroom/04-ImplementOperationReducers.md +241 -435
- package/docs/academy/03-ExampleUsecases/Chatroom/05-ImplementChatroomEditor.md +27 -388
- package/docs/academy/03-ExampleUsecases/Chatroom/06-LaunchALocalReactor.md +7 -95
- package/docs/academy/03-ExampleUsecases/Chatroom/_category_.json +1 -1
- package/docs/academy/04-APIReferences/00-PowerhouseCLI.md +2 -6
- package/docs/academy/04-APIReferences/01-ReactHooks.md +501 -291
- package/docs/academy/05-Architecture/00-PowerhouseArchitecture.md +39 -7
- package/docs/academy/05-Architecture/02-ReferencingMonorepoPackages +65 -0
- package/docs/academy/05-Architecture/04-MovingBeyondCRUD +61 -0
- package/docs/academy/06-ComponentLibrary/00-DocumentEngineering.md +24 -72
- package/docs/academy/08-Glossary.md +0 -7
- package/docusaurus.config.ts +3 -28
- package/package.json +1 -1
- package/sidebars.ts +13 -49
- package/src/css/custom.css +18 -26
- package/docs/academy/01-GetStarted/04-WriteDocumentModelTests.md +0 -425
- package/docs/academy/01-GetStarted/05-BuildToDoListEditor.md +0 -557
- package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/images/Modules.png +0 -0
- package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/images/VetraStudioDrive.png +0 -0
- package/docs/academy/02-MasteryTrack/05-Launch/05-DockerDeployment.md +0 -384
- package/docs/academy/03-ExampleUsecases/TodoList/00-GetTheStarterCode.md +0 -24
- package/docs/academy/03-ExampleUsecases/TodoList/01-GenerateTodoListDocumentModel.md +0 -211
- package/docs/academy/03-ExampleUsecases/TodoList/02-ImplementTodoListDocumentModelReducerOperationHandlers.md +0 -171
- package/docs/academy/03-ExampleUsecases/TodoList/03-AddTestsForTodoListActions.md +0 -462
- package/docs/academy/03-ExampleUsecases/TodoList/04-GenerateTodoListDocumentEditor.md +0 -45
- package/docs/academy/03-ExampleUsecases/TodoList/05-ImplementTodoListDocumentEditorUIComponents.md +0 -422
- package/docs/academy/03-ExampleUsecases/TodoList/06-GenerateTodoDriveExplorer.md +0 -61
- package/docs/academy/03-ExampleUsecases/TodoList/07-AddSharedComponentForShowingTodoListStats.md +0 -384
- package/docs/academy/03-ExampleUsecases/TodoList/_category_.json +0 -8
- package/docs/academy/03-ExampleUsecases/VetraPackageLibrary/VetraPackageLibrary.md +0 -7
- package/docs/academy/03-ExampleUsecases/VetraPackageLibrary/_category_.json +0 -9
- package/docs/academy/04-APIReferences/06-VetraRemoteDrive.md +0 -160
- package/docs/academy/04-APIReferences/renown-sdk/00-Overview.md +0 -316
- package/docs/academy/04-APIReferences/renown-sdk/01-Authentication.md +0 -672
- package/docs/academy/04-APIReferences/renown-sdk/02-APIReference.md +0 -957
- package/docs/academy/04-APIReferences/renown-sdk/_category_.json +0 -8
- package/docs/academy/10-TodoListTutorial/02-ImplementTodoListDocumentModelReducerOperationHandlers.md +0 -171
- package/docs/academy/10-TodoListTutorial/03-AddTestsForTodoListActions.md +0 -462
- package/docs/academy/10-TodoListTutorial/05-ImplementTodoListDocumentEditorUIComponents.md +0 -422
- package/docs/academy/10-TodoListTutorial/07-AddSharedComponentForShowingTodoListStats.md +0 -370
- package/static/img/Vetra-logo-dark.svg +0 -11
- package/static/img/vetra-logo-light.svg +0 -11
- /package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/{02-RevisionHistoryTimeline/360/237/232/247" → 02-RevisionHistoryTimeline} +0 -0
- /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /01-WhatIsADocumentModel" → 01-WhatIsADocumentModel} +0 -0
- /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /02-DAOandDocumentsModelsQ+A" → 02-DAOandDocumentsModelsQ+A} +0 -0
- /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /02-domain-modeling" → 02-domain-modeling} +0 -0
- /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /03-BenefitsOfDocumentModels" → 03-BenefitsOfDocumentModels} +0 -0
- /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /04-UtilitiesAndTips" → 04-UtilitiesAndTips} +0 -0
- /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /05-best-practices" → 05-best-practices} +0 -0
- /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /_category_.json" → _category_.json} +0 -0
- /package/docs/academy/05-Architecture/05-DocumentModelTheory/{360/237/232/247 /three-data-layers.png" → three-data-layers.png} +0 -0
package/docs/academy/03-ExampleUsecases/TodoList/07-AddSharedComponentForShowingTodoListStats.md
DELETED
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
# Step 7 - Add shared component for showing TodoList stats
|
|
2
|
-
|
|
3
|
-
So far we've been creating components that live in the same directories as the editors that use them. But sometimes we want to use the same component across multiple editors.
|
|
4
|
-
|
|
5
|
-
Let's create a component for showing statistics about our todos. We'd like this component to work with any set of todos or todo lists, so that we can use the same one in our document editor or in our drive editor or a folder.
|
|
6
|
-
|
|
7
|
-
## Creating the `<Stats />` component
|
|
8
|
-
|
|
9
|
-
Create a new directory at `editors/components` and create two new files inside it:
|
|
10
|
-
|
|
11
|
-
`editors/components/Stats.tsx` with this content:
|
|
12
|
-
|
|
13
|
-
```jsx
|
|
14
|
-
import type {
|
|
15
|
-
TodoItem,
|
|
16
|
-
TodoListDocument,
|
|
17
|
-
} from "todo-tutorial/document-models/todo-list";
|
|
18
|
-
|
|
19
|
-
type Props = {
|
|
20
|
-
todos: TodoItem[] | undefined;
|
|
21
|
-
todoListDocuments?: TodoListDocument[] | undefined;
|
|
22
|
-
createdAtUtcIso?: string;
|
|
23
|
-
lastModifiedAtUtcIso?: string;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/** Generic component for showing statistics about todo lists and the todos they contain */
|
|
27
|
-
export function Stats({
|
|
28
|
-
todos,
|
|
29
|
-
todoListDocuments,
|
|
30
|
-
createdAtUtcIso,
|
|
31
|
-
lastModifiedAtUtcIso,
|
|
32
|
-
}: Props) {
|
|
33
|
-
const totalTodos = todos?.length ?? 0;
|
|
34
|
-
const totalChecked = todos?.filter((todo) => todo.checked).length ?? 0;
|
|
35
|
-
const totalUnchecked = todos?.filter((todo) => !todo.checked).length ?? 0;
|
|
36
|
-
const percentageChecked = Math.round(
|
|
37
|
-
calculatePercentage(totalTodos, totalChecked),
|
|
38
|
-
);
|
|
39
|
-
const percentageUnchecked = Math.round(
|
|
40
|
-
calculatePercentage(totalTodos, totalUnchecked),
|
|
41
|
-
);
|
|
42
|
-
const createdAt = createdAtUtcIso ? new Date(createdAtUtcIso) : null;
|
|
43
|
-
const hasCreatedAt = createdAt !== null;
|
|
44
|
-
const lastModified = lastModifiedAtUtcIso
|
|
45
|
-
? new Date(lastModifiedAtUtcIso)
|
|
46
|
-
: null;
|
|
47
|
-
const hasLastModified = lastModified !== null;
|
|
48
|
-
const createdAtFormattedDate = createdAt
|
|
49
|
-
? createdAt.toLocaleDateString()
|
|
50
|
-
: null;
|
|
51
|
-
const lastModifiedFormattedDate = lastModified
|
|
52
|
-
? lastModified.toLocaleDateString()
|
|
53
|
-
: null;
|
|
54
|
-
const createdAtFormattedTime = createdAt
|
|
55
|
-
? createdAt.toLocaleTimeString()
|
|
56
|
-
: null;
|
|
57
|
-
const lastModifiedFormattedTime = lastModified
|
|
58
|
-
? lastModified.toLocaleTimeString()
|
|
59
|
-
: null;
|
|
60
|
-
const totalTodoListDocuments = todoListDocuments?.length ?? 0;
|
|
61
|
-
const hasTodoLists = todoListDocuments !== undefined;
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<ul className="text-sm text-gray-800 max-w-1/2">
|
|
65
|
-
{hasTodoLists && (
|
|
66
|
-
<li className="flex justify-between">
|
|
67
|
-
<span>Todo Lists:</span> <span>{totalTodoListDocuments}</span>
|
|
68
|
-
</li>
|
|
69
|
-
)}
|
|
70
|
-
<li className="flex justify-between">
|
|
71
|
-
<span>Todos:</span> <span>{totalTodos}</span>
|
|
72
|
-
</li>
|
|
73
|
-
<li className="flex justify-between">
|
|
74
|
-
<span>Checked:</span>{" "}
|
|
75
|
-
<span>
|
|
76
|
-
{totalChecked} ({percentageChecked}%)
|
|
77
|
-
</span>
|
|
78
|
-
</li>
|
|
79
|
-
<li className="flex justify-between">
|
|
80
|
-
<span>Unchecked:</span>{" "}
|
|
81
|
-
<span>
|
|
82
|
-
{totalUnchecked} ({percentageUnchecked}%)
|
|
83
|
-
</span>
|
|
84
|
-
</li>
|
|
85
|
-
{hasCreatedAt && (
|
|
86
|
-
<li className="flex justify-between">
|
|
87
|
-
<span>Created:</span>{" "}
|
|
88
|
-
<span>
|
|
89
|
-
{createdAtFormattedDate} {createdAtFormattedTime}
|
|
90
|
-
</span>
|
|
91
|
-
</li>
|
|
92
|
-
)}
|
|
93
|
-
{hasLastModified && (
|
|
94
|
-
<li className="flex justify-between">
|
|
95
|
-
<span>Last modified:</span>{" "}
|
|
96
|
-
<span>
|
|
97
|
-
{lastModifiedFormattedDate} {lastModifiedFormattedTime}
|
|
98
|
-
</span>
|
|
99
|
-
</li>
|
|
100
|
-
)}
|
|
101
|
-
</ul>
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function calculatePercentage(total: unknown, value: unknown) {
|
|
106
|
-
if (typeof total !== "number" || typeof value !== "number") {
|
|
107
|
-
return 0;
|
|
108
|
-
}
|
|
109
|
-
const ratio = value / total;
|
|
110
|
-
if (isNaN(ratio)) {
|
|
111
|
-
return 0;
|
|
112
|
-
}
|
|
113
|
-
return ratio * 100;
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
And `editors/components/index.ts` with this content:
|
|
118
|
-
|
|
119
|
-
```ts
|
|
120
|
-
export { Stats } from "./Stats.js";
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
The index file lets us use a nice neat import path like `todo-tutorial/editors/components` in all of our editor components.
|
|
124
|
-
|
|
125
|
-
Don't be too concerned with the math and time related code you see here — those are just implementation details.
|
|
126
|
-
|
|
127
|
-
## Using the `<Stats />` component in our `TodoListEditor`
|
|
128
|
-
|
|
129
|
-
Now let's use the `<Stats />` component in our `<TodoList />` component:
|
|
130
|
-
|
|
131
|
-
```tsx
|
|
132
|
-
import { useSelectedTodoListDocument } from "todo-tutorial/document-models/todo-list";
|
|
133
|
-
// added-line
|
|
134
|
-
import { Stats } from "todo-tutorial/editors/components";
|
|
135
|
-
import { EditTodoListName } from "./EditName.js";
|
|
136
|
-
import { Todos } from "./Todos.js";
|
|
137
|
-
import { AddTodo } from "./AddTodo.js";
|
|
138
|
-
import { CloseButton } from "./CloseButton.js";
|
|
139
|
-
|
|
140
|
-
/** Displays the selected todo list */
|
|
141
|
-
export function TodoList() {
|
|
142
|
-
const [selectedTodoList] = useSelectedTodoListDocument();
|
|
143
|
-
|
|
144
|
-
if (!selectedTodoList) return null;
|
|
145
|
-
|
|
146
|
-
const todos = selectedTodoList.state.global.items;
|
|
147
|
-
// added-start
|
|
148
|
-
const createdAtUtcIso = selectedTodoList.header.createdAtUtcIso;
|
|
149
|
-
const lastModifiedAtUtcIso = selectedTodoList.header.lastModifiedAtUtcIso;
|
|
150
|
-
// added-end
|
|
151
|
-
|
|
152
|
-
return (
|
|
153
|
-
<div>
|
|
154
|
-
<section className="mb-4 flex gap-2 items-center">
|
|
155
|
-
<div className="grow">
|
|
156
|
-
<EditTodoListName />
|
|
157
|
-
</div>
|
|
158
|
-
<div className="flex-none">
|
|
159
|
-
<CloseButton />
|
|
160
|
-
</div>
|
|
161
|
-
</section>
|
|
162
|
-
// added-start
|
|
163
|
-
<section className="mb-4">
|
|
164
|
-
<Stats
|
|
165
|
-
todos={todos}
|
|
166
|
-
createdAtUtcIso={createdAtUtcIso}
|
|
167
|
-
lastModifiedAtUtcIso={lastModifiedAtUtcIso}
|
|
168
|
-
/>
|
|
169
|
-
</section>
|
|
170
|
-
// added-end
|
|
171
|
-
<section className="mb-4">
|
|
172
|
-
<Todos todos={todos} />
|
|
173
|
-
</section>
|
|
174
|
-
<section>
|
|
175
|
-
<AddTodo />
|
|
176
|
-
</section>
|
|
177
|
-
</div>
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
With this, you will now see statistics about the todo items in a todo list document.
|
|
183
|
-
|
|
184
|
-
And now we can also show off the flexibility of our new `<Stats />` component. Since drives are also just documents themselves, we can derive the same information about a drive too. This means we can use this same component in our drive editor as well.
|
|
185
|
-
|
|
186
|
-
## Using the `<Stats />` component in our `TodoDriveExplorer`
|
|
187
|
-
|
|
188
|
-
Let's add this to our `<DriveContents />` component, along with some conditional logic that either shows stats for the selected folder (if one is selected) or the selected drive otherwise.
|
|
189
|
-
|
|
190
|
-
```tsx
|
|
191
|
-
// added-start
|
|
192
|
-
import {
|
|
193
|
-
useSelectedDrive,
|
|
194
|
-
useSelectedFolder,
|
|
195
|
-
} from "@powerhousedao/reactor-browser";
|
|
196
|
-
// added-end
|
|
197
|
-
import { CreateDocument } from "./CreateDocument.js";
|
|
198
|
-
import { EmptyState } from "./EmptyState.js";
|
|
199
|
-
import { Files } from "./Files.js";
|
|
200
|
-
import { Folders } from "./Folders.js";
|
|
201
|
-
import { NavigationBreadcrumbs } from "./NavigationBreadcrumbs.js";
|
|
202
|
-
// added-start
|
|
203
|
-
import { Stats } from "todo-tutorial/editors/components";
|
|
204
|
-
import {
|
|
205
|
-
useTodoListDocumentsInSelectedDrive,
|
|
206
|
-
useTodoListDocumentsInSelectedFolder,
|
|
207
|
-
type TodoItem,
|
|
208
|
-
type TodoListDocument,
|
|
209
|
-
} from "todo-tutorial/document-models/todo-list";
|
|
210
|
-
|
|
211
|
-
/** Small helper function to get all todo items from all todo lists */
|
|
212
|
-
export function getAllTodoItemsFromTodoLists(
|
|
213
|
-
todoLists: TodoListDocument[] | undefined,
|
|
214
|
-
): TodoItem[] {
|
|
215
|
-
return todoLists?.flatMap((todoList) => todoList.state.global.items) ?? [];
|
|
216
|
-
}
|
|
217
|
-
// added-end
|
|
218
|
-
|
|
219
|
-
/** Shows the documents and folders in the selected drive */
|
|
220
|
-
export function DriveContents() {
|
|
221
|
-
// added-start
|
|
222
|
-
const selectedFolder = useSelectedFolder();
|
|
223
|
-
const hasSelectedFolder = selectedFolder !== undefined;
|
|
224
|
-
// added-end
|
|
225
|
-
return (
|
|
226
|
-
<div className="space-y-6 px-6">
|
|
227
|
-
<NavigationBreadcrumbs />
|
|
228
|
-
// added-line
|
|
229
|
-
{hasSelectedFolder ? <FolderStats /> : <DriveStats />}
|
|
230
|
-
<Folders />
|
|
231
|
-
<Files />
|
|
232
|
-
<EmptyState />
|
|
233
|
-
<CreateDocument />
|
|
234
|
-
</div>
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// added-start
|
|
239
|
-
/** Shows the statistics for the selected drive */
|
|
240
|
-
function DriveStats() {
|
|
241
|
-
const todoListDocumentsInSelectedDrive =
|
|
242
|
-
useTodoListDocumentsInSelectedDrive();
|
|
243
|
-
const allTodos = getAllTodoItemsFromTodoLists(
|
|
244
|
-
todoListDocumentsInSelectedDrive,
|
|
245
|
-
);
|
|
246
|
-
const [selectedDrive] = useSelectedDrive();
|
|
247
|
-
const driveCreatedAt = selectedDrive.header.createdAtUtcIso;
|
|
248
|
-
const driveLastModified = selectedDrive.header.lastModifiedAtUtcIso;
|
|
249
|
-
|
|
250
|
-
return (
|
|
251
|
-
<Stats
|
|
252
|
-
todos={allTodos}
|
|
253
|
-
todoListDocuments={todoListDocumentsInSelectedDrive}
|
|
254
|
-
createdAtUtcIso={driveCreatedAt}
|
|
255
|
-
lastModifiedAtUtcIso={driveLastModified}
|
|
256
|
-
/>
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/** Shows the statistics for the selected folder */
|
|
261
|
-
function FolderStats() {
|
|
262
|
-
const todoListDocumentsInSelectedFolder =
|
|
263
|
-
useTodoListDocumentsInSelectedFolder();
|
|
264
|
-
const allTodos = getAllTodoItemsFromTodoLists(
|
|
265
|
-
todoListDocumentsInSelectedFolder,
|
|
266
|
-
);
|
|
267
|
-
|
|
268
|
-
return (
|
|
269
|
-
<Stats
|
|
270
|
-
todos={allTodos}
|
|
271
|
-
todoListDocuments={todoListDocumentsInSelectedFolder}
|
|
272
|
-
/>
|
|
273
|
-
);
|
|
274
|
-
}
|
|
275
|
-
// added-end
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
The final result should look like this:
|
|
279
|
-
|
|
280
|
-
```jsx
|
|
281
|
-
import {
|
|
282
|
-
useSelectedDrive,
|
|
283
|
-
useSelectedFolder,
|
|
284
|
-
} from "@powerhousedao/reactor-browser";
|
|
285
|
-
import { CreateDocument } from "./CreateDocument.js";
|
|
286
|
-
import { EmptyState } from "./EmptyState.js";
|
|
287
|
-
import { Files } from "./Files.js";
|
|
288
|
-
import { Folders } from "./Folders.js";
|
|
289
|
-
import { NavigationBreadcrumbs } from "./NavigationBreadcrumbs.js";
|
|
290
|
-
import { Stats } from "todo-tutorial/editors/components";
|
|
291
|
-
import {
|
|
292
|
-
useTodoListDocumentsInSelectedDrive,
|
|
293
|
-
useTodoListDocumentsInSelectedFolder,
|
|
294
|
-
type TodoItem,
|
|
295
|
-
type TodoListDocument,
|
|
296
|
-
} from "todo-tutorial/document-models/todo-list";
|
|
297
|
-
|
|
298
|
-
/** Small helper function to get all todo items from all todo lists */
|
|
299
|
-
export function getAllTodoItemsFromTodoLists(
|
|
300
|
-
todoLists: TodoListDocument[] | undefined,
|
|
301
|
-
): TodoItem[] {
|
|
302
|
-
return todoLists?.flatMap((todoList) => todoList.state.global.items) ?? [];
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
/** Shows the documents and folders in the selected drive */
|
|
306
|
-
export function DriveContents() {
|
|
307
|
-
const selectedFolder = useSelectedFolder();
|
|
308
|
-
const hasSelectedFolder = selectedFolder !== undefined;
|
|
309
|
-
return (
|
|
310
|
-
<div className="space-y-6 px-6">
|
|
311
|
-
<NavigationBreadcrumbs />
|
|
312
|
-
{hasSelectedFolder ? <FolderStats /> : <DriveStats />}
|
|
313
|
-
<Folders />
|
|
314
|
-
<Files />
|
|
315
|
-
<EmptyState />
|
|
316
|
-
<CreateDocument />
|
|
317
|
-
</div>
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/** Shows the statistics for the selected drive */
|
|
322
|
-
function DriveStats() {
|
|
323
|
-
const todoListDocumentsInSelectedDrive =
|
|
324
|
-
useTodoListDocumentsInSelectedDrive();
|
|
325
|
-
const allTodos = getAllTodoItemsFromTodoLists(
|
|
326
|
-
todoListDocumentsInSelectedDrive,
|
|
327
|
-
);
|
|
328
|
-
const [selectedDrive] = useSelectedDrive();
|
|
329
|
-
const driveCreatedAt = selectedDrive.header.createdAtUtcIso;
|
|
330
|
-
const driveLastModified = selectedDrive.header.lastModifiedAtUtcIso;
|
|
331
|
-
|
|
332
|
-
return (
|
|
333
|
-
<Stats
|
|
334
|
-
todos={allTodos}
|
|
335
|
-
todoListDocuments={todoListDocumentsInSelectedDrive}
|
|
336
|
-
createdAtUtcIso={driveCreatedAt}
|
|
337
|
-
lastModifiedAtUtcIso={driveLastModified}
|
|
338
|
-
/>
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/** Shows the statistics for the selected folder */
|
|
343
|
-
function FolderStats() {
|
|
344
|
-
const todoListDocumentsInSelectedFolder =
|
|
345
|
-
useTodoListDocumentsInSelectedFolder();
|
|
346
|
-
const allTodos = getAllTodoItemsFromTodoLists(
|
|
347
|
-
todoListDocumentsInSelectedFolder,
|
|
348
|
-
);
|
|
349
|
-
|
|
350
|
-
return (
|
|
351
|
-
<Stats
|
|
352
|
-
todos={allTodos}
|
|
353
|
-
todoListDocuments={todoListDocumentsInSelectedFolder}
|
|
354
|
-
/>
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
With this update, you can now see the statistics for the todo lists and todo items for the selected drive, folder or document depending on which you select.
|
|
360
|
-
|
|
361
|
-
## Check your work
|
|
362
|
-
|
|
363
|
-
To make sure all works as expected, we should:
|
|
364
|
-
|
|
365
|
-
- check types
|
|
366
|
-
run: `pnpm tsc`
|
|
367
|
-
|
|
368
|
-
- check linting
|
|
369
|
-
run: `pnpm lint`
|
|
370
|
-
|
|
371
|
-
- check tests
|
|
372
|
-
run: `pnpm test`
|
|
373
|
-
|
|
374
|
-
- test in connect
|
|
375
|
-
run: `pnpm connect` — you should now be able to see the `<Stats />` component showing the data for your drives, folder and documents.
|
|
376
|
-
|
|
377
|
-
- make sure your code matches the code in the completed step branch
|
|
378
|
-
run: `git diff step-7-complete-added-shared-component-for-showing-todo-list-stats`
|
|
379
|
-
|
|
380
|
-
## The end
|
|
381
|
-
|
|
382
|
-
Congratulations! You now have a working `TodoList` document model, and editor for those documents, and a drive editor for managing those documents. This will make a good starting point for creating your own new implementations.
|
|
383
|
-
|
|
384
|
-
We're excited to see what you build!
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Vetra Package Library
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
The Vetra package library is your best source to explore packages built by different builder teams on the Powerhouse Vetra platform. Through the packages you'll find the GitHub repository with the source code of each package.
|
|
6
|
-
|
|
7
|
-
You can get access to the [package library here.](https://vetra.io/packages)
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
# Vetra Remote Drive
|
|
2
|
-
|
|
3
|
-
These commands enable collaborative development using Vetra remote drives. Instead of working with local drives only, you can connect your Powerhouse project to a remote drive that syncs across team members.
|
|
4
|
-
|
|
5
|
-
## Commands Overview
|
|
6
|
-
|
|
7
|
-
### `ph init --remote-drive`
|
|
8
|
-
|
|
9
|
-
**Purpose:** Create a new Powerhouse project and connect it to a remote Vetra drive.
|
|
10
|
-
|
|
11
|
-
**When to use:** You're starting a NEW project that will be shared via a remote drive.
|
|
12
|
-
|
|
13
|
-
**How it works:**
|
|
14
|
-
|
|
15
|
-
1. Validates the remote drive URL and checks that no GitHub URL is configured yet
|
|
16
|
-
2. Creates a standard Powerhouse project from the boilerplate
|
|
17
|
-
3. Adds Vetra configuration to `powerhouse.config.json`:
|
|
18
|
-
```json
|
|
19
|
-
{
|
|
20
|
-
"vetra": {
|
|
21
|
-
"driveId": "abc123",
|
|
22
|
-
"driveUrl": "https://vetra.example.com/d/abc123"
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
**Usage:**
|
|
28
|
-
```bash
|
|
29
|
-
ph init my-project --remote-drive https://vetra.example.com/d/abc123
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
**After initialization:**
|
|
33
|
-
- Create a GitHub repository
|
|
34
|
-
- Commit and push your code
|
|
35
|
-
- Run `ph vetra` to configure the GitHub URL in the remote drive
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
### `ph checkout --remote-drive`
|
|
40
|
-
|
|
41
|
-
**Purpose:** Clone an existing Powerhouse project that's already connected to a remote drive.
|
|
42
|
-
|
|
43
|
-
**When to use:** You're joining an EXISTING project that someone else initialized.
|
|
44
|
-
|
|
45
|
-
**How it works:**
|
|
46
|
-
|
|
47
|
-
1. Queries the remote drive to find the configured GitHub URL
|
|
48
|
-
2. Clones the repository from GitHub
|
|
49
|
-
3. Installs dependencies
|
|
50
|
-
4. The project is already configured to use the remote drive
|
|
51
|
-
|
|
52
|
-
**Usage:**
|
|
53
|
-
```bash
|
|
54
|
-
ph checkout --remote-drive https://vetra.example.com/d/abc123
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**Requirements:**
|
|
58
|
-
- The remote drive must have a GitHub URL configured (done during `ph vetra` after init)
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
### `ph vetra`
|
|
63
|
-
|
|
64
|
-
**Purpose:** Start the Vetra development environment with Switchboard and Connect Studio.
|
|
65
|
-
|
|
66
|
-
**When to use:** After initializing or checking out a project, to start development.
|
|
67
|
-
|
|
68
|
-
**How it works:**
|
|
69
|
-
|
|
70
|
-
1. Reads the remote drive URL from `powerhouse.config.json` (or `--remote-drive` flag)
|
|
71
|
-
2. Starts Switchboard connected to the remote drive (syncs automatically)
|
|
72
|
-
3. Prompts to configure GitHub URL if not set (first time after init)
|
|
73
|
-
4. Starts Connect Studio pointing to the drive(s)
|
|
74
|
-
|
|
75
|
-
**With `--watch` flag:**
|
|
76
|
-
- Creates a second "Vetra Preview" drive for testing local changes
|
|
77
|
-
- Dynamically loads your local document models and editors
|
|
78
|
-
- Main drive stays stable, preview drive for experimentation
|
|
79
|
-
|
|
80
|
-
**Usage:**
|
|
81
|
-
```bash
|
|
82
|
-
# Basic usage (uses config from powerhouse.config.json)
|
|
83
|
-
ph vetra
|
|
84
|
-
|
|
85
|
-
# With watch mode for development
|
|
86
|
-
ph vetra --watch
|
|
87
|
-
|
|
88
|
-
# Override remote drive URL
|
|
89
|
-
ph vetra --remote-drive https://vetra.example.com/d/abc123
|
|
90
|
-
|
|
91
|
-
# Disable Connect Studio
|
|
92
|
-
ph vetra --disable-connect
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**Key options:**
|
|
96
|
-
- `--watch` - Enable dynamic loading and create preview drive
|
|
97
|
-
- `--remote-drive <url>` - Specify remote drive URL
|
|
98
|
-
- `--switchboard-port <port>` - Custom Switchboard port (default: 4001)
|
|
99
|
-
- `--connect-port <port>` - Custom Connect Studio port (default: 3000)
|
|
100
|
-
- `--disable-connect` - Skip Connect Studio
|
|
101
|
-
- `--interactive` - Enable interactive mode for code generation
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
## Workflows
|
|
106
|
-
|
|
107
|
-
### Starting a New Project (Owner)
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
# 1. Initialize with remote drive
|
|
111
|
-
ph init my-project --remote-drive https://vetra.example.com/d/abc123
|
|
112
|
-
|
|
113
|
-
# 2. Create GitHub repo and push
|
|
114
|
-
cd my-project
|
|
115
|
-
git add .
|
|
116
|
-
git commit -m "Initial commit"
|
|
117
|
-
git remote add origin https://github.com/user/my-project.git
|
|
118
|
-
git push -u origin main
|
|
119
|
-
|
|
120
|
-
# 3. Start Vetra and configure GitHub URL
|
|
121
|
-
ph vetra
|
|
122
|
-
# (Select option to use detected GitHub URL when prompted)
|
|
123
|
-
|
|
124
|
-
# 4. Start developing with watch mode
|
|
125
|
-
ph vetra --watch
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Joining an Existing Project (Collaborator)
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
# 1. Checkout from remote drive
|
|
132
|
-
ph checkout --remote-drive https://vetra.example.com/d/abc123
|
|
133
|
-
|
|
134
|
-
# 2. Navigate to project
|
|
135
|
-
cd project-name
|
|
136
|
-
|
|
137
|
-
# 3. Start Vetra environment
|
|
138
|
-
ph vetra
|
|
139
|
-
|
|
140
|
-
# You're now synced with the remote drive
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## Key Concepts
|
|
146
|
-
|
|
147
|
-
**Remote Drive vs Local Drive:**
|
|
148
|
-
- Without remote drive: `ph vetra` creates a local drive on your machine only
|
|
149
|
-
- With remote drive: `ph vetra` connects to a shared drive that syncs across team members
|
|
150
|
-
|
|
151
|
-
**When to use each command:**
|
|
152
|
-
- Use `ph init --remote-drive` when starting a NEW project (no GitHub URL configured in drive yet)
|
|
153
|
-
- Use `ph checkout --remote-drive` when joining an EXISTING project (GitHub URL already configured)
|
|
154
|
-
- Use `ph vetra` to start development after either init or checkout
|
|
155
|
-
|
|
156
|
-
**Preview Drive (`--watch` mode):**
|
|
157
|
-
- Main "Vetra" drive: syncs with remote, contains stable package configuration
|
|
158
|
-
- "Vetra Preview" drive: created locally with `--watch`, for testing local document models
|
|
159
|
-
- Without `--watch`: safer, prevents untested code from affecting Connect
|
|
160
|
-
- With `--watch`: enables rapid development and testing
|