@powerhousedao/academy 5.1.0-dev.9 → 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 +43 -1108
- 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 +9 -118
- package/docs/academy/01-GetStarted/02-DefineToDoListDocumentModel.md +28 -110
- package/docs/academy/01-GetStarted/03-ImplementOperationReducers.md +145 -191
- package/docs/academy/01-GetStarted/04-BuildToDoListEditor.md +218 -0
- package/docs/academy/{02-MasteryTrack/01-BuilderEnvironment → 01-GetStarted}/05-VetraStudio.md +6 -48
- 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 +76 -255
- package/docs/academy/03-ExampleUsecases/Chatroom/04-ImplementOperationReducers.md +160 -281
- package/docs/academy/03-ExampleUsecases/Chatroom/05-ImplementChatroomEditor.md +35 -188
- 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 +12 -49
- package/src/css/custom.css +18 -26
- package/docs/academy/01-GetStarted/04-WriteDocumentModelTests.md +0 -378
- package/docs/academy/01-GetStarted/05-BuildToDoListEditor.md +0 -560
- 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/01-BuilderEnvironment → 01-GetStarted}/images/Modules.png +0 -0
- /package/docs/academy/{02-MasteryTrack/01-BuilderEnvironment → 01-GetStarted}/images/VetraStudioDrive.png +0 -0
- /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
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
# Step 1 - Generate the `TodoList` document model
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
This tutorial guides you through creating a simplified version of a 'Powerhouse project' for a **To-do List**.
|
|
6
|
-
A Powerhouse project primarily consists of a document model and its editor.
|
|
7
|
-
As your projects use-case expands you can add data-integrations or a specific drive-app as seen in the demo package.
|
|
8
|
-
|
|
9
|
-
For todays purpose, you'll be using Connect, our user-centric collaboration tool and Vetra Studio, the builder tooling through which developers can access and manage specifications of your project.
|
|
10
|
-
|
|
11
|
-
## Develop a single document model in Connect
|
|
12
|
-
|
|
13
|
-
Once in the project directory, run the `pnpm connect` command to start a local instance of the Connect application. This allows you to start your document model specification document.
|
|
14
|
-
Run the following command to start the Connect application:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
pnpm connect
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
The Connect application will start and you will see the following output:
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
➜ Local: http://localhost:3000/
|
|
24
|
-
➜ Network: http://192.168.5.110:3000/
|
|
25
|
-
➜ press h + enter to show help
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
A new browser window will open and you will see the Connect application. If it doesn't open automatically, you can open it manually by navigating to `http://localhost:3000/` in your browser. You will see your local drive and a button to create a new drive.
|
|
29
|
-
|
|
30
|
-
:::tip
|
|
31
|
-
If you local drive is not present navigate into Settings in the bottom left corner. Settings > Danger Zone > Clear Storage.
|
|
32
|
-
Clear the storage of your localhost application as it might has an old session cached.
|
|
33
|
-
:::
|
|
34
|
-
|
|
35
|
-
4. Move into your local drive.
|
|
36
|
-
Create a new document model by clicking the `DocumentModel` button, found in the 'New Document' section at the bottom of the page. Name your document `Todo List`.
|
|
37
|
-
|
|
38
|
-
If you've followed the steps correctly, you'll have an empty `TodoList` document where you can define the **'Document Specifications'**.
|
|
39
|
-
|
|
40
|
-
## TodoList document specification
|
|
41
|
-
|
|
42
|
-
To start, fill in the following details for your new document model:
|
|
43
|
-
|
|
44
|
-
Name: `Todo List`
|
|
45
|
-
Document type: `powerhouse/todo-list`
|
|
46
|
-
Author name: Powerhouse
|
|
47
|
-
Website URL: https://powerhouse.inc
|
|
48
|
-
|
|
49
|
-
It's important that you use these exact details so that your generated code matches the generated code in the tutorial repository.
|
|
50
|
-
|
|
51
|
-
We'll continue with this project to teach you how to create a document model specification and later an editor for your document model. We use the **GraphQL Schema Definition Language** (SDL) to define the schema for the document model.
|
|
52
|
-
Below, you can see the SDL for the `TodoList` document model.
|
|
53
|
-
|
|
54
|
-
:::info
|
|
55
|
-
This schema defines the **data structure** of the document model and the types involved in its operations, which are detailed further as input types.
|
|
56
|
-
Documents in Powerhouse leverage **event sourcing principles**, where every state transition is represented by an operation. GraphQL input types describe operations, ensuring that user intents are captured effectively. These operations detail the parameters needed for state transitions. The use of GraphQL aligns these transitions with explicit, validated, and reproducible commands.
|
|
57
|
-
:::
|
|
58
|
-
|
|
59
|
-
## The document model state schema
|
|
60
|
-
|
|
61
|
-
First, let's add a graphql type that represents an individual item in a todo list document. A todo item has an ID, text, and can be either checked or unchecked.
|
|
62
|
-
|
|
63
|
-
Add this underneath the boilerplate `TodoListState` type you see in the Global State Schema text editor.
|
|
64
|
-
|
|
65
|
-
```graphql
|
|
66
|
-
# Defines a GraphQL type for a single to-do item
|
|
67
|
-
type TodoItem {
|
|
68
|
-
id: OID! # Unique identifier for each to-do item
|
|
69
|
-
text: String! # The text description of the to-do item
|
|
70
|
-
checked: Boolean! # Status of the to-do item (checked/unchecked)
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Now update the `TodoListState` type to use our new type by replacing the boilerplate with this:
|
|
75
|
-
|
|
76
|
-
```graphql
|
|
77
|
-
type TodoListState {
|
|
78
|
-
items: [TodoItem!]!
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
The final result in your editor should look like this:
|
|
83
|
-
|
|
84
|
-
```graphql
|
|
85
|
-
type TodoListState {
|
|
86
|
-
items: [TodoItem!]!
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
# Defines a GraphQL type for a single to-do item
|
|
90
|
-
type TodoItem {
|
|
91
|
-
id: OID! # Unique identifier for each to-do item
|
|
92
|
-
text: String! # The text description of the to-do item
|
|
93
|
-
checked: Boolean! # Status of the to-do item (checked/unchecked)
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
With our state schema defined, go ahead and click the "Sync with schema" button underneath "Global State Initial Value". This will set the initial state for the documents you create with this model based on the schema you defined.
|
|
98
|
-
|
|
99
|
-
Your initial value field should now look like this:
|
|
100
|
-
|
|
101
|
-
```json
|
|
102
|
-
{
|
|
103
|
-
"items": []
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Operation inputs and their schemas
|
|
108
|
-
|
|
109
|
-
We've defined the shape for the state of our `TodoList` documents, but we also need to be able to update them.
|
|
110
|
-
|
|
111
|
-
Documents are updated by dispatching actions, which are applied to documents as operations.
|
|
112
|
-
|
|
113
|
-
We define modules to group sets of operations together. In this simple case, we will only need one module.
|
|
114
|
-
|
|
115
|
-
Add a new module for our `todos` operations by typing `todos` in the "Add new module" input and pressing enter.
|
|
116
|
-
|
|
117
|
-
We need to add three different operations to this module:
|
|
118
|
-
|
|
119
|
-
1. add todo item
|
|
120
|
-
2. update todo item
|
|
121
|
-
3. delete todo item
|
|
122
|
-
|
|
123
|
-
Let's start with adding todos.
|
|
124
|
-
|
|
125
|
-
When we add a new todo, the only input we need to provide is the text. Creating the ID will be handled later in our reducer code, and todos always start as unchecked by default.
|
|
126
|
-
|
|
127
|
-
type `add todo item` in the "Add new operation" input and press enter.
|
|
128
|
-
|
|
129
|
-
You will see your new operation with the name `ADD_TODO_ITEM` (we automatically handle changing the casing to the required CONSTANT_CASE).
|
|
130
|
-
|
|
131
|
-
You will also see a boilerplate placeholder graphql input.
|
|
132
|
-
|
|
133
|
-
Update the graphql input like so:
|
|
134
|
-
|
|
135
|
-
```graphql
|
|
136
|
-
input AddTodoItemInput {
|
|
137
|
-
text: String!
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Next let's handle updating todo items.
|
|
142
|
-
|
|
143
|
-
Type `update todo item` in the "Add new operation" input and press enter.
|
|
144
|
-
|
|
145
|
-
For updating items, we will need to provide an `id` so we know which one to update. We can use the same operation to update the text or the checked state, so both of these fields are optional (no ! on the field).
|
|
146
|
-
|
|
147
|
-
Update the `UpdateTodoItemInput` to be like so:
|
|
148
|
-
|
|
149
|
-
```graphql
|
|
150
|
-
input UpdateTodoItemInput {
|
|
151
|
-
id: OID!
|
|
152
|
-
text: String
|
|
153
|
-
checked: Boolean
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
Finally, we can handle the delete item operation.
|
|
158
|
-
|
|
159
|
-
type `delete todo item` in the "Add new operation" input.
|
|
160
|
-
|
|
161
|
-
For deleting items, all we need is an `id`.
|
|
162
|
-
|
|
163
|
-
Update your `DeleteTodoItemInput` to be like this:
|
|
164
|
-
|
|
165
|
-
```graphql
|
|
166
|
-
input DeleteTodoItemInput {
|
|
167
|
-
id: OID!
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
Once you have added all the input operations, click the `Export` button at the top right of the editor to save the document model specification document to your local machine. Ideally, you should save your file in the root of your repository with the name `todo-list.phd`
|
|
172
|
-
|
|
173
|
-
## Generating your document model code
|
|
174
|
-
|
|
175
|
-
With our newly created document model, we can run the codegen to generate the rest of the code for it.
|
|
176
|
-
|
|
177
|
-
To run the codegen, you use the `generate` command with a path to the file you just exported.
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
pnpm generate ./todo-list.phd
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
**NOTE:** this generated code contains values that will always be different for each generated document model, like module ids for example. For the purposes of this tutorial, we recommend that you instead use the reference example that we have already included in the repo for you — this will make your generated code look exactly the same as the generated code in the branches in the repo, and your diffs will match exactly.
|
|
184
|
-
|
|
185
|
-
To use our reference example, run:
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
pnpm generate ./todo-list.phdm.phd
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
This will overwrite your generated code with code that is identical to the branches in this repository.
|
|
192
|
-
|
|
193
|
-
## Check your work
|
|
194
|
-
|
|
195
|
-
To make sure all works as expected, we should:
|
|
196
|
-
|
|
197
|
-
- check types
|
|
198
|
-
run: `pnpm tsc`
|
|
199
|
-
|
|
200
|
-
- check linting
|
|
201
|
-
run: `pnpm lint`
|
|
202
|
-
|
|
203
|
-
- check tests
|
|
204
|
-
run: `pnpm test`
|
|
205
|
-
|
|
206
|
-
- make sure your code matches the code in the completed step branch
|
|
207
|
-
run: `git diff your-branch-name step-1-complete-generated-todo-list-document-model`
|
|
208
|
-
|
|
209
|
-
### Up next: reducers and operations
|
|
210
|
-
|
|
211
|
-
Up next, you'll learn how to implement the runtime logic and components that will use the `TodoList` document model specification you've just created and exported.
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
# Step 2 — Implement the `TodoList` document model reducer operation handlers
|
|
2
|
-
|
|
3
|
-
## Adding the logic for handling operations with reducers
|
|
4
|
-
|
|
5
|
-
Your document model update's the state of a given document by applying a set of append-only actions. Once these have been applied to the document, we call them operations.
|
|
6
|
-
|
|
7
|
-
The document model does this with a reducer — a function which takes the existing state and a given action, and then returns the new state with the action applied.
|
|
8
|
-
|
|
9
|
-
## What we have so far
|
|
10
|
-
|
|
11
|
-
The operation handler logic for each module is found in `document-models/SOME-DOCUMENT-MODEL/src/reducers/SOME-MODULE-NAME.ts`.
|
|
12
|
-
|
|
13
|
-
So for our todos module, we will implement our handler logic in `document-models/todo-list/src/reducers/todos.ts`
|
|
14
|
-
|
|
15
|
-
When you generated your document model code, we created a boilerplate implementation of the reducer logic for each of the operations we defined in step 1. You will see that there are functions for handling each of the operations, but all they do is throw "not implemented" errors.
|
|
16
|
-
|
|
17
|
-
```ts
|
|
18
|
-
import type { TodoListTodosOperations } from "todo-tutorial/document-models/todo-list";
|
|
19
|
-
|
|
20
|
-
export const todoListTodosOperations: TodoListTodosOperations = {
|
|
21
|
-
addTodoItemOperation(state, action) {
|
|
22
|
-
// TODO: Implement "addTodoItemOperation" reducer
|
|
23
|
-
throw new Error('Reducer "addTodoItemOperation" not yet implemented');
|
|
24
|
-
},
|
|
25
|
-
updateTodoItemOperation(state, action) {
|
|
26
|
-
// TODO: Implement "updateTodoItemOperation" reducer
|
|
27
|
-
throw new Error('Reducer "updateTodoItemOperation" not yet implemented');
|
|
28
|
-
},
|
|
29
|
-
deleteTodoItemOperation(state, action) {
|
|
30
|
-
// TODO: Implement "deleteTodoItemOperation" reducer
|
|
31
|
-
throw new Error('Reducer "deleteTodoItemOperation" not yet implemented');
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Let's add the handler logic for each operation in the same order we defined them in the previous step.
|
|
37
|
-
|
|
38
|
-
To handle the `addTodoItemOperation`, all we need to do is create an `id` for our new operation, and then push an object with that `id` and the rest of the action input into the `items` array in our state.
|
|
39
|
-
|
|
40
|
-
Update your `addTodoItemOperation` like so:
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
import type { TodoListTodosOperations } from "todo-tutorial/document-models/todo-list";
|
|
44
|
-
|
|
45
|
-
export const todoListTodosOperations: TodoListTodosOperations = {
|
|
46
|
-
// removed-start
|
|
47
|
-
addTodoItemOperation(state, action) {
|
|
48
|
-
// TODO: Implement "addTodoItemOperation" reducer
|
|
49
|
-
throw new Error('Reducer "addTodoItemOperation" not yet implemented');
|
|
50
|
-
},
|
|
51
|
-
// removed-end
|
|
52
|
-
// added-start
|
|
53
|
-
addTodoItemOperation(state, action) {
|
|
54
|
-
const id = generateId();
|
|
55
|
-
state.items.push({ ...action.input, id, checked: false });
|
|
56
|
-
},
|
|
57
|
-
// added-end
|
|
58
|
-
updateTodoItemOperation(state, action) {
|
|
59
|
-
// TODO: Implement "updateTodoItemOperation" reducer
|
|
60
|
-
throw new Error('Reducer "updateTodoItemOperation" not yet implemented');
|
|
61
|
-
},
|
|
62
|
-
deleteTodoItemOperation(state, action) {
|
|
63
|
-
// TODO: Implement "deleteTodoItemOperation" reducer
|
|
64
|
-
throw new Error('Reducer "deleteTodoItemOperation" not yet implemented');
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Under the hood, we use a library for making the functions always create and return new copies of the state, i.e. they are always _immutable_. This is why you don't actually have to return your new state, the newly created copy of the state is used automatically.
|
|
70
|
-
|
|
71
|
-
The `updateTodoOperation` works in much the same way, except this time instead of creating a new `id`, we find the item in the items array which has the given id. Then we spread out the rest of the values we get from the action input, same as when creating.
|
|
72
|
-
|
|
73
|
-
Update your `updateTodoOperation` to be like so:
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
export const todoListTodosOperations: TodoListTodosOperations = {
|
|
77
|
-
addTodoItemOperation(state, action) {
|
|
78
|
-
const id = generateId();
|
|
79
|
-
state.items.push({ ...action.input, id, checked: false });
|
|
80
|
-
},
|
|
81
|
-
// removed-start
|
|
82
|
-
updateTodoItemOperation(state, action) {
|
|
83
|
-
// TODO: Implement "updateTodoItemOperation" reducer
|
|
84
|
-
throw new Error('Reducer "updateTodoItemOperation" not yet implemented');
|
|
85
|
-
},
|
|
86
|
-
// removed-end
|
|
87
|
-
// added-start
|
|
88
|
-
updateTodoItemOperation(state, action) {
|
|
89
|
-
const item = state.items.find((item) => item.id === action.input.id);
|
|
90
|
-
if (!item) return;
|
|
91
|
-
item.text = action.input.text ?? item.text;
|
|
92
|
-
item.checked = action.input.checked ?? item.checked;
|
|
93
|
-
},
|
|
94
|
-
// added-end
|
|
95
|
-
deleteTodoItemOperation(state, action) {
|
|
96
|
-
// TODO: Implement "deleteTodoItemOperation" reducer
|
|
97
|
-
throw new Error('Reducer "deleteTodoItemOperation" not yet implemented');
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
The delete operation is the simplest of the three. All we need to do is filter the items array so that it no longer contains the item with the given id.
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
export const todoListTodosOperations: TodoListTodosOperations = {
|
|
106
|
-
addTodoItemOperation(state, action) {
|
|
107
|
-
const id = generateId();
|
|
108
|
-
state.items.push({ ...action.input, id, checked: false });
|
|
109
|
-
},
|
|
110
|
-
updateTodoItemOperation(state, action) {
|
|
111
|
-
const item = state.items.find((item) => item.id === action.input.id);
|
|
112
|
-
if (!item) return;
|
|
113
|
-
item.text = action.input.text ?? item.text;
|
|
114
|
-
item.checked = action.input.checked ?? item.checked;
|
|
115
|
-
},
|
|
116
|
-
// removed-start
|
|
117
|
-
deleteTodoItemOperation(state, action) {
|
|
118
|
-
// TODO: Implement "deleteTodoItemOperation" reducer
|
|
119
|
-
throw new Error('Reducer "deleteTodoItemOperation" not yet implemented');
|
|
120
|
-
},
|
|
121
|
-
// removed-end
|
|
122
|
-
// added-start
|
|
123
|
-
deleteTodoItemOperation(state, action) {
|
|
124
|
-
state.items = state.items.filter((item) => item.id !== action.input.id);
|
|
125
|
-
},
|
|
126
|
-
// added-end
|
|
127
|
-
};
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
With that all done, your final result should look like this:
|
|
131
|
-
|
|
132
|
-
```ts
|
|
133
|
-
import { generateId } from "document-model/core";
|
|
134
|
-
import type { TodoListTodosOperations } from "todo-tutorial/document-models/todo-list";
|
|
135
|
-
|
|
136
|
-
export const todoListTodosOperations: TodoListTodosOperations = {
|
|
137
|
-
addTodoItemOperation(state, action) {
|
|
138
|
-
const id = generateId();
|
|
139
|
-
state.items.push({ ...action.input, id, checked: false });
|
|
140
|
-
},
|
|
141
|
-
updateTodoItemOperation(state, action) {
|
|
142
|
-
const item = state.items.find((item) => item.id === action.input.id);
|
|
143
|
-
if (!item) return;
|
|
144
|
-
item.text = action.input.text ?? item.text;
|
|
145
|
-
item.checked = action.input.checked ?? item.checked;
|
|
146
|
-
},
|
|
147
|
-
deleteTodoItemOperation(state, action) {
|
|
148
|
-
state.items = state.items.filter((item) => item.id !== action.input.id);
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
## Check your work
|
|
154
|
-
|
|
155
|
-
To make sure all works as expected, we should:
|
|
156
|
-
|
|
157
|
-
- check types
|
|
158
|
-
run: `pnpm tsc`
|
|
159
|
-
|
|
160
|
-
- check linting
|
|
161
|
-
run: `pnpm lint`
|
|
162
|
-
|
|
163
|
-
- check tests
|
|
164
|
-
run: `pnpm test`
|
|
165
|
-
|
|
166
|
-
- make sure your code matches the code in the completed step branch
|
|
167
|
-
run: `git diff your-branch-name step-2-complete-implemented-todo-list-document-model-reducer-operation-handlers`
|
|
168
|
-
|
|
169
|
-
### Up next: tests for our new operation handlers
|
|
170
|
-
|
|
171
|
-
Up next, you'll implement some custom tests to check the behavior of our new code.
|