| 137 | `, |
| 138 | }) |
| 139 | export class App { |
| 140 | projects = [ |
| 141 | { id: 1, name: 'Work' }, |
| 142 | { id: 2, name: 'Home' }, |
| 143 | ] |
| 144 | |
| 145 | selectedProjectId = signal(2) |
| 146 | |
| 147 | todoQuery = injectLiveQuery({ |
| 148 | params: () => ({ projectID: this.selectedProjectId() }), |
| 149 | query: ({ params, q }) => |
| 150 | q.from({ todo: todosCollection }).where(({ todo }) => eq(todo.projectID, params.projectID)), |
| 151 | }) |
| 152 | |
| 153 | newTodoText = '' |
| 154 | |
| 155 | addTodo() { |
| 156 | if (!this.newTodoText.trim()) return |
| 157 | |
| 158 | const newTodo = { |
| 159 | id: Date.now(), |
| 160 | text: this.newTodoText.trim(), |
| 161 | projectID: this.selectedProjectId(), |
| 162 | completed: false, |
| 163 | created_at: new Date(), |
| 164 | } |
| 165 | |
| 166 | todosCollection.insert(newTodo) |
| 167 | this.newTodoText = '' |
| 168 | } |
| 169 | |
| 170 | toggleTodo(id: number) { |
| 171 | todosCollection.update(id, (draft: any) => { |
| 172 | draft.completed = !draft.completed |
| 173 | }) |
| 174 | } |
| 175 | |
| 176 | deleteTodo(id: number) { |
| 177 | todosCollection.delete(id) |
| 178 | } |
| 179 | |
| 180 | getCompletedCount(): number { |
| 181 | return this.todoQuery.data().filter((todo) => todo.completed).length |
| 182 | } |
| 183 | } |
nothing calls this directly
no test coverage detected