diff --git a/client/src/App.css b/client/src/App.css deleted file mode 100644 index 74b5e05..0000000 --- a/client/src/App.css +++ /dev/null @@ -1,38 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/client/src/App.tsx b/client/src/App.tsx index 7be22ae..5c4bc14 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import './App.css'; import TodoService from './services/TodoService'; import TodoList from './components/TodoList'; import TodoListViewModel from './viewmodels/TodoListViewModel'; diff --git a/client/src/components/TodoItem.tsx b/client/src/components/TodoItem.tsx index 7530088..3cb7043 100644 --- a/client/src/components/TodoItem.tsx +++ b/client/src/components/TodoItem.tsx @@ -4,21 +4,20 @@ import TodoItemViewModel from '../viewmodels/TodoItemViewModel'; type TodoItemProps = { viewModel: TodoItemViewModel, - deleteItem: () => void } export default observer( - ({viewModel, deleteItem} : TodoItemProps) => { + ({viewModel} : TodoItemProps) => { const [isEditing, setIsEditing] = useState(false); - const [content, setContent] = useState(viewModel.content); + const [draftContent, setDraftContent] = useState(''); function onCheckboxChanged(e: React.FormEvent) { viewModel.setIsDone(e.currentTarget.checked); } function onInputChanged(e: React.FormEvent) { - setContent(e.currentTarget.value); + setDraftContent(e.currentTarget.value); } function onInputKeyUp(e: React.KeyboardEvent) { @@ -28,10 +27,19 @@ export default observer( } function update() { - viewModel.updateContent(content); + viewModel.updateContent(draftContent); setIsEditing(false); } + function deleteItem() { + viewModel.deleteTodoItem(); + } + + function startDrafting() { + setDraftContent(viewModel.content); + setIsEditing(true); + } + return (
  • {viewModel.isAwaiting @@ -40,11 +48,14 @@ export default observer( {viewModel.isAwaiting ? Loading... : isEditing - ? - : setIsEditing(true)}>{content}} + ? + : {viewModel.content}} {isEditing ? : } + {viewModel.didRequestFail + ? {viewModel.failReason} + : null}
  • ); } diff --git a/client/src/components/TodoList.tsx b/client/src/components/TodoList.tsx index 498f4e3..d89fe2b 100644 --- a/client/src/components/TodoList.tsx +++ b/client/src/components/TodoList.tsx @@ -29,7 +29,7 @@ export default observer(

    Todo Items: {viewModel.todosCount}

      - {viewModel.todoItems?.map(item => await viewModel.deleteTodoItem(item.id)}/>)} + {viewModel.todoItems?.map(item => )}
    diff --git a/client/src/services/TodoService.ts b/client/src/services/TodoService.ts index 4e11894..54d1d18 100644 --- a/client/src/services/TodoService.ts +++ b/client/src/services/TodoService.ts @@ -1,6 +1,5 @@ import TodoItem from '../models/TodoItem'; import ServerResponseInterface from './ServerResponseInterface'; -import { Server } from 'http'; const url = "http://localhost:4963/todos"; diff --git a/client/src/viewmodels/TodoItemViewModel.ts b/client/src/viewmodels/TodoItemViewModel.ts index 7fb0e72..7ec6001 100644 --- a/client/src/viewmodels/TodoItemViewModel.ts +++ b/client/src/viewmodels/TodoItemViewModel.ts @@ -7,7 +7,8 @@ export default class TodoItemViewModel extends PromiseAwareViewModelBase { constructor( private service: TodoService, - model : TodoItem + model : TodoItem, + private remove: () => void ) { super(); this.id = model.id; @@ -62,6 +63,19 @@ export default class TodoItemViewModel extends PromiseAwareViewModelBase { }); } + public async deleteTodoItem() { + await this.runWithAwareness(async () => { + var response = await this.service.deleteTodo(this.id); + + if (response.didFail) { + this.didRequestFail = true; + this.failReason = response.failReason; + } else { + this.remove() + } + }); + } + //#endregion } \ No newline at end of file diff --git a/client/src/viewmodels/TodoListViewModel.ts b/client/src/viewmodels/TodoListViewModel.ts index 1517728..338d6a3 100644 --- a/client/src/viewmodels/TodoListViewModel.ts +++ b/client/src/viewmodels/TodoListViewModel.ts @@ -30,7 +30,8 @@ export default class TodoListViewModel extends PromiseAwareViewModelBase { this.didRequestFail = true; this.failReason = response.failReason; } else { - this.todoItems = (response.data as Array).map(item => new TodoItemViewModel(this.service, item)); + this.todoItems = (response.data!) + .map(item => new TodoItemViewModel(this.service, item, () => this.remove(item.id))); } }); } @@ -50,31 +51,21 @@ export default class TodoListViewModel extends PromiseAwareViewModelBase { this.didRequestFail = true; this.failReason = response.failReason; } else { - this.todoItems.push( - new TodoItemViewModel( - this.service, - new TodoItem( - response.data as number, - content, - false - ) - ) - ); + this.insert(new TodoItemViewModel( + this.service, + new TodoItem(response.data!, content, false), + () => this.remove(response.data!) + )); } }); } - public async deleteTodoItem(id: number) { - await this.runWithAwareness(async () => { - var response = await this.service.deleteTodo(id); + public insert(item: TodoItemViewModel) { + this.todoItems.push(item); + } - if (response.didFail) { - this.didRequestFail = true; - this.failReason = response.failReason; - } else { - this.todoItems = this.todoItems.filter(item => item.id !== id); - } - }); + public remove(id: number) { + this.todoItems = this.todoItems.filter(item => item.id !== id); } //#endregion