@powerhousedao/academy 5.0.0-staging.9 → 5.0.1-staging.10
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/.vscode/settings.json +1 -1
- package/CHANGELOG.md +415 -0
- package/README.md +3 -3
- package/babel.config.js +1 -1
- package/blog/BeyondCommunication-ABlueprintForDevelopment.md +25 -24
- package/blog/TheChallengeOfChange.md +21 -21
- package/docs/academy/01-GetStarted/00-ExploreDemoPackage.mdx +67 -30
- package/docs/academy/01-GetStarted/01-CreateNewPowerhouseProject.md +38 -21
- package/docs/academy/01-GetStarted/02-DefineToDoListDocumentModel.md +24 -19
- package/docs/academy/01-GetStarted/03-ImplementOperationReducers.md +44 -41
- package/docs/academy/01-GetStarted/04-BuildToDoListEditor.md +10 -10
- package/docs/academy/01-GetStarted/05-VetraStudio.md +164 -0
- package/docs/academy/01-GetStarted/06-ReactorMCP.md +58 -0
- package/docs/academy/01-GetStarted/home.mdx +185 -90
- package/docs/academy/01-GetStarted/images/Modules.png +0 -0
- package/docs/academy/01-GetStarted/images/VetraStudioDrive.png +0 -0
- package/docs/academy/01-GetStarted/styles.module.css +5 -5
- package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/01-Prerequisites.md +46 -18
- package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/02-StandardDocumentModelWorkflow.md +118 -68
- package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/03-BuilderTools.md +75 -33
- package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/_category_.json +6 -6
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/01-WhatIsADocumentModel.md +30 -21
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/02-SpecifyTheStateSchema.md +41 -37
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/03-SpecifyDocumentOperations.md +29 -25
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/04-UseTheDocumentModelGenerator.md +36 -37
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/05-ImplementDocumentReducers.md +128 -109
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/06-ImplementDocumentModelTests.md +95 -86
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/07-ExampleToDoListRepository.md +7 -9
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/_category_.json +6 -6
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/01-BuildingDocumentEditors.md +65 -47
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/02-ConfiguringDrives.md +77 -62
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/03-BuildingADriveExplorer.md +360 -349
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/00-DocumentToolbar.mdx +16 -10
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/01-OperationHistory.md +10 -7
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/02-RevisionHistoryTimeline.md +25 -17
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/_category_.json +6 -6
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/07-Authorization/01-RenownAuthenticationFlow.md +14 -7
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/07-Authorization/02-Authorization.md +0 -1
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/07-Authorization/_category_.json +5 -5
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/_category_.json +1 -1
- package/docs/academy/02-MasteryTrack/04-WorkWithData/01-GraphQLAtPowerhouse.md +45 -33
- package/docs/academy/02-MasteryTrack/04-WorkWithData/02-UsingTheAPI.mdx +61 -18
- package/docs/academy/02-MasteryTrack/04-WorkWithData/03-UsingSubgraphs.md +50 -54
- package/docs/academy/02-MasteryTrack/04-WorkWithData/04-analytics-processor.md +126 -110
- package/docs/academy/02-MasteryTrack/04-WorkWithData/05-RelationalDbProcessor.md +75 -45
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/GraphQL References/QueryingADocumentWithGraphQL.md +23 -21
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/best-practices.md +9 -9
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/graphql/index.md +11 -23
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/graphql/integration.md +25 -9
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/intro.md +10 -10
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/typescript/benchmarks.md +1 -1
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/typescript/index.md +16 -11
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/typescript/memory.md +6 -5
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/typescript/schema.md +2 -2
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/typescript/utilities.md +7 -5
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/use-cases/maker.md +32 -58
- package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/use-cases/processors.md +1 -1
- package/docs/academy/02-MasteryTrack/04-WorkWithData/07-drive-analytics.md +105 -71
- package/docs/academy/02-MasteryTrack/04-WorkWithData/_ARCHIVE-AnalyticsProcessorTutorial/_01-SetupBuilderEnvironment.md +22 -0
- package/docs/academy/02-MasteryTrack/04-WorkWithData/_ARCHIVE-AnalyticsProcessorTutorial/_02-CreateNewPowerhouseProject.md +9 -8
- package/docs/academy/02-MasteryTrack/04-WorkWithData/_ARCHIVE-AnalyticsProcessorTutorial/_03-GenerateAnAnalyticsProcessor.md +28 -32
- package/docs/academy/02-MasteryTrack/04-WorkWithData/_ARCHIVE-AnalyticsProcessorTutorial/_04-UpdateAnalyticsProcessor.md +25 -26
- package/docs/academy/02-MasteryTrack/04-WorkWithData/_ARCHIVE-AnalyticsProcessorTutorial/_category_.json +1 -1
- package/docs/academy/02-MasteryTrack/04-WorkWithData/_category_.json +7 -7
- package/docs/academy/02-MasteryTrack/05-Launch/01-IntroductionToPackages.md +3 -4
- package/docs/academy/02-MasteryTrack/05-Launch/02-PublishYourProject.md +69 -45
- package/docs/academy/02-MasteryTrack/05-Launch/03-SetupEnvironment.md +70 -40
- package/docs/academy/02-MasteryTrack/05-Launch/04-ConfigureEnvironment.md +1 -0
- package/docs/academy/02-MasteryTrack/05-Launch/_category_.json +7 -7
- package/docs/academy/02-MasteryTrack/_category_.json +6 -6
- package/docs/academy/03-ExampleUsecases/Chatroom/02-CreateNewPowerhouseProject.md +5 -3
- package/docs/academy/03-ExampleUsecases/Chatroom/03-DefineChatroomDocumentModel.md +38 -37
- package/docs/academy/03-ExampleUsecases/Chatroom/04-ImplementOperationReducers.md +45 -41
- package/docs/academy/03-ExampleUsecases/Chatroom/05-ImplementChatroomEditor.md +14 -14
- package/docs/academy/03-ExampleUsecases/Chatroom/06-LaunchALocalReactor.md +6 -6
- package/docs/academy/03-ExampleUsecases/Chatroom/_category_.json +1 -1
- package/docs/academy/04-APIReferences/00-PowerhouseCLI.md +143 -48
- package/docs/academy/04-APIReferences/01-ReactHooks.md +177 -129
- package/docs/academy/04-APIReferences/04-RelationalDatabase.md +121 -113
- package/docs/academy/04-APIReferences/05-PHDocumentMigrationGuide.md +48 -41
- package/docs/academy/04-APIReferences/_category_.json +6 -6
- package/docs/academy/05-Architecture/00-PowerhouseArchitecture.md +1 -2
- package/docs/academy/05-Architecture/01-WorkingWithTheReactor.md +11 -8
- package/docs/academy/05-Architecture/05-DocumentModelTheory/_category_.json +1 -1
- package/docs/academy/05-Architecture/_category_.json +6 -6
- package/docs/academy/06-ComponentLibrary/00-DocumentEngineering.md +25 -23
- package/docs/academy/06-ComponentLibrary/02-CreateCustomScalars.md +105 -93
- package/docs/academy/06-ComponentLibrary/03-IntegrateIntoAReactComponent.md +1 -0
- package/docs/academy/06-ComponentLibrary/_category_.json +7 -7
- package/docs/academy/07-Cookbook.md +268 -35
- package/docs/academy/08-Glossary.md +7 -1
- package/docs/bookofpowerhouse/01-Overview.md +2 -2
- package/docs/bookofpowerhouse/02-GeneralFrameworkAndPhilosophy.md +1 -7
- package/docs/bookofpowerhouse/03-PowerhouseSoftwareArchitecture.md +10 -7
- package/docs/bookofpowerhouse/04-DevelopmentApproaches.md +10 -4
- package/docs/bookofpowerhouse/05-SNOsandANewModelForOSSandPublicGoods.md +23 -30
- package/docs/bookofpowerhouse/06-SNOsInActionAndPlatformEconomies.md +0 -7
- package/docusaurus.config.ts +64 -66
- package/package.json +9 -7
- package/scripts/generate-combined-cli-docs.ts +43 -13
- package/sidebars.ts +2 -0
- package/src/components/HomepageFeatures/index.tsx +171 -78
- package/src/components/HomepageFeatures/styles.module.css +1 -2
- package/src/css/custom.css +89 -89
- package/src/pages/_archive-homepage.tsx +17 -16
- package/src/theme/DocCardList/index.tsx +9 -8
- package/static.json +6 -6
- package/tsconfig.tsbuildinfo +1 -0
package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/06-ImplementDocumentModelTests.md
CHANGED
|
@@ -22,77 +22,85 @@ With the reducer logic in place, it's critical to test it. Navigate to the gener
|
|
|
22
22
|
This suite tests each operation, verifying not only that the `items` array is correct, but also that our `stats` object is updated as expected and that the operation itself is recorded properly in the document's history.
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
|
-
import utils from
|
|
26
|
-
import { reducer } from
|
|
27
|
-
import * as creators from
|
|
28
|
-
import { ToDoListDocument } from
|
|
29
|
-
|
|
30
|
-
describe(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
25
|
+
import utils from "../../gen/utils.js";
|
|
26
|
+
import { reducer } from "../../gen/reducer.js";
|
|
27
|
+
import * as creators from "../../gen/creators.js";
|
|
28
|
+
import { ToDoListDocument } from "../../gen/types.js";
|
|
29
|
+
|
|
30
|
+
describe("Todolist Operations", () => {
|
|
31
|
+
let document: ToDoListDocument;
|
|
32
|
+
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
// REMARKS: We start with a fresh, empty document for each test.
|
|
35
|
+
// The `createDocument` utility initializes the state with an empty 'items' array
|
|
36
|
+
// and a 'stats' object with all counts set to 0.
|
|
37
|
+
document = utils.createDocument();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should handle addTodoItem operation", () => {
|
|
41
|
+
const input = { id: "1", text: "Buy milk" };
|
|
42
|
+
|
|
43
|
+
// REMARKS: We apply the 'addTodoItem' operation.
|
|
44
|
+
const updatedDocument = reducer(document, creators.addTodoItem(input));
|
|
45
|
+
|
|
46
|
+
// REMARKS: We verify the operation was recorded in the document's history.
|
|
47
|
+
// Powerhouse records every operation in an array.
|
|
48
|
+
expect(updatedDocument.operations.global).toHaveLength(1);
|
|
49
|
+
expect(updatedDocument.operations.global[0].type).toBe("ADD_TODO_ITEM");
|
|
50
|
+
// REMARKS: We also check that the input data and index are recorded correctly.
|
|
51
|
+
expect(updatedDocument.operations.global[0].input).toStrictEqual(input);
|
|
52
|
+
expect(updatedDocument.operations.global[0].index).toEqual(0);
|
|
53
|
+
|
|
54
|
+
// REMARKS: Finally, we verify the state was updated according to our reducer logic.
|
|
55
|
+
expect(updatedDocument.state.global.items).toHaveLength(1);
|
|
56
|
+
expect(updatedDocument.state.global.stats.total).toBe(1);
|
|
57
|
+
expect(updatedDocument.state.global.stats.unchecked).toBe(1);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should handle updateTodoItem operation", () => {
|
|
61
|
+
// REMARKS: For an update, we first need to add an item.
|
|
62
|
+
const addInput = { id: "1", text: "Buy milk" };
|
|
63
|
+
const updateInput = { id: "1", checked: true }; // We'll test checking the item.
|
|
64
|
+
|
|
65
|
+
// REMARKS: Operations are applied sequentially to build up document state.
|
|
66
|
+
const createdDocument = reducer(document, creators.addTodoItem(addInput));
|
|
67
|
+
const updatedDocument = reducer(
|
|
68
|
+
createdDocument,
|
|
69
|
+
creators.updateTodoItem(updateInput),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// REMARKS: Now we should have 2 operations in the history.
|
|
73
|
+
expect(updatedDocument.operations.global).toHaveLength(2);
|
|
74
|
+
expect(updatedDocument.operations.global[1].type).toBe("UPDATE_TODO_ITEM");
|
|
75
|
+
expect(updatedDocument.operations.global[1].input).toStrictEqual(
|
|
76
|
+
updateInput,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// REMARKS: We check that the state reflects the update, including our stats.
|
|
80
|
+
expect(updatedDocument.state.global.items[0].checked).toBe(true);
|
|
81
|
+
expect(updatedDocument.state.global.stats.total).toBe(1);
|
|
82
|
+
expect(updatedDocument.state.global.stats.unchecked).toBe(0);
|
|
83
|
+
expect(updatedDocument.state.global.stats.checked).toBe(1);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should handle deleteTodoItem operation", () => {
|
|
87
|
+
const addInput = { id: "1", text: "Buy milk" };
|
|
88
|
+
const deleteInput = { id: "1" };
|
|
89
|
+
|
|
90
|
+
const createdDocument = reducer(document, creators.addTodoItem(addInput));
|
|
91
|
+
const updatedDocument = reducer(
|
|
92
|
+
createdDocument,
|
|
93
|
+
creators.deleteTodoItem(deleteInput),
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// REMARKS: After deletion, we still have 2 operations in history,
|
|
97
|
+
// but the items array is now empty and the stats are back to zero.
|
|
98
|
+
expect(updatedDocument.operations.global).toHaveLength(2);
|
|
99
|
+
expect(updatedDocument.operations.global[1].type).toBe("DELETE_TODO_ITEM");
|
|
100
|
+
expect(updatedDocument.state.global.items).toHaveLength(0);
|
|
101
|
+
expect(updatedDocument.state.global.stats.total).toBe(0);
|
|
102
|
+
expect(updatedDocument.state.global.stats.unchecked).toBe(0);
|
|
103
|
+
});
|
|
96
104
|
});
|
|
97
105
|
```
|
|
98
106
|
|
|
@@ -112,28 +120,29 @@ If all tests pass, you have successfully verified the core logic of your `To-do
|
|
|
112
120
|
|
|
113
121
|
While the tutorial provides a concrete example, keep these general best practices in mind when writing your tests:
|
|
114
122
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
- **Isolate Tests**: Each `it` block should ideally test one specific aspect or scenario. `beforeEach` is crucial for resetting state between tests.
|
|
124
|
+
- **Descriptive Names**: Name your `describe` and `it` blocks clearly so they explain what's being tested.
|
|
125
|
+
- **AAA Pattern (Arrange, Act, Assert)**:
|
|
126
|
+
- **Arrange**: Set up the initial state and any required test data (e.g., using `utils.createDocument()` and defining `input` objects).
|
|
127
|
+
- **Act**: Execute the operation by calling the `reducer` with an action from a `creator`.
|
|
128
|
+
- **Assert**: Check if the outcome is as expected using `expect()`.
|
|
129
|
+
- **Test Immutability**: A key assertion is to ensure the state is not mutated directly. You can check that a new array or object was created: `expect(newState.items).not.toBe(oldState.items);`.
|
|
130
|
+
- **Cover Edge Cases**: Test what happens when an operation receives invalid input (e.g., trying to update an item that doesn't exist). Your test should confirm the reducer either throws an error or returns the state unchanged, depending on your implementation.
|
|
131
|
+
- **Run Tests Frequently**: Integrate testing into your development workflow. Run tests after making changes to ensure you haven't broken anything. The `pnpm run test` command is your friend.
|
|
124
132
|
|
|
125
133
|
## Conclusion: The payoff of diligent testing
|
|
126
134
|
|
|
127
135
|
Implementing comprehensive tests for your document model reducers is an investment that pays dividends in the long run. It leads to:
|
|
128
136
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
137
|
+
- **Higher Quality Models**: More reliable and robust document models with fewer bugs.
|
|
138
|
+
- **Increased Confidence**: Ability to make changes and refactor code without fear of breaking existing functionality.
|
|
139
|
+
- **Easier Debugging**: When tests fail, they pinpoint the exact operation and scenario that's problematic.
|
|
140
|
+
- **Better Collaboration**: Tests clarify the intended behavior of the document model for all team members.
|
|
133
141
|
|
|
134
142
|
By following the tutorial and applying these best practices, you can build a strong suite of tests that safeguard the integrity and functionality of your document models. This diligence is a hallmark of a "Mastery Track" developer, ensuring that the solutions you build are not just functional but also stable, maintainable, and trustworthy.
|
|
135
143
|
|
|
136
144
|
## Up next
|
|
137
|
-
In the next chapter of the Mastery Track - Building User Experiences you will learn how to implement an [editor](/academy/MasteryTrack/BuildingUserExperiences/BuildingDocumentEditors) for your document model so you can see a simple user interface for the **To-do List** document model in action.
|
|
138
145
|
|
|
139
|
-
|
|
146
|
+
In the next chapter of the Mastery Track - Building User Experiences you will learn how to implement an [editor](/academy/MasteryTrack/BuildingUserExperiences/BuildingDocumentEditors) for your document model so you can see a simple user interface for the **To-do List** document model in action.
|
|
147
|
+
|
|
148
|
+
For a complete, working example, you can always have a look at the [Example To-do List Repository](/academy/MasteryTrack/DocumentModelCreation/ExampleToDoListRepository) which contains the full implementation of the concepts discussed in this Mastery Track.
|
package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/07-ExampleToDoListRepository.md
CHANGED
|
@@ -16,12 +16,13 @@ Follow the steps in the "Mastery Track – Document Model Creation" chapters to
|
|
|
16
16
|
|
|
17
17
|
### Option 2: Clone and run the code locally
|
|
18
18
|
|
|
19
|
-
The package includes:
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
- Reducer
|
|
23
|
-
-
|
|
24
|
-
-
|
|
19
|
+
The package includes:
|
|
20
|
+
|
|
21
|
+
- The Document Model
|
|
22
|
+
- Reducer Code
|
|
23
|
+
- Reducer Tests
|
|
24
|
+
- Editor Code
|
|
25
|
+
- Drive Explorer Code
|
|
25
26
|
|
|
26
27
|
You can clone the repository and run Connect Studio to see all the code in action:
|
|
27
28
|
|
|
@@ -36,6 +37,3 @@ Alternatively, you can install this package in a Powerhouse project or in your d
|
|
|
36
37
|
```bash
|
|
37
38
|
ph install @powerhousedao/todo-demo-package
|
|
38
39
|
```
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
"label": "Document Model Creation",
|
|
3
|
+
"link": {
|
|
4
|
+
"type": "doc",
|
|
5
|
+
"id": "academy/MasteryTrack/DocumentModelCreation/WhatIsADocumentModel"
|
|
6
|
+
}
|
|
7
|
+
}
|
package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/01-BuildingDocumentEditors.md
CHANGED
|
@@ -6,15 +6,17 @@ At Powerhouse, frontend development for document editors follows a simple and fa
|
|
|
6
6
|
|
|
7
7
|
### Development environment
|
|
8
8
|
|
|
9
|
-
Connect Studio is your primary tool for development.
|
|
9
|
+
Connect Studio is your primary tool for development.
|
|
10
10
|
When you run `ph connect`, it provides a dynamic, local environment where you can define and preview your document models and their editors live. This replaces the need for tools like Storybook for editor development, though Storybook remains invaluable for exploring the [Powerhouse Component Library](#powerhouse-component-library).
|
|
11
11
|
|
|
12
12
|
Key aspects of the Powerhouse development environment:
|
|
13
|
+
|
|
13
14
|
- **React Foundation**: Build your editor UIs using React components, just as you would in any standard React project.
|
|
14
15
|
- **Automatic Build Processes**: Tailwind CSS is installed by default and fully managed by Connect Studio. There's no need to manually configure or run Tailwind or other build processes during development. Connect Studio handles CSS generation and other necessary build steps automatically, especially when you publish a package.
|
|
15
16
|
- **Styling Flexibility**: You are not limited to Tailwind. Regular CSS (`.css` files), inline styles, and any React-compatible styling method work exactly as you would expect.
|
|
16
17
|
|
|
17
18
|
Powerhouse aims to keep your developer experience clean, familiar, and focused:
|
|
19
|
+
|
|
18
20
|
- Build React components as you normally would.
|
|
19
21
|
- Use styling approaches you're comfortable with.
|
|
20
22
|
- Trust Connect Studio to handle the setup and build processes for you.
|
|
@@ -25,9 +27,11 @@ To kickstart your editor development, Powerhouse provides a command to generate
|
|
|
25
27
|
If you want a refresher on how to define your document model specification please read the chapter on [specifying the State Schema](/academy/MasteryTrack/DocumentModelCreation/SpecifyTheStateSchema)
|
|
26
28
|
|
|
27
29
|
For example, to generate an editor for a To-do List document model with a document type `powerhouse/todolist`:
|
|
30
|
+
|
|
28
31
|
```bash
|
|
29
32
|
ph generate --editor ToDoList --document-types powerhouse/todolist
|
|
30
33
|
```
|
|
34
|
+
|
|
31
35
|
This will create the template in the `editors/to-do-list/editor.tsx` folder.
|
|
32
36
|
|
|
33
37
|
### Styling your editor
|
|
@@ -37,7 +41,8 @@ You have several options for styling your editor components:
|
|
|
37
41
|
1. **Default HTML Styling**: Standard HTML tags (`<h1>`, `<p>`, `<button>`, etc.) will render with default browser styles or any base styling provided by the Connect environment. This is suitable for basic structure and quick prototyping.
|
|
38
42
|
|
|
39
43
|
2. **Tailwind CSS**: Connect Studio comes with Tailwind CSS integrated. You can directly use Tailwind utility classes in your JSX for rapid and consistent styling without writing separate CSS files.
|
|
40
|
-
|
|
44
|
+
_Example (from the ToDoList Editor):_
|
|
45
|
+
|
|
41
46
|
```typescript
|
|
42
47
|
<div className="container mx-auto p-4 max-w-md">
|
|
43
48
|
<h1 className="text-2xl font-bold mb-4">ToDoList</h1>
|
|
@@ -46,19 +51,22 @@ You have several options for styling your editor components:
|
|
|
46
51
|
```
|
|
47
52
|
|
|
48
53
|
3. **Custom CSS Files**: You can import traditional CSS files (`.css`) to apply custom styles or integrate existing style libraries.
|
|
49
|
-
|
|
54
|
+
_Create an `editor.css` file in your editor's directory:_
|
|
55
|
+
|
|
50
56
|
```css
|
|
51
57
|
/* editors/your-editor/editor.css */
|
|
52
58
|
.editor-container {
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
padding: 1rem;
|
|
60
|
+
border: 1px solid #ccc;
|
|
55
61
|
}
|
|
56
62
|
.editor-title {
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
color: navy;
|
|
64
|
+
font-size: 1.8rem;
|
|
59
65
|
}
|
|
60
66
|
```
|
|
61
|
-
|
|
67
|
+
|
|
68
|
+
_Import and use it in your `editor.tsx`:_
|
|
69
|
+
|
|
62
70
|
```typescript
|
|
63
71
|
import './editor.css'; // Import the CSS file
|
|
64
72
|
|
|
@@ -74,9 +82,9 @@ You have several options for styling your editor components:
|
|
|
74
82
|
|
|
75
83
|
Choose the method or combination of methods that best suits your project needs and team preferences. Connect Studio (`ph connect`) will allow you to see your styles applied in real-time.
|
|
76
84
|
|
|
77
|
-
:::warning
|
|
85
|
+
:::warning **Best practices for consistent reliable styles**
|
|
78
86
|
|
|
79
|
-
In any package the styles are being generated through the styles.css file with the help of the tailwindcss/cli package.
|
|
87
|
+
In any package the styles are being generated through the styles.css file with the help of the tailwindcss/cli package.
|
|
80
88
|
|
|
81
89
|
**1. Centralize style imports**
|
|
82
90
|
|
|
@@ -93,28 +101,28 @@ In any package the styles are being generated through the styles.css file with t
|
|
|
93
101
|
**Using `ph install` includes package styles automatically**
|
|
94
102
|
|
|
95
103
|
- When installing a package with `ph install` on any instance, package styles are automatically added to styles.css. This ensures production builds always include the required package styles.
|
|
96
|
-
:::
|
|
97
|
-
|
|
98
|
-
|
|
104
|
+
:::
|
|
99
105
|
|
|
100
106
|
### State management in editors
|
|
101
107
|
|
|
102
108
|
When you build an editor in Powerhouse, your main editor component receives `EditorProps`. These props are crucial for interacting with the document:
|
|
103
109
|
|
|
104
|
-
|
|
105
|
-
|
|
110
|
+
- **`document`**: This object contains the entire document structure, including its current state. You'll typically access the global document state via `document.state.global`.
|
|
111
|
+
- **`dispatch`**: This function is your gateway to modifying the document's state. You call `dispatch` with an action object (usually created by action creators from your document model's generated code) to signal an intended change.
|
|
106
112
|
|
|
107
113
|
**Local vs. Global State:**
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
|
|
115
|
+
- **Local Component State**: For UI-specific state that doesn't need to be part of the persisted document model (e.g., the current text in an input field before submission, visibility of a dropdown), use React's `useState` hook.
|
|
116
|
+
```typescript
|
|
117
|
+
const [inputValue, setInputValue] = useState('');
|
|
118
|
+
// ...
|
|
119
|
+
<input value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
|
|
120
|
+
```
|
|
121
|
+
- **Global Document State**: For data that is part of the document itself and should be saved (e.g., the items in a to-do list), you modify it by dispatching actions. The `document.state.global` object provides read-only access to this state within your editor.
|
|
115
122
|
|
|
116
123
|
**Dispatching Actions:**
|
|
117
124
|
Your document model's generated code (e.g., in `document-models/your-model/index.js` or `document-models/your-model/gen/operations.js`) will provide action creators.
|
|
125
|
+
|
|
118
126
|
```typescript
|
|
119
127
|
// Assuming 'actions' are imported from your document model
|
|
120
128
|
// import { actions } from '../../document-models/to-do-list/index.js';
|
|
@@ -133,6 +141,7 @@ Your document model's generated code (e.g., in `document-models/your-model/index
|
|
|
133
141
|
// };
|
|
134
142
|
// }
|
|
135
143
|
```
|
|
144
|
+
|
|
136
145
|
The actual state modification logic resides in your document model's reducers, ensuring that all changes are consistent and follow the defined operations.
|
|
137
146
|
|
|
138
147
|
## Powerhouse component library
|
|
@@ -140,19 +149,26 @@ The actual state modification logic resides in your document model's reducers, e
|
|
|
140
149
|
Powerhouse provides a rich set of reusable UI components through the **`@powerhousedao/document-engineering/scalars`** package. These components are designed for consistency, efficiency, and seamless integration with the Powerhouse ecosystem, with many based on GraphQL scalar types. For more information read our chapter on the [Component Library](/academy/ComponentLibrary/DocumentEngineering)
|
|
141
150
|
|
|
142
151
|
### Exploring components
|
|
152
|
+
|
|
143
153
|
You can explore available components, see usage examples, and understand their properties (props) using our Storybook instance:
|
|
144
154
|
[https://storybook.powerhouse.academy](https://storybook.powerhouse.academy)
|
|
145
155
|
|
|
146
156
|
Storybook allows you to:
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
157
|
+
|
|
158
|
+
- Visually inspect each component.
|
|
159
|
+
- Interact with different states and variations.
|
|
160
|
+
- View code snippets for basic implementation.
|
|
161
|
+
- Consult the props table for detailed configuration options.
|
|
151
162
|
|
|
152
163
|
### Using components
|
|
164
|
+
|
|
153
165
|
1. **Import**: Add an import statement at the top of your editor file:
|
|
154
166
|
```typescript
|
|
155
|
-
import {
|
|
167
|
+
import {
|
|
168
|
+
Checkbox,
|
|
169
|
+
StringField,
|
|
170
|
+
Form,
|
|
171
|
+
} from "@powerhousedao/document-engineering/scalars";
|
|
156
172
|
```
|
|
157
173
|
2. **Implement**: Use the component in your JSX, configuring it with props:
|
|
158
174
|
```typescript
|
|
@@ -172,11 +188,11 @@ Storybook allows you to:
|
|
|
172
188
|
|
|
173
189
|
## Build a To-do List editor
|
|
174
190
|
|
|
175
|
-
In this final part of our tutorial we will continue with the interface or editor implementation of the **To-do List** document model. This means you will create a simple user interface for the **To-do List** document model which will be used inside the Connect app to create, update and delete your To-do List items, but also dispaly the statistics we've implemented in our reducers.
|
|
191
|
+
In this final part of our tutorial we will continue with the interface or editor implementation of the **To-do List** document model. This means you will create a simple user interface for the **To-do List** document model which will be used inside the Connect app to create, update and delete your To-do List items, but also dispaly the statistics we've implemented in our reducers.
|
|
176
192
|
|
|
177
193
|
## Generate the editor template
|
|
178
194
|
|
|
179
|
-
Run the command below to generate the editor template for the **To-do List** document model.
|
|
195
|
+
Run the command below to generate the editor template for the **To-do List** document model.
|
|
180
196
|
This command reads the **To-do List** document model definition from the `document-models` folder and generates the editor template in the `editors/to-do-list` folder as `editor.tsx`.
|
|
181
197
|
|
|
182
198
|
Notice the `--editor` flag which specifies the **To-do List** document model, and the `--document-types` flag defines the document type `powerhouse/todolist`.
|
|
@@ -187,12 +203,11 @@ ph generate --editor ToDoList --document-types powerhouse/todolist
|
|
|
187
203
|
|
|
188
204
|
Once complete, navigate to the `editors/to-do-list/editor.tsx` file and open it in your editor.
|
|
189
205
|
|
|
190
|
-
|
|
191
206
|
### Editor implementation options
|
|
192
207
|
|
|
193
208
|
When building your editor component within the Powerhouse ecosystem, you have several options for styling, allowing you to leverage your preferred methods:
|
|
194
209
|
|
|
195
|
-
1. **Default HTML Styling:** Standard HTML tags (`<h1>`, `<p>`, `<button>`, etc.) will render with default styles offered through the boilerplate.
|
|
210
|
+
1. **Default HTML Styling:** Standard HTML tags (`<h1>`, `<p>`, `<button>`, etc.) will render with default styles offered through the boilerplate.
|
|
196
211
|
2. **Tailwind CSS:** Connect Studio comes with Tailwind CSS integrated. You can directly use Tailwind utility classes for rapid, consistent styling without writing separate CSS files.
|
|
197
212
|
3. **Custom CSS Files:** You can import traditional CSS files (`.css`) to apply custom styles or integrate existing style libraries.
|
|
198
213
|
|
|
@@ -203,9 +218,9 @@ Connect Studio provides a dynamic local environment (`ph connect`) to visualize
|
|
|
203
218
|
## To-do List editor
|
|
204
219
|
|
|
205
220
|
:::tip Implementing components
|
|
206
|
-
The editor we are about to implement makes use of some components from **Powerhouse Document Engineering**.
|
|
221
|
+
The editor we are about to implement makes use of some components from **Powerhouse Document Engineering**.
|
|
207
222
|
When you add the editor code, you'll see it makes use of two components, the `Checkbox` and `InputField`.
|
|
208
|
-
These are imported from the Powerhouse Document Engineering design system (`@powerhousedao/document-engineering/scalars`) which you should find under 'devdependencies' in your package.json file.
|
|
223
|
+
These are imported from the Powerhouse Document Engineering design system (`@powerhousedao/document-engineering/scalars`) which you should find under 'devdependencies' in your package.json file.
|
|
209
224
|
|
|
210
225
|
This system provides a library of reusable components to ensure consistency and speed up development.
|
|
211
226
|
You can explore available components, see usage examples, and understand their properties (props) using our Storybook instance. For a detailed guide on how to leverage the Document Engineering design system and Storybook, see [Using the Powerhouse Document Engineering](/academy/ComponentLibrary/DocumentEngineering) page.
|
|
@@ -219,23 +234,24 @@ For this tutorial, create a `components` folder inside `editors/to-do-list`. The
|
|
|
219
234
|
import { Form, BooleanField } from "@powerhousedao/document-engineering/scalars";
|
|
220
235
|
|
|
221
236
|
interface CheckboxProps {
|
|
222
|
-
|
|
223
|
-
|
|
237
|
+
value: boolean;
|
|
238
|
+
onChange: (value: boolean) => void;
|
|
224
239
|
}
|
|
225
240
|
|
|
226
241
|
export const Checkbox = ({ value, onChange }: CheckboxProps) => {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
242
|
+
return (
|
|
243
|
+
<Form onSubmit={() => {}}>
|
|
244
|
+
<BooleanField
|
|
230
245
|
name="checked"
|
|
231
246
|
description="Check this box to mark the todo as completed"
|
|
232
247
|
value={value}
|
|
233
248
|
onChange={onChange}
|
|
234
249
|
/>
|
|
235
|
-
|
|
236
|
-
|
|
250
|
+
</Form>
|
|
251
|
+
);
|
|
237
252
|
};
|
|
238
|
-
|
|
253
|
+
|
|
254
|
+
````
|
|
239
255
|
</details>
|
|
240
256
|
|
|
241
257
|
<details>
|
|
@@ -277,9 +293,9 @@ export const InputField = (props: InputFieldProps) => {
|
|
|
277
293
|
</Form>
|
|
278
294
|
);
|
|
279
295
|
};
|
|
280
|
-
|
|
281
|
-
</details>
|
|
296
|
+
````
|
|
282
297
|
|
|
298
|
+
</details>
|
|
283
299
|
|
|
284
300
|
Below is the complete code for the To-Do List editor. It primarily uses Tailwind CSS for styling and imports the local `Checkbox` and `InputField` components you created in the previous step. These local components, in turn, utilize elements from the Powerhouse Document Engineering design system.
|
|
285
301
|
|
|
@@ -506,6 +522,7 @@ export default function Editor(props: IProps) {
|
|
|
506
522
|
);
|
|
507
523
|
}
|
|
508
524
|
```
|
|
525
|
+
|
|
509
526
|
</details>
|
|
510
527
|
|
|
511
528
|
Now you can run the Connect app and see the **To-do List** editor in action.
|
|
@@ -517,14 +534,15 @@ ph connect
|
|
|
517
534
|
In Connect, in the bottom right corner you'll find a new Document Model that you can create: **To-do List**. Click on it to create a new To-do List document.
|
|
518
535
|
|
|
519
536
|
:::tip Connect as your dynamic development environment
|
|
520
|
-
The editor will update dynamically, so you can play around with your editor styling while seeing your results appear in Connect Studio.
|
|
537
|
+
The editor will update dynamically, so you can play around with your editor styling while seeing your results appear in Connect Studio.
|
|
521
538
|
:::
|
|
522
539
|
|
|
523
540
|
</details>
|
|
524
541
|
|
|
525
542
|
Congratulations!
|
|
526
|
-
If you managed to follow this tutorial until this point, you have successfully implemented the **To-do List** document model with its reducer operations and editor.
|
|
543
|
+
If you managed to follow this tutorial until this point, you have successfully implemented the **To-do List** document model with its reducer operations and editor.
|
|
544
|
+
|
|
545
|
+
## Up Next
|
|
527
546
|
|
|
528
|
-
|
|
529
|
-
Now you can move on to creating a [custom drive explorer](/academy/MasteryTrack/BuildingUserExperiences/BuildingADriveExplorer) for your To-do List document.
|
|
547
|
+
Now you can move on to creating a [custom drive explorer](/academy/MasteryTrack/BuildingUserExperiences/BuildingADriveExplorer) for your To-do List document.
|
|
530
548
|
Imagine you have many To-do Lists sitting in a drive. A custom drive explorer will allow you to organize and track them at a glance, opening up a new world of possibilities to increase the functionality of your documents!
|